From 7532cc57219f596be4bcffb9e2cc4a406a458a1a Mon Sep 17 00:00:00 2001 From: mphelt Date: Fri, 21 Apr 2023 09:22:21 +0200 Subject: [PATCH 01/21] add missing overrides in LoggingHttpMessageHandler and LoggingScopeHttpMessageHandler (https://github.com/dotnet/runtime/issues/85104) --- .../src/Logging/LoggingHttpMessageHandler.cs | 18 +++++ .../Logging/LoggingScopeHttpMessageHandler.cs | 20 +++++ .../Logging/LoggingUriOutputTests.cs | 76 ++++++++++++++++++- 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index 62ec57cbc71f3a..cbe8cf191258e2 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -69,6 +69,24 @@ async Task Core(HttpRequestMessage request, CancellationTok } } + /// + /// Loggs the request to and response from the sent . + protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) + { + ThrowHelper.ThrowIfNull(request); + + var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; + + // Not using a scope here because we always expect this to be at the end of the pipeline, thus there's + // not really anything to surround. + Log.RequestStart(_logger, request, shouldRedactHeaderValue); + var stopwatch = ValueStopwatch.StartNew(); + var response = base.Send(request, cancellationToken); + Log.RequestEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); + + return response; + } + // Used in tests. internal static class Log { diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index a2cadee1bcf81c..a32a5240183202 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -71,6 +71,26 @@ async Task Core(HttpRequestMessage request, CancellationTok } } + /// + /// Loggs the request to and response from the sent . + protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) + { + ThrowHelper.ThrowIfNull(request); + + var stopwatch = ValueStopwatch.StartNew(); + + var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; + + using (Log.BeginRequestPipelineScope(_logger, request)) + { + Log.RequestPipelineStart(_logger, request, shouldRedactHeaderValue); + var response = base.Send(request, cancellationToken); + Log.RequestPipelineEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); + + return response; + } + } + // Used in tests internal static class Log { diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 9f5588a3f61051..461f0738dd401a 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -1,7 +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.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -90,6 +89,81 @@ public async Task LoggingScopeHttpMessageHandler_LogsAbsoluteUri() Assert.Equal("HTTP GET http://api.example.com/search?term=Western%20Australia", message.Scope.ToString()); } + [Fact] + public void LoggingHttpMessageHandler_LogsAbsoluteUri_Sync() + { + // Arrange + var sink = new TestSink(); + + var serviceCollection = new ServiceCollection(); + serviceCollection.AddLogging(); + serviceCollection.AddSingleton(new TestLoggerFactory(sink, enabled: true)); + + serviceCollection + .AddHttpClient("test") + .ConfigurePrimaryHttpMessageHandler(() => new TestMessageHandler()); + + var services = serviceCollection.BuildServiceProvider(); + + var client = services.GetRequiredService().CreateClient("test"); + + + // Act + var request = new HttpRequestMessage(HttpMethod.Get, "http://api.example.com/search?term=Western%20Australia"); + + client.Send(request); + + // Assert + var messages = sink.Writes.ToArray(); + + var message = Assert.Single(messages.Where(m => + { + return + m.EventId == LoggingHttpMessageHandler.Log.EventIds.RequestStart && + m.LoggerName == "System.Net.Http.HttpClient.test.ClientHandler"; + })); + + Assert.Equal("Sending HTTP request GET http://api.example.com/search?term=Western%20Australia", message.Message); + } + + [Fact] + public void LoggingScopeHttpMessageHandler_LogsAbsoluteUri_Sync() + { + // Arrange + var sink = new TestSink(); + + var serviceCollection = new ServiceCollection(); + serviceCollection.AddLogging(); + serviceCollection.AddSingleton(new TestLoggerFactory(sink, enabled: true)); + + serviceCollection + .AddHttpClient("test") + .ConfigurePrimaryHttpMessageHandler(() => new TestMessageHandler()); + + var services = serviceCollection.BuildServiceProvider(); + + var client = services.GetRequiredService().CreateClient("test"); + + + // Act + var request = new HttpRequestMessage(HttpMethod.Get, "http://api.example.com/search?term=Western%20Australia"); + + client.Send(request); + + // Assert + var messages = sink.Writes.ToArray(); + + var message = Assert.Single(messages.Where(m => + { + return + m.EventId == LoggingScopeHttpMessageHandler.Log.EventIds.PipelineStart && + m.LoggerName == "System.Net.Http.HttpClient.test.LogicalHandler"; + })); + + Assert.Equal("Start processing HTTP request GET http://api.example.com/search?term=Western%20Australia", message.Message); + Assert.Equal("HTTP GET http://api.example.com/search?term=Western%20Australia", message.Scope.ToString()); + } + private class TestMessageHandler : HttpClientHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) From 04c3ae649c0d7740a66abb613e47b263511c938d Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Fri, 21 Apr 2023 09:44:20 +0200 Subject: [PATCH 02/21] Update LoggingUriOutputTests.cs --- .../Logging/LoggingUriOutputTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 461f0738dd401a..7ac7447ff4bf4f 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; From 0b6199cc3873638fe559a667f34a4df63cadd26f Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:27:58 +0200 Subject: [PATCH 03/21] Update LoggingHttpMessageHandler.cs --- .../src/Logging/LoggingHttpMessageHandler.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index cbe8cf191258e2..b64f2905577236 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -48,7 +48,7 @@ public LoggingHttpMessageHandler(ILogger logger, HttpClientFactoryOptions option } /// - /// Loggs the request to and response from the sent . + /// Logs the request to and response from the sent . protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); @@ -69,8 +69,9 @@ async Task Core(HttpRequestMessage request, CancellationTok } } +#if NET5_0_OR_GREATER /// - /// Loggs the request to and response from the sent . + /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); @@ -86,6 +87,7 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella return response; } +#endif // Used in tests. internal static class Log From 022e908a98d787bd5776c32aa78b949f50333cdd Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:29:33 +0200 Subject: [PATCH 04/21] Update LoggingScopeHttpMessageHandler.cs --- .../src/Logging/LoggingScopeHttpMessageHandler.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index a32a5240183202..211880fa64d9da 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -70,7 +70,8 @@ async Task Core(HttpRequestMessage request, CancellationTok } } } - + +#if NET5_0_OR_GREATER /// /// Loggs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) @@ -90,6 +91,7 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella return response; } } +#endif // Used in tests internal static class Log From a69446a46c3ca917e2e8560a6fb376595eeda902 Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:30:04 +0200 Subject: [PATCH 05/21] Update LoggingScopeHttpMessageHandler.cs --- .../src/Logging/LoggingScopeHttpMessageHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index 211880fa64d9da..fb399148dc5eeb 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -48,7 +48,7 @@ public LoggingScopeHttpMessageHandler(ILogger logger, HttpClientFactoryOptions o } /// - /// Loggs the request to and response from the sent . + /// Logs the request to and response from the sent . protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); @@ -73,7 +73,7 @@ async Task Core(HttpRequestMessage request, CancellationTok #if NET5_0_OR_GREATER /// - /// Loggs the request to and response from the sent . + /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); From 44260f53c67f28308044fb042d8777b321fb328a Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:35:06 +0200 Subject: [PATCH 06/21] Update LoggingUriOutputTests.cs --- .../Logging/LoggingUriOutputTests.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 7ac7447ff4bf4f..e9592e9594b0ff 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -1,4 +1,4 @@ -// 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.Linq; @@ -90,6 +90,8 @@ public async Task LoggingScopeHttpMessageHandler_LogsAbsoluteUri() Assert.Equal("HTTP GET http://api.example.com/search?term=Western%20Australia", message.Scope.ToString()); } +if NET5_0_OR_GREATER + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] [Fact] public void LoggingHttpMessageHandler_LogsAbsoluteUri_Sync() { @@ -127,6 +129,7 @@ public void LoggingHttpMessageHandler_LogsAbsoluteUri_Sync() Assert.Equal("Sending HTTP request GET http://api.example.com/search?term=Western%20Australia", message.Message); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] [Fact] public void LoggingScopeHttpMessageHandler_LogsAbsoluteUri_Sync() { @@ -164,6 +167,7 @@ public void LoggingScopeHttpMessageHandler_LogsAbsoluteUri_Sync() Assert.Equal("Start processing HTTP request GET http://api.example.com/search?term=Western%20Australia", message.Message); Assert.Equal("HTTP GET http://api.example.com/search?term=Western%20Australia", message.Scope.ToString()); } +#endif private class TestMessageHandler : HttpClientHandler { From ccb3a05cb3e9e51509d9ee04ef77a03e5ed297f7 Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Tue, 25 Apr 2023 17:32:58 +0200 Subject: [PATCH 07/21] Update LoggingScopeHttpMessageHandler.cs --- .../src/Logging/LoggingScopeHttpMessageHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index fb399148dc5eeb..478aade39c6b95 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -70,7 +70,7 @@ async Task Core(HttpRequestMessage request, CancellationTok } } } - + #if NET5_0_OR_GREATER /// /// Logs the request to and response from the sent . @@ -91,7 +91,7 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella return response; } } -#endif +#endif // Used in tests internal static class Log From 6c14e6676dd07a34ce9cceac67bcdf2fa11fce03 Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Tue, 25 Apr 2023 18:18:13 +0200 Subject: [PATCH 08/21] Update LoggingUriOutputTests.cs --- .../Logging/LoggingUriOutputTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index e9592e9594b0ff..9496caed6db44c 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -90,7 +90,7 @@ public async Task LoggingScopeHttpMessageHandler_LogsAbsoluteUri() Assert.Equal("HTTP GET http://api.example.com/search?term=Western%20Australia", message.Scope.ToString()); } -if NET5_0_OR_GREATER +#if NET5_0_OR_GREATER [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] [Fact] public void LoggingHttpMessageHandler_LogsAbsoluteUri_Sync() From 8813153addf5addb14954827ac70d13543e1650c Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Tue, 25 Apr 2023 19:20:32 +0200 Subject: [PATCH 09/21] Update LoggingUriOutputTests.cs --- .../Logging/LoggingUriOutputTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 9496caed6db44c..437beaac1db1f0 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Linq; using System.Net.Http; using System.Threading; From 86037ffc95738800bd01fedd97b8afb8e5eba42f Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:13:23 +0200 Subject: [PATCH 10/21] Update LoggingUriOutputTests.cs --- .../Logging/LoggingUriOutputTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 437beaac1db1f0..78139061e6131c 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -93,7 +93,6 @@ public async Task LoggingScopeHttpMessageHandler_LogsAbsoluteUri() #if NET5_0_OR_GREATER [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] - [Fact] public void LoggingHttpMessageHandler_LogsAbsoluteUri_Sync() { // Arrange @@ -131,7 +130,6 @@ public void LoggingHttpMessageHandler_LogsAbsoluteUri_Sync() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] - [Fact] public void LoggingScopeHttpMessageHandler_LogsAbsoluteUri_Sync() { // Arrange From 8ca29b40364dcc845862b21258ef12fdfa5e1344 Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Wed, 26 Apr 2023 14:25:03 +0200 Subject: [PATCH 11/21] Update LoggingUriOutputTests.cs --- .../Logging/LoggingUriOutputTests.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 78139061e6131c..c7a30a591351e5 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -176,6 +176,10 @@ protected override Task SendAsync(HttpRequestMessage reques return Task.FromResult(response); } + +#if NET5_0_OR_GREATER + protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) => new(); +#endif } } } From 838b6408abb0c3b3c43edb77eead9f519a407d6e Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 27 Apr 2023 08:45:39 +0200 Subject: [PATCH 12/21] Update LoggingHttpMessageHandler.cs --- .../src/Logging/LoggingHttpMessageHandler.cs | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index b64f2905577236..ccd78adf3f4c95 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -47,46 +47,42 @@ public LoggingHttpMessageHandler(ILogger logger, HttpClientFactoryOptions option _options = options; } - /// - /// Logs the request to and response from the sent . - protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + private Task SendCoreAsync(HttpRequestMessage request, bool useAsync CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); return Core(request, cancellationToken); async Task Core(HttpRequestMessage request, CancellationToken cancellationToken) { - Func shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; + var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; // Not using a scope here because we always expect this to be at the end of the pipeline, thus there's // not really anything to surround. Log.RequestStart(_logger, request, shouldRedactHeaderValue); var stopwatch = ValueStopwatch.StartNew(); - HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + var response = useAsync + ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) +#if NET5_0_OR_GREATER + : base.Send(request, cancellationToken); +#else + : throw new UnreachableException(); +#endif Log.RequestEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); return response; } } + /// + /// Logs the request to and response from the sent . + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + => SendCoreAsync(request, true, cancellationToken); + #if NET5_0_OR_GREATER /// /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) - { - ThrowHelper.ThrowIfNull(request); - - var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; - - // Not using a scope here because we always expect this to be at the end of the pipeline, thus there's - // not really anything to surround. - Log.RequestStart(_logger, request, shouldRedactHeaderValue); - var stopwatch = ValueStopwatch.StartNew(); - var response = base.Send(request, cancellationToken); - Log.RequestEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); - - return response; - } + => SendCoreAsync(request, false, cancellationToken).GetAwaiter().GetResult(); #endif // Used in tests. From bb7daea9ece06d7894a60efd200f2fbee6b32f2a Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 27 Apr 2023 08:49:33 +0200 Subject: [PATCH 13/21] Update LoggingScopeHttpMessageHandler.cs --- .../Logging/LoggingScopeHttpMessageHandler.cs | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index 478aade39c6b95..47d9e6e298fc44 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -47,9 +47,7 @@ public LoggingScopeHttpMessageHandler(ILogger logger, HttpClientFactoryOptions o _options = options; } - /// - /// Logs the request to and response from the sent . - protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + private Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); return Core(request, cancellationToken); @@ -58,12 +56,18 @@ async Task Core(HttpRequestMessage request, CancellationTok { var stopwatch = ValueStopwatch.StartNew(); - Func shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; + var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; using (Log.BeginRequestPipelineScope(_logger, request)) { Log.RequestPipelineStart(_logger, request, shouldRedactHeaderValue); - HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + var response = useAsync + ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false); +#if NET5_0_OR_GREATER + : base.Send(request, cancellationToken); +#else + : throw new UnreachableException(); +#endif Log.RequestPipelineEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); return response; @@ -71,26 +75,16 @@ async Task Core(HttpRequestMessage request, CancellationTok } } + /// + /// Logs the request to and response from the sent . + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + => SendCoreAsync(request, true, cancellationToken); + #if NET5_0_OR_GREATER /// /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) - { - ThrowHelper.ThrowIfNull(request); - - var stopwatch = ValueStopwatch.StartNew(); - - var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; - - using (Log.BeginRequestPipelineScope(_logger, request)) - { - Log.RequestPipelineStart(_logger, request, shouldRedactHeaderValue); - var response = base.Send(request, cancellationToken); - Log.RequestPipelineEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); - - return response; - } - } + => SendCoreAsync(request, false, cancellationToken).GetAwaiter().GetResult(); #endif // Used in tests From 16f55c9217326e97e067f801eb4946bef3b9721f Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 27 Apr 2023 09:16:49 +0200 Subject: [PATCH 14/21] Update LoggingHttpMessageHandler.cs --- .../src/Logging/LoggingHttpMessageHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index ccd78adf3f4c95..05b40ef69c7a14 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -47,7 +47,7 @@ public LoggingHttpMessageHandler(ILogger logger, HttpClientFactoryOptions option _options = options; } - private Task SendCoreAsync(HttpRequestMessage request, bool useAsync CancellationToken cancellationToken) + private Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); return Core(request, cancellationToken); From ebfe45b711f0f00dba91ca0c5ca2cecff6fb035f Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 27 Apr 2023 09:17:39 +0200 Subject: [PATCH 15/21] Update LoggingScopeHttpMessageHandler.cs --- .../src/Logging/LoggingScopeHttpMessageHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index 47d9e6e298fc44..08701f26610bc0 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -62,7 +62,7 @@ async Task Core(HttpRequestMessage request, CancellationTok { Log.RequestPipelineStart(_logger, request, shouldRedactHeaderValue); var response = useAsync - ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) #if NET5_0_OR_GREATER : base.Send(request, cancellationToken); #else From ba43a5d653750c229a2c5c88478e1377705473d2 Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 27 Apr 2023 09:38:37 +0200 Subject: [PATCH 16/21] Update LoggingHttpMessageHandler.cs --- .../src/Logging/LoggingHttpMessageHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index 05b40ef69c7a14..eb24e8c2fc1c5b 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -61,7 +61,7 @@ async Task Core(HttpRequestMessage request, CancellationTok Log.RequestStart(_logger, request, shouldRedactHeaderValue); var stopwatch = ValueStopwatch.StartNew(); var response = useAsync - ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) + ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) #if NET5_0_OR_GREATER : base.Send(request, cancellationToken); #else From 1d654a93cbb05cb8a3964c0c8c6e1599a67c131f Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:28:52 +0200 Subject: [PATCH 17/21] Update LoggingHttpMessageHandler.cs --- .../src/Logging/LoggingHttpMessageHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index eb24e8c2fc1c5b..6009ef1a4c1772 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -65,7 +65,7 @@ async Task Core(HttpRequestMessage request, CancellationTok #if NET5_0_OR_GREATER : base.Send(request, cancellationToken); #else - : throw new UnreachableException(); + : throw new NotImplementedException("Unreachable code"); #endif Log.RequestEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); From 497d6c2749a58604fc77b59ad2c61bf0e14b1f1f Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:29:38 +0200 Subject: [PATCH 18/21] Update LoggingScopeHttpMessageHandler.cs --- .../src/Logging/LoggingScopeHttpMessageHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index 08701f26610bc0..d91ab3099422c9 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -66,7 +66,7 @@ async Task Core(HttpRequestMessage request, CancellationTok #if NET5_0_OR_GREATER : base.Send(request, cancellationToken); #else - : throw new UnreachableException(); + : throw new NotImplementedException("Unreachable code"); #endif Log.RequestPipelineEnd(_logger, response, stopwatch.GetElapsedTime(), shouldRedactHeaderValue); From 91d421b61eeb90c5c7d409990c3d81e437ff280c Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Fri, 28 Apr 2023 08:58:50 +0200 Subject: [PATCH 19/21] Code style update --- .../src/Logging/LoggingHttpMessageHandler.cs | 10 +++++----- .../src/Logging/LoggingScopeHttpMessageHandler.cs | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index 6009ef1a4c1772..3d5697274f736e 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -47,20 +47,20 @@ public LoggingHttpMessageHandler(ILogger logger, HttpClientFactoryOptions option _options = options; } - private Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) + protected virtual Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); return Core(request, cancellationToken); async Task Core(HttpRequestMessage request, CancellationToken cancellationToken) { - var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; + Func shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; // Not using a scope here because we always expect this to be at the end of the pipeline, thus there's // not really anything to surround. Log.RequestStart(_logger, request, shouldRedactHeaderValue); var stopwatch = ValueStopwatch.StartNew(); - var response = useAsync + HttpResponseMessage response = useAsync ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) #if NET5_0_OR_GREATER : base.Send(request, cancellationToken); @@ -76,13 +76,13 @@ async Task Core(HttpRequestMessage request, CancellationTok /// /// Logs the request to and response from the sent . protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - => SendCoreAsync(request, true, cancellationToken); + => SendCoreAsync(request, useAsync: true, cancellationToken); #if NET5_0_OR_GREATER /// /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) - => SendCoreAsync(request, false, cancellationToken).GetAwaiter().GetResult(); + => SendCoreAsync(request, useAsync: false, cancellationToken).GetAwaiter().GetResult(); #endif // Used in tests. diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index d91ab3099422c9..5bdadd070051d2 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -47,7 +47,7 @@ public LoggingScopeHttpMessageHandler(ILogger logger, HttpClientFactoryOptions o _options = options; } - private Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) + protected virtual Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); return Core(request, cancellationToken); @@ -56,12 +56,12 @@ async Task Core(HttpRequestMessage request, CancellationTok { var stopwatch = ValueStopwatch.StartNew(); - var shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; + Func shouldRedactHeaderValue = _options?.ShouldRedactHeaderValue ?? _shouldNotRedactHeaderValue; using (Log.BeginRequestPipelineScope(_logger, request)) { Log.RequestPipelineStart(_logger, request, shouldRedactHeaderValue); - var response = useAsync + HttpResponseMessage response = useAsync ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) #if NET5_0_OR_GREATER : base.Send(request, cancellationToken); @@ -78,13 +78,13 @@ async Task Core(HttpRequestMessage request, CancellationTok /// /// Logs the request to and response from the sent . protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - => SendCoreAsync(request, true, cancellationToken); + => SendCoreAsync(request, useAsync: true, cancellationToken); #if NET5_0_OR_GREATER /// /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) - => SendCoreAsync(request, false, cancellationToken).GetAwaiter().GetResult(); + => SendCoreAsync(request, useAsync: false, cancellationToken).GetAwaiter().GetResult(); #endif // Used in tests From 67d2534a77621448952d63c285f8ac07403de815 Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:06:29 +0200 Subject: [PATCH 20/21] back to private methods --- .../src/Logging/LoggingHttpMessageHandler.cs | 2 +- .../src/Logging/LoggingScopeHttpMessageHandler.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index 3d5697274f736e..c91bc63b82396d 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -47,7 +47,7 @@ public LoggingHttpMessageHandler(ILogger logger, HttpClientFactoryOptions option _options = options; } - protected virtual Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) + private Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); return Core(request, cancellationToken); diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index 5bdadd070051d2..d111c04c5c71d4 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -47,7 +47,7 @@ public LoggingScopeHttpMessageHandler(ILogger logger, HttpClientFactoryOptions o _options = options; } - protected virtual Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) + private Task SendCoreAsync(HttpRequestMessage request, bool useAsync, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); return Core(request, cancellationToken); From 08ecd2cc4d8ef1f3a7888d31b189283a88821adb Mon Sep 17 00:00:00 2001 From: mphelt <25581948+mphelt@users.noreply.github.com> Date: Thu, 4 May 2023 13:10:45 +0200 Subject: [PATCH 21/21] merge with dotnet/runtime (#7) --- .config/dotnet-tools.json | 2 +- .github/ISSUE_TEMPLATE/04_ci_known_issue.yml | 2 +- CONTRIBUTING.md | 8 +- Directory.Build.props | 132 +- THIRD-PARTY-NOTICES.TXT | 43 + docs/area-owners.md | 2 +- docs/coding-guidelines/project-guidelines.md | 3 - docs/design/coreclr/botr/clr-abi.md | 2 +- docs/design/coreclr/botr/method-descriptor.md | 8 +- docs/design/coreclr/botr/readytorun-format.md | 2 + docs/design/coreclr/botr/shared-generics.md | 26 +- docs/design/coreclr/botr/type-loader.md | 7 +- docs/design/features/hybrid-globalization.md | 17 + .../LibraryImportGenerator/Compatibility.md | 10 +- docs/design/specs/Ecma-335-Augments.md | 11 + docs/pr-builds.md | 98 - docs/workflow/README.md | 21 +- docs/workflow/ci/analysis-check.png | Bin 0 -> 3619 bytes docs/workflow/ci/failed-build.png | Bin 0 -> 17614 bytes docs/workflow/ci/failed-test.png | Bin 0 -> 84781 bytes docs/workflow/ci/failure-analysis.md | 118 + docs/workflow/ci/issue-impact.png | Bin 0 -> 26517 bytes docs/workflow/ci/known-issue-example.png | Bin 0 -> 18393 bytes docs/workflow/ci/pipelines-overview.md | 139 + docs/{ => workflow/ci}/pr-guide.md | 12 +- docs/workflow/ci/theory-azdo.png | Bin 0 -> 34690 bytes .../debugging/coreclr/debugging-runtime.md | 2 +- .../testing/libraries/filtering-tests.md | 12 + eng/SourceBuild.props | 9 +- eng/Subsets.props | 16 +- eng/Version.Details.xml | 308 +- eng/Versions.props | 151 +- eng/build.ps1 | 10 +- eng/build.sh | 25 +- eng/common/cross/build-rootfs.sh | 4 +- eng/common/cross/toolchain.cmake | 32 +- eng/common/native/init-compiler.sh | 2 +- eng/common/templates/job/job.yml | 17 +- .../templates/steps/component-governance.yml | 13 + eng/docker/build-docker-sdk.ps1 | 3 + eng/docker/libraries-sdk.linux.Dockerfile | 7 +- eng/liveBuilds.targets | 10 +- eng/native/build-commons.sh | 12 +- eng/native/configuretools.cmake | 1 + eng/native/genmoduleindex.sh | 12 +- eng/native/init-distro-rid.sh | 164 +- eng/native/init-vs-env.cmd | 2 +- eng/nativepgo.targets | 3 +- eng/pipelines/common/global-build-job.yml | 2 +- eng/pipelines/common/platform-matrix.yml | 22 + .../templates/pipeline-with-resources.yml | 11 +- .../build-runtime-tests-and-send-to-helix.yml | 3 + .../templates/runtimes/run-test-job.yml | 12 +- eng/pipelines/coreclr/perf-non-wasm-jobs.yml | 63 +- eng/pipelines/coreclr/release-tests.yml | 1 + .../coreclr/templates/build-jit-job.yml | 7 + .../coreclr/templates/build-perf-bdn-app.yml | 179 + eng/pipelines/coreclr/templates/perf-job.yml | 8 + .../templates/run-superpmi-collect-job.yml | 7 + .../runtime-extra-platforms-other.yml | 61 +- .../libraries/helix-queues-setup.yml | 2 +- eng/pipelines/mono/templates/build-job.yml | 12 +- eng/pipelines/runtime-codeql.yml | 2 +- eng/pipelines/runtime-llvm.yml | 4 +- eng/pipelines/runtime-official.yml | 27 +- eng/pipelines/runtime.yml | 5 +- eng/testing/ProvisioningVersions.props | 10 +- eng/testing/WasmRunnerAOTTemplate.sh | 14 +- eng/testing/WasmRunnerTemplate.cmd | 6 + eng/testing/WasmRunnerTemplate.sh | 6 + .../SupportFiles/Directory.Build.targets | 2 +- .../performance/android_scenarios.proj | 19 + eng/testing/performance/performance-setup.ps1 | 1 + eng/testing/tests.browser.targets | 1 + eng/testing/tests.props | 2 +- eng/testing/tests.singlefile.targets | 2 +- global.json | 8 +- src/coreclr/.nuget/Directory.Build.props | 4 +- src/coreclr/.nuget/builds.targets | 4 +- src/coreclr/CMakeLists.txt | 6 +- .../System.Private.CoreLib.csproj | 2 +- .../Reflection/Emit/CustomAttributeBuilder.cs | 6 +- .../Reflection/Emit/RuntimeAssemblyBuilder.cs | 13 +- .../Emit/RuntimeConstructorBuilder.cs | 7 +- .../Reflection/Emit/RuntimeEnumBuilder.cs | 11 +- .../Reflection/Emit/RuntimeEventBuilder.cs | 9 +- .../Reflection/Emit/RuntimeFieldBuilder.cs | 9 +- .../RuntimeGenericTypeParameterBuilder.cs | 7 +- .../Reflection/Emit/RuntimeMethodBuilder.cs | 13 +- .../Reflection/Emit/RuntimeModuleBuilder.cs | 7 +- ...rBuilder.cs => RuntimeParameterBuilder.cs} | 32 +- .../Reflection/Emit/RuntimePropertyBuilder.cs | 10 +- .../Reflection/Emit/RuntimeTypeBuilder.cs | 29 +- .../Reflection/Metadata/MetadataUpdater.cs | 2 +- .../Reflection/MethodInvoker.CoreCLR.cs | 2 +- .../Threading/LowLevelLifoSemaphore.Unix.cs | 4 +- src/coreclr/build-runtime.sh | 1 - src/coreclr/debug/createdump/createdump.h | 2 +- src/coreclr/debug/createdump/main.cpp | 4 +- src/coreclr/debug/daccess/dacdbiimpl.cpp | 6 +- src/coreclr/debug/ee/controller.cpp | 636 +- src/coreclr/debug/ee/controller.h | 173 +- src/coreclr/debug/ee/controller.inl | 21 +- src/coreclr/debug/ee/debugger.cpp | 402 +- src/coreclr/debug/ee/debugger.h | 25 +- src/coreclr/debug/ee/functioninfo.cpp | 149 +- src/coreclr/debug/ee/rcthread.cpp | 2 +- src/coreclr/debug/inc/dbgtargetcontext.h | 18 +- src/coreclr/debug/inc/riscv64/primitives.h | 18 +- src/coreclr/debug/runtimeinfo/CMakeLists.txt | 2 +- src/coreclr/gc/gc.cpp | 445 +- src/coreclr/gc/gcimpl.h | 3 +- src/coreclr/gc/gcinterface.h | 3 +- src/coreclr/gc/gcpriv.h | 43 +- src/coreclr/inc/clrconfigvalues.h | 76 +- src/coreclr/inc/corerror.xml | 14 +- src/coreclr/inc/corinfo.h | 26 +- src/coreclr/inc/corinfoinstructionset.h | 152 +- src/coreclr/inc/corjitflags.h | 2 +- src/coreclr/inc/corprof.idl | 27 + src/coreclr/inc/crosscomp.h | 2 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 12 +- src/coreclr/inc/jiteeversionguid.h | 10 +- src/coreclr/inc/jithelpers.h | 6 +- src/coreclr/inc/readytorun.h | 5 +- src/coreclr/inc/readytorunhelpers.h | 2 + src/coreclr/inc/readytoruninstructionset.h | 2 + src/coreclr/jit/CMakeLists.txt | 5 +- src/coreclr/jit/ICorJitInfo_names_generated.h | 4 +- .../jit/ICorJitInfo_wrapper_generated.hpp | 30 +- src/coreclr/jit/assertionprop.cpp | 13 +- src/coreclr/jit/block.cpp | 98 + src/coreclr/jit/block.h | 2 +- src/coreclr/jit/codegen.h | 15 +- src/coreclr/jit/codegenarm64.cpp | 121 +- src/coreclr/jit/codegenarmarch.cpp | 3 +- src/coreclr/jit/codegencommon.cpp | 7 +- src/coreclr/jit/codegenloongarch64.cpp | 415 +- src/coreclr/jit/codegenriscv64.cpp | 637 +- src/coreclr/jit/codegenxarch.cpp | 668 +- src/coreclr/jit/compiler.cpp | 47 +- src/coreclr/jit/compiler.h | 79 +- src/coreclr/jit/compiler.hpp | 35 +- src/coreclr/jit/compphases.h | 1 + src/coreclr/jit/decomposelongs.cpp | 6 +- src/coreclr/jit/earlyprop.cpp | 2 +- src/coreclr/jit/emit.cpp | 27 + src/coreclr/jit/emit.h | 334 +- src/coreclr/jit/emitarm.cpp | 6 +- src/coreclr/jit/emitarm64.cpp | 448 +- src/coreclr/jit/emitarm64.h | 94 +- src/coreclr/jit/emitfmtsxarch.h | 250 +- src/coreclr/jit/emitloongarch64.cpp | 51 +- src/coreclr/jit/emitloongarch64.h | 5 - src/coreclr/jit/emitriscv64.cpp | 126 +- src/coreclr/jit/emitxarch.cpp | 2410 +- src/coreclr/jit/emitxarch.h | 47 +- src/coreclr/jit/fgbasic.cpp | 34 +- src/coreclr/jit/fgdiagnostic.cpp | 88 +- src/coreclr/jit/fgopt.cpp | 43 +- src/coreclr/jit/fgprofile.cpp | 86 +- src/coreclr/jit/fgprofilesynthesis.cpp | 18 +- src/coreclr/jit/fgstmt.cpp | 23 +- src/coreclr/jit/flowgraph.cpp | 193 +- src/coreclr/jit/forwardsub.cpp | 2 +- src/coreclr/jit/gentree.cpp | 1919 +- src/coreclr/jit/gentree.h | 157 +- src/coreclr/jit/gschecks.cpp | 3 +- src/coreclr/jit/gtlist.h | 27 +- src/coreclr/jit/gtstructs.h | 6 +- src/coreclr/jit/helperexpansion.cpp | 128 +- src/coreclr/jit/hwintrinsic.cpp | 13 +- src/coreclr/jit/hwintrinsic.h | 12 +- src/coreclr/jit/hwintrinsicarm64.cpp | 8 +- src/coreclr/jit/hwintrinsiccodegenxarch.cpp | 423 +- src/coreclr/jit/hwintrinsiclistxarch.h | 249 +- src/coreclr/jit/hwintrinsicxarch.cpp | 72 +- src/coreclr/jit/ifconversion.cpp | 99 +- src/coreclr/jit/importer.cpp | 595 +- src/coreclr/jit/importercalls.cpp | 62 +- src/coreclr/jit/importervectorization.cpp | 8 +- src/coreclr/jit/indirectcalltransformer.cpp | 17 +- src/coreclr/jit/inlinepolicy.cpp | 6 +- src/coreclr/jit/instr.cpp | 952 +- src/coreclr/jit/instrsxarch.h | 374 +- src/coreclr/jit/jitconfigvalues.h | 71 +- src/coreclr/jit/jitee.h | 3 +- src/coreclr/jit/lclmorph.cpp | 396 +- src/coreclr/jit/lclvars.cpp | 53 - src/coreclr/jit/liveness.cpp | 39 +- src/coreclr/jit/loopcloning.cpp | 7 +- src/coreclr/jit/lower.cpp | 175 +- src/coreclr/jit/lower.h | 6 +- src/coreclr/jit/lowerarmarch.cpp | 72 +- src/coreclr/jit/lowerloongarch64.cpp | 21 +- src/coreclr/jit/lowerriscv64.cpp | 36 +- src/coreclr/jit/lowerxarch.cpp | 363 +- src/coreclr/jit/lsra.cpp | 53 +- src/coreclr/jit/lsra.h | 3 + src/coreclr/jit/lsraarm64.cpp | 6 +- src/coreclr/jit/lsrabuild.cpp | 9 +- src/coreclr/jit/lsraloongarch64.cpp | 4 + src/coreclr/jit/lsrariscv64.cpp | 75 +- src/coreclr/jit/lsraxarch.cpp | 82 +- src/coreclr/jit/morph.cpp | 390 +- src/coreclr/jit/morphblock.cpp | 463 +- src/coreclr/jit/objectalloc.cpp | 2 - src/coreclr/jit/optimizer.cpp | 119 +- src/coreclr/jit/promotion.cpp | 764 +- src/coreclr/jit/promotion.h | 135 +- src/coreclr/jit/promotiondecomposition.cpp | 593 + src/coreclr/jit/rangecheck.cpp | 3 +- src/coreclr/jit/rationalize.cpp | 170 +- src/coreclr/jit/rationalize.h | 5 - src/coreclr/jit/redundantbranchopts.cpp | 13 +- src/coreclr/jit/scopeinfo.cpp | 2 +- src/coreclr/jit/sideeffects.cpp | 7 +- src/coreclr/jit/simd.cpp | 152 +- src/coreclr/jit/simd.h | 7 + src/coreclr/jit/simdashwintrinsic.cpp | 10 +- src/coreclr/jit/simdcodegenxarch.cpp | 41 + src/coreclr/jit/ssabuilder.cpp | 76 +- src/coreclr/jit/target.h | 24 +- src/coreclr/jit/unwindamd64.cpp | 8 + .../jit/{unwindarm.cpp => unwindarmarch.cpp} | 12 +- src/coreclr/jit/unwindloongarch64.cpp | 8 + src/coreclr/jit/unwindriscv64.cpp | 84 +- src/coreclr/jit/utils.cpp | 3 +- src/coreclr/jit/valuenum.cpp | 442 +- src/coreclr/jit/valuenum.h | 14 +- src/coreclr/jit/valuenumfuncs.h | 2 - .../BuildFrameworkNativeObjects.proj | 3 +- ...soft.DotNet.ILCompiler.SingleEntry.targets | 13 +- .../Microsoft.NETCore.Native.Unix.targets | 9 +- .../Microsoft.NETCore.Native.Windows.targets | 2 +- .../Microsoft.NETCore.Native.targets | 8 +- .../src/Internal/Runtime/MethodTable.cs | 406 +- .../src/Internal/Runtime/TypeManagerHandle.cs | 9 - src/coreclr/nativeaot/Directory.Build.props | 3 +- .../src/System/Runtime/DispatchResolve.cs | 12 +- .../src/System/Runtime/ExceptionHandling.cs | 13 +- .../src/System/Runtime/MethodTable.Runtime.cs | 2 +- .../src/System/Runtime/RuntimeExports.cs | 6 +- .../src/System/Runtime/TypeCast.cs | 101 +- src/coreclr/nativeaot/Runtime/AsmOffsets.h | 7 + src/coreclr/nativeaot/Runtime/DebugHeader.cpp | 7 +- src/coreclr/nativeaot/Runtime/EHHelpers.cpp | 27 +- .../nativeaot/Runtime/IntrinsicConstants.h | 7 + src/coreclr/nativeaot/Runtime/MethodTable.cpp | 8 +- .../nativeaot/Runtime/StackFrameIterator.cpp | 39 +- .../nativeaot/Runtime/StackFrameIterator.h | 1 + src/coreclr/nativeaot/Runtime/TypeManager.cpp | 1 - src/coreclr/nativeaot/Runtime/TypeManager.h | 3 - .../nativeaot/Runtime/amd64/AsmMacros.inc | 1 - .../nativeaot/Runtime/amd64/GetThread.asm | 27 - .../nativeaot/Runtime/amd64/WriteBarriers.S | 5 + .../nativeaot/Runtime/amd64/WriteBarriers.asm | 5 + .../nativeaot/Runtime/arm/GetThread.asm | 32 - .../nativeaot/Runtime/arm/WriteBarriers.S | 5 + .../nativeaot/Runtime/arm64/AllocFast.asm | 7 - .../nativeaot/Runtime/arm64/AsmMacros.h | 56 +- .../Runtime/arm64/ExceptionHandling.asm | 2 - .../nativeaot/Runtime/arm64/GcProbe.asm | 2 - .../nativeaot/Runtime/arm64/GetThread.asm | 29 - .../nativeaot/Runtime/arm64/PInvoke.asm | 2 - .../nativeaot/Runtime/arm64/WriteBarriers.S | 57 +- .../nativeaot/Runtime/arm64/WriteBarriers.asm | 53 +- .../nativeaot/Runtime/forward_declarations.h | 1 - .../nativeaot/Runtime/i386/GetThread.asm | 31 - .../nativeaot/Runtime/inc/MethodTable.h | 39 +- .../nativeaot/Runtime/inc/MethodTable.inl | 7 +- .../nativeaot/Runtime/inc/ModuleHeaders.h | 4 +- src/coreclr/nativeaot/Runtime/startup.cpp | 13 +- src/coreclr/nativeaot/Runtime/thread.cpp | 30 +- src/coreclr/nativeaot/Runtime/threadstore.cpp | 58 +- src/coreclr/nativeaot/Runtime/threadstore.h | 1 - .../nativeaot/Runtime/unix/UnwindHelpers.cpp | 4 +- .../Runtime/Augments/RuntimeAugments.cs | 43 + .../CompilerHelpers/SharedCodeHelpers.cs | 2 +- .../src/System.Private.CoreLib.csproj | 1 - .../src/System/Array.NativeAot.cs | 4 +- .../src/System/EETypePtr.cs | 17 +- .../Reflection/Emit/CustomAttributeBuilder.cs | 5 + .../Reflection/Emit/ParameterBuilder.cs | 73 - .../Reflection/ModifiedType.NativeAot.cs | 115 +- .../NativeFormatRuntimeFieldInfo.cs | 2 + .../Runtime/General/QSignatureTypeHandle.cs | 5 + .../RuntimeMethodParameterInfo.cs | 2 + .../NativeFormatRuntimePropertyInfo.cs | 6 + .../RuntimeHelpers.NativeAot.cs | 12 +- .../InteropServices/ComWrappers.NativeAot.cs | 184 +- .../src/System/Runtime/RuntimeImports.cs | 11 - .../src/System/RuntimeExceptionHelpers.cs | 425 +- .../src/System/RuntimeTypeHandle.cs | 13 +- .../Threading/LowLevelLifoSemaphore.Unix.cs | 4 +- ...EnvironmentImplementation.MappingTables.cs | 4 +- .../Runtime/TypeLoader/EETypeCreator.cs | 86 +- .../TypeLoader/NativeLayoutInfoLoadContext.cs | 24 +- .../Runtime/TypeLoader/TypeBuilder.cs | 86 +- .../Runtime/TypeLoader/TypeBuilderState.cs | 13 +- ...vironment.ConstructedGenericTypesLookup.cs | 62 +- .../TypeLoaderEnvironment.Metadata.cs | 92 +- .../TypeLoader/TypeLoaderEnvironment.cs | 85 +- .../Internal/TypeSystem/TypeDesc.Runtime.cs | 44 +- .../TypeSystem/TypeSystemContext.Runtime.cs | 72 +- src/coreclr/nativeaot/docs/compiling.md | 3 + src/coreclr/nativeaot/docs/optimizing.md | 9 +- src/coreclr/pal/inc/pal.h | 2 +- src/coreclr/pal/prebuilt/corerror/mscorurt.rc | 2 + src/coreclr/pal/prebuilt/idl/corprof_i.cpp | 3 + src/coreclr/pal/prebuilt/inc/corerror.h | 1 + src/coreclr/pal/prebuilt/inc/corprof.h | 22765 +++++++++------- src/coreclr/runtime.proj | 11 +- src/coreclr/scripts/superpmi.py | 2 +- .../SortableDependencyNode.cs | 2 + .../NativeFormat/Generator/SchemaDef.cs | 8 +- .../NativeFormat/NativeFormatReaderGen.cs | 8 +- .../Internal/NativeFormat/NativeFormat.cs | 3 +- .../NativeFormat/NativeFormatWriter.cs | 37 + .../Internal/Runtime/EETypeBuilderHelpers.cs | 5 + .../Internal/Runtime/MappingTableFlags.cs | 6 - .../Common/Internal/Runtime/MetadataBlob.cs | 4 +- .../Internal/Runtime/MethodTable.Constants.cs | 43 +- .../Common/Internal/Runtime/ModuleHeaders.cs | 4 +- .../Internal/Runtime/ReadyToRunConstants.cs | 4 +- .../Runtime/ReadyToRunInstructionSet.cs | 2 + .../Runtime/ReadyToRunInstructionSetHelper.cs | 8 + .../Common/JitInterface/CorInfoHelpFunc.cs | 6 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 2 - .../JitInterface/CorInfoImpl_generated.cs | 186 +- .../JitInterface/CorInfoInstructionSet.cs | 164 +- .../tools/Common/JitInterface/CorInfoTypes.cs | 4 +- .../ThunkGenerator/InstructionSetDesc.txt | 130 +- .../ThunkGenerator/ThunkInput.txt | 4 +- .../Common/TypeSystem/Common/FieldDesc.cs | 2 + .../Common/FieldForInstantiatedType.cs | 8 + .../TypeSystem/Common/PropertySignature.cs | 13 +- .../tools/Common/TypeSystem/Ecma/EcmaField.cs | 20 +- .../TypeSystem/Ecma/EcmaSignatureParser.cs | 51 +- .../IL/Stubs/ArrayMethodILEmitter.cs | 6 +- .../IL/Stubs/PInvokeLazyFixupField.cs | 2 + .../TypeSystem/Interop/IL/InlineArrayType.cs | 2 + .../TypeSystem/Interop/IL/NativeStructType.cs | 2 + .../TypeSystemMetadataEmitter.cs | 10 +- .../ILVerification/ILImporter.StackValue.cs | 3 +- .../SuperFileCheck/SuperFileCheck.csproj | 8 +- .../aot/DependencyGraphViewer/NodeForm.cs | 18 +- .../aot/DependencyGraphViewer/Program.cs | 16 + .../Compiler/Compilation.cs | 24 +- .../Compiler/Dataflow/FlowAnnotations.cs | 4 + .../Compiler/Dataflow/MethodBodyScanner.cs | 22 +- .../Compiler/Dataflow/ReflectionMarker.cs | 186 +- .../Dataflow/ReflectionMethodBodyScanner.cs | 47 +- .../Dataflow/TrimAnalysisPatternStore.cs | 10 +- ...n.cs => TrimAnalysisTokenAccessPattern.cs} | 10 +- .../DependencyAnalysis/ArrayMapNode.cs | 12 +- .../DependencyAnalysis/ByRefTypeMapNode.cs | 73 + .../DependencyAnalysis/CanonicalEETypeNode.cs | 3 - .../ConstructedEETypeNode.cs | 6 - ...DynamicDependencyAttributesOnEntityNode.cs | 27 +- .../Compiler/DependencyAnalysis/EETypeNode.cs | 136 +- .../DependencyAnalysis/FieldMetadataNode.cs | 7 + .../DependencyAnalysis/FrozenObjectNode.cs | 2 + .../FunctionPointerMapNode.cs | 20 +- .../GenericCompositionNode.cs | 194 +- .../GenericDefinitionEETypeNode.cs | 7 + .../DependencyAnalysis/GenericVarianceNode.cs | 147 + .../InterfaceDispatchMapNode.cs | 1 - .../DependencyAnalysis/MethodMetadataNode.cs | 7 + .../NativeLayoutVertexNode.cs | 46 +- .../NodeFactory.NativeLayout.cs | 20 +- .../DependencyAnalysis/NodeFactory.cs | 27 +- .../DependencyAnalysis/ObjectWriter.cs | 4 +- .../DependencyAnalysis/PointerTypeMapNode.cs | 73 + .../Compiler/ExternSymbolMappedField.cs | 1 + .../Compiler/HardwareIntrinsicHelpers.Aot.cs | 6 + .../ILCompiler.Compiler/Compiler/JitHelper.cs | 4 - .../ILCompiler.Compiler/Compiler/Logger.cs | 5 - .../Compiler/MetadataManager.cs | 6 + .../Compiler/TypePreinit.cs | 44 +- .../ILCompiler.Compiler.csproj | 5 +- .../ILCompiler/Metadata/Transform.Field.cs | 25 +- .../ILCompiler/Metadata/Transform.Method.cs | 50 +- .../ILCompiler/Metadata/Transform.Property.cs | 17 +- .../ILCompiler/Metadata/Transform.Type.cs | 136 + .../Writer/NativeFormatWriterGen.cs | 12 +- .../ReadyToRunCodegenCompilationBuilder.cs | 4 + .../JitInterface/CorInfoImpl.ReadyToRun.cs | 13 +- .../ReadyToRunSignature.cs | 8 + .../JitInterface/CorInfoImpl.RyuJit.cs | 33 +- .../reproNative/reproNative.vcxproj | 6 +- .../Mono.Linker.Tests.csproj | 3 + .../TestCases/TestDatabase.cs | 5 + .../Mono.Linker.Tests/TestCases/TestSuites.cs | 14 + .../TestCasesRunner/AssemblyChecker.cs | 11 +- .../TestCasesRunner/AssemblyQualifiedToken.cs | 2 + .../TestCasesRunner/ILCompilerDriver.cs | 10 + .../TestCasesRunner/ILInputCompiler.cs | 5 +- .../TestCasesRunner/ResultChecker.cs | 21 +- .../TestCasesRunner/TestRunner.cs | 8 +- .../aot/jitinterface/jitinterface_generated.h | 30 +- .../TypeRefTypeSystemField.cs | 2 + .../tools/superpmi/superpmi-shared/lwmlist.h | 4 +- .../superpmi-shared/methodcontext.cpp | 106 +- .../superpmi/superpmi-shared/methodcontext.h | 19 +- .../superpmi-shim-collector/icorjitinfo.cpp | 25 +- .../icorjitinfo_generated.cpp | 24 +- .../icorjitinfo_generated.cpp | 20 +- .../tools/superpmi/superpmi/icorjitinfo.cpp | 19 +- src/coreclr/utilcode/log.cpp | 4 +- src/coreclr/vm/ceeload.cpp | 60 +- src/coreclr/vm/ceeload.h | 21 +- src/coreclr/vm/class.cpp | 529 +- src/coreclr/vm/class.h | 75 +- src/coreclr/vm/codeman.cpp | 31 +- src/coreclr/vm/codeversion.cpp | 3 - src/coreclr/vm/crst.cpp | 4 +- src/coreclr/vm/eepolicy.cpp | 29 +- src/coreclr/vm/encee.cpp | 144 +- src/coreclr/vm/encee.h | 36 +- src/coreclr/vm/field.h | 2 +- src/coreclr/vm/frozenobjectheap.cpp | 31 + src/coreclr/vm/frozenobjectheap.h | 10 +- src/coreclr/vm/gchelpers.cpp | 108 + src/coreclr/vm/gchelpers.h | 6 + src/coreclr/vm/genericdict.cpp | 1 + src/coreclr/vm/generics.cpp | 1 - src/coreclr/vm/genmeth.cpp | 7 +- src/coreclr/vm/interpreter.h | 3 +- src/coreclr/vm/jithelpers.cpp | 106 +- src/coreclr/vm/jitinterface.cpp | 108 +- src/coreclr/vm/jitinterface.h | 1 + src/coreclr/vm/memberload.cpp | 183 +- src/coreclr/vm/method.cpp | 32 +- src/coreclr/vm/method.hpp | 25 +- src/coreclr/vm/methoditer.cpp | 10 +- src/coreclr/vm/methodtable.cpp | 91 +- src/coreclr/vm/methodtable.h | 10 +- src/coreclr/vm/methodtablebuilder.cpp | 14 +- src/coreclr/vm/object.h | 1 + src/coreclr/vm/prestub.cpp | 2 +- src/coreclr/vm/profilingenumerators.cpp | 37 + src/coreclr/vm/profilingenumerators.h | 13 +- src/coreclr/vm/proftoeeinterfaceimpl.cpp | 110 + src/coreclr/vm/proftoeeinterfaceimpl.h | 13 +- src/coreclr/vm/riscv64/asmconstants.h | 2 +- src/coreclr/vm/runtimehandles.cpp | 3 +- src/coreclr/vm/syncblk.cpp | 59 +- src/coreclr/vm/syncblk.h | 18 +- src/coreclr/vm/threads.cpp | 1 + src/coreclr/vm/threadsuspend.cpp | 2 +- src/coreclr/vm/typedesc.cpp | 44 +- src/coreclr/vm/typedesc.h | 4 + src/coreclr/vm/typehandle.cpp | 9 +- src/installer/Directory.Build.props | 4 +- .../pkg/projects/Directory.Build.props | 2 +- .../Microsoft.DotNet.ILCompiler.pkgproj | 1 - .../Microsoft.DotNet.ILCompiler/sdk/Sdk.props | 22 - src/installer/pkg/projects/host-packages.proj | 2 +- .../pkg/projects/nativeaot-packages.proj | 2 +- .../Directory.Build.props | 14 +- .../Microsoft.NETCore.App.Crossgen2.sfxproj | 1 - .../Microsoft.NETCore.App.Runtime.props | 34 +- src/installer/tests/Directory.Build.targets | 2 +- .../Interop.Evp.cs | 34 - .../Interop/Browser/Interop.CompareInfo.cs | 6 + .../Interop.OpenSsl.cs | 5 +- .../Interop.Ssl.cs | 5 +- .../Interop.SslCtx.cs | 5 +- .../src/System/IO/Archiving.Utils.Windows.cs | 2 +- .../src/System/Net/CaseInsensitiveAscii.cs | 21 +- .../Net/Http/aspnetcore/ReadMe.SharedCode.md | 7 + .../NetworkInformation/UnixCommandLinePing.cs | 4 +- .../Net/Security/TargetHostNameHelper.cs | 83 + .../Net/WebSockets/WebSocketValidate.cs | 4 +- .../Cryptography/IncrementalHash.netfx.cs | 231 + .../Common/src/System/TimeProvider.cs | 27 +- .../tests/SourceGenerators/RoslynTestUtils.cs | 15 +- .../FunctionPointerCallingConventionTests.cs | 8 - .../System/FunctionPointerEqualityTests.cs | 3 - .../tests/System/FunctionPointerTests.cs | 4 - .../Common/tests/System/ModifiedTypeTests.cs | 36 +- .../System/Net/Capability.Security.Unix.cs | 2 +- .../setup/linuxclient/Dockerfile | 23 +- .../System/Reflection/InvokeEmitTests.cs | 4 +- .../Reflection/InvokeInterpretedTests.cs | 4 +- .../AlgorithmImplementations/DES/DesTests.cs | 1 + .../Common/tests/System/TimeProviderTests.cs | 155 +- src/libraries/Directory.Build.props | 1 - .../src/Microsoft.Bcl.Cryptography.csproj | 4 - ...SP800108HmacCounterKdfImplementationCng.cs | 24 +- ...0108HmacCounterKdfImplementationManaged.cs | 46 +- .../ref/Microsoft.Bcl.TimeProvider.Common.cs | 1 + .../src/Microsoft.Bcl.TimeProvider.csproj | 13 +- .../Tasks/TimeProviderTaskExtensions.cs | 122 +- ...igurationBindingSourceGenerator.Emitter.cs | 8 +- ...igurationBindingSourceGenerator.Helpers.cs | 37 +- ...figurationBindingSourceGenerator.Parser.cs | 33 +- .../ConfigurationBindingSourceGenerator.cs | 2 + .../gen/ExceptionMessages.cs | 2 +- ...nfiguration.Binder.SourceGeneration.csproj | 19 +- .../gen/PopulationStrategy.cs | 14 - .../gen/Resources/Strings.resx | 25 +- .../gen/Resources/xlf/Strings.cs.xlf | 41 +- .../gen/Resources/xlf/Strings.de.xlf | 41 +- .../gen/Resources/xlf/Strings.es.xlf | 41 +- .../gen/Resources/xlf/Strings.fr.xlf | 41 +- .../gen/Resources/xlf/Strings.it.xlf | 41 +- .../gen/Resources/xlf/Strings.ja.xlf | 41 +- .../gen/Resources/xlf/Strings.ko.xlf | 41 +- .../gen/Resources/xlf/Strings.pl.xlf | 41 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 41 +- .../gen/Resources/xlf/Strings.ru.xlf | 41 +- .../gen/Resources/xlf/Strings.tr.xlf | 41 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 41 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 41 +- .../gen/SourceGenerationSpec.cs | 2 - .../gen/{ => TypeGraph}/CollectionSpec.cs | 0 .../ConfigurationSectionTypeSpec.cs | 0 .../{ => TypeGraph}/ConstructionStrategy.cs | 0 .../gen/{ => TypeGraph}/NullableSpec.cs | 0 .../gen/{ => TypeGraph}/ObjectSpec.cs | 0 .../ParsableFromStringTypeSpec.cs | 0 .../gen/{ => TypeGraph}/PropertySpec.cs | 0 .../gen/{ => TypeGraph}/TypeSpec.cs | 0 .../gen/{ => TypeGraph}/TypeSpecKind.cs | 0 .../TestConfigureCallGen.generated.txt | 2 +- .../Baselines/TestGetCallGen.generated.txt | 2 +- .../src/ActivatorUtilities.cs | 20 +- .../tests/DI.Tests/ActivatorUtilitiesTests.cs | 61 +- .../ServiceLookup/CallSiteFactoryTest.cs | 3 +- .../src/EnvironmentWrapper.cs | 9 +- ...icrosoft.Extensions.DependencyModel.csproj | 1 - .../DotNetReferenceAssembliesPathResolver.cs | 15 +- .../src/Internal/PathUtils.cs | 18 +- ...t.Extensions.FileProviders.Physical.csproj | 7 +- .../src/Resources/Strings.resx | 9 + .../src/WindowsServiceHelpers.cs | 8 +- ...owsServiceLifetimeHostBuilderExtensions.cs | 6 + .../src/HostingHostBuilderExtensions.cs | 10 +- .../src/Internal/ConsoleLifetime.cs | 8 + .../src/Internal/Host.cs | 47 +- .../src/Microsoft.Extensions.Hosting.csproj | 1 - .../tests/UnitTests/DelegateHostedService.cs | 8 +- .../tests/UnitTests/HostTests.cs | 16 +- .../gen/DiagnosticDescriptors.cs | 2 +- .../gen/LoggerMessageGenerator.Emitter.cs | 4 +- .../src/ConsoleLoggerProcessor.cs | 2 +- .../src/ConsoleLoggerProvider.cs | 8 +- ...icrosoft.Extensions.Logging.Console.csproj | 2 - .../ConsoleLoggerProcessorTests.cs | 33 +- .../ref/System.Collections.Immutable.cs | 8 + .../src/System.Collections.Immutable.csproj | 2 +- .../Collections/Frozen/FrozenDictionary.cs | 5 +- .../System/Collections/Frozen/FrozenSet.cs | 3 +- .../Frozen/ImmutableArrayFactory.cs | 19 - .../Collections/Frozen/String/KeyAnalyzer.cs | 6 +- .../Collections/Immutable/ImmutableArray_1.cs | 27 +- .../Collections/Immutable/ImmutableList_1.cs | 2 +- .../Immutable/ImmutableSortedSet_1.cs | 20 +- .../ImmutableCollectionsMarshal.cs | 58 + .../tests/Frozen/FrozenDictionaryTests.cs | 2 +- .../tests/Frozen/FrozenSetTests.cs | 2 +- .../tests/ImmutableCollectionsMarshal.cs | 156 + .../tests/ImmutableListTestBase.cs | 1 - .../tests/ImmutableSortedSetTest.cs | 5 + .../tests/IndexOfTests.cs | 2 + .../System.Collections.Immutable.Tests.csproj | 8 + .../ComponentModel/DateOnlyConverter.cs | 7 +- .../ComponentModel/DateTimeConverter.cs | 2 +- .../ComponentModel/DateTimeOffsetConverter.cs | 2 +- .../ComponentModel/MaskedTextProvider.cs | 8 +- .../ComponentModel/TimeOnlyConverter.cs | 5 +- .../tests/DateOnlyConverterTests.cs | 11 +- .../tests/DateTimeConverterTests.cs | 19 +- .../tests/DateTimeOffsetConverterTests.cs | 19 +- .../tests/TimeOnlyConverterTests.cs | 14 +- .../tests/TypeConverterTestBase.cs | 6 +- .../src/System/Data/DataSetUtil.cs | 21 +- .../System/Diagnostics/Metrics/Aggregator.cs | 6 +- .../Metrics/ExponentialHistogramAggregator.cs | 45 +- .../Diagnostics/Metrics/MetricsEventSource.cs | 8 +- .../tests/ExponentialHistogramTests.cs | 54 + .../tests/MetricEventSourceTests.cs | 44 +- .../System/Formats/Asn1/AsnDecoder.Text.cs | 32 +- .../tests/Reader/ReadUTF8String.cs | 3 - .../src/Resources/Strings.resx | 8 +- .../src/System/Formats/Tar/TarHeader.cs | 22 +- .../tests/TarEntry/PaxTarEntry.Tests.cs | 27 +- .../CompareInfo/CompareInfoTests.IsPrefix.cs | 67 +- .../CompareInfo/CompareInfoTests.IsSuffix.cs | 64 +- .../tests/CompareInfo/CompareInfoTestsBase.cs | 1 + .../tests/Hybrid/Hybrid.WASM.Tests.csproj | 2 + .../System/Globalization/TextInfoTests.cs | 16 +- .../src/System.IO.Hashing.csproj | 6 + .../src/System/IO/Hashing/Crc32.Arm.cs | 69 + .../src/System/IO/Hashing/Crc32.Vectorized.cs | 216 + .../src/System/IO/Hashing/Crc32.cs | 26 + .../src/System/ThrowHelper.cs | 14 + .../System.IO.Hashing/tests/Crc32Tests.cs | 15 + .../pkg/runtime.native.System.IO.Ports.proj | 2 +- .../pkg/runtime.native.System.IO.Ports.props | 4 +- .../System.IO/tests/IndentedTextWriter.cs | 57 +- .../StreamWriter/StreamWriter.FlushTests.cs | 68 +- .../tests/StringWriter/StringWriterTests.cs | 21 +- .../tests/TextWriter/TextWriterTests.cs | 31 + .../System.Linq/src/System/Linq/Enumerable.cs | 11 + .../System/Linq/OrderedEnumerable.SpeedOpt.cs | 46 +- .../src/System/Linq/Partition.SpeedOpt.cs | 19 +- .../src/System/Linq/Range.SpeedOpt.cs | 20 +- .../src/System/Linq/Repeat.SpeedOpt.cs | 5 +- .../src/System/Linq/Select.SpeedOpt.cs | 114 +- .../System.Linq/src/System/Linq/Select.cs | 14 +- .../System.Linq/tests/ToArrayTests.cs | 1 + .../System.Memory/ref/System.Memory.cs | 16 +- .../tests/MemoryMarshal/GetReference.cs | 12 + .../tests/Span/IndexOfAny.byte.cs | 8 +- .../tests/Span/IndexOfAny.char.cs | 8 +- .../tests/Span/IndexOfAnyExcept.T.cs | 32 +- .../tests/Span/LastIndexOfAny.byte.cs | 8 +- .../{IndexOfAnyValues.cs => SearchValues.cs} | 92 +- .../tests/System.Memory.Tests.csproj | 2 +- .../src/System.Net.Http.csproj | 1 - .../src/System/Net/Http/ByteArrayHelpers.cs | 62 - .../Net/Http/Headers/HeaderDescriptor.cs | 4 +- .../Net/Http/Headers/HeaderUtilities.cs | 4 +- .../System/Net/Http/Headers/KnownHeaders.cs | 3 +- .../src/System/Net/Http/HttpRuleParser.cs | 12 +- .../src/System/Net/Http/MultipartContent.cs | 4 +- .../Http/SocketsHttpHandler/HttpConnection.cs | 2 +- .../SocketsHttpHandler/HttpConnectionBase.cs | 2 +- .../System.Net.Http.Functional.Tests.csproj | 3 + .../tests/FunctionalTests/TelemetryTest.cs | 1 + .../HttpStress/Directory.Build.props | 11 +- .../tests/StressTests/HttpStress/Dockerfile | 1 + .../StressTests/HttpStress/HttpStress.csproj | 7 + .../tests/StressTests/HttpStress/Program.cs | 26 + .../StressTests/HttpStress/build-local.ps1 | 6 +- .../StressTests/HttpStress/windows.Dockerfile | 1 + .../System.Net.Http.Unit.Tests.csproj | 2 - .../System/Net/Managed/HttpEndPointManager.cs | 8 +- .../Managed/HttpListenerRequest.Managed.cs | 2 +- .../src/System/Net/Mail/MailBnfHelper.cs | 8 +- .../src/System/Net/Cookie.cs | 6 +- .../System.Net.Quic/ref/System.Net.Quic.cs | 2 + .../src/System.Net.Quic.csproj | 6 +- .../src/System/Net/Quic/Internal/MsQuicApi.cs | 4 +- .../Net/Quic/Internal/MsQuicConfiguration.cs | 13 +- .../QuicConnection.SslConnectionOptions.cs | 8 +- .../src/System/Net/Quic/QuicConnection.cs | 26 +- .../tests/FunctionalTests/MsQuicTests.cs | 55 +- .../FunctionalTests/QuicConnectionTests.cs | 5 +- .../tests/FunctionalTests/QuicTestBase.cs | 12 +- .../System.Net.Quic.Functional.Tests.csproj | 13 +- .../ref/System.Net.Security.cs | 13 +- .../src/CompatibilitySuppressions.xml | 130 - .../src/ReferenceAssemblyExclusions.txt | 4 - .../src/System.Net.Security.csproj | 2 + .../Pal.Android/SafeDeleteSslContext.cs | 8 +- .../Security/Pal.OSX/SafeDeleteSslContext.cs | 6 +- .../Net/Security/SslAuthenticationOptions.cs | 71 +- .../System/Net/Security/SslStream.Protocol.cs | 19 +- .../SslStreamCertificateContext.Android.cs | 7 +- .../SslStreamCertificateContext.Linux.cs | 17 +- .../SslStreamCertificateContext.OSX.cs | 7 +- .../SslStreamCertificateContext.Windows.cs | 15 +- .../Security/SslStreamCertificateContext.cs | 19 +- .../Net/Security/SslStreamPal.Windows.cs | 10 +- .../SslAuthenticationOptionsTest.cs | 1 - .../tests/FunctionalTests/SslStreamSniTest.cs | 48 + .../SslStress/Directory.Build.props | 6 +- .../UnitTests/NegotiateAuthenticationTests.cs | 5 - .../System.Net.Security.Unit.Tests.csproj | 2 + .../tests/CloseTest.cs | 1 + .../tests/SendReceiveTest.cs | 2 +- .../System.Net.WebSockets.Client.Tests.csproj | 7 +- .../ILLink.Substitutions.NoX86Intrinsics.xml | 9 + .../src/Resources/Strings.resx | 21 + .../System.Private.CoreLib.Shared.projitems | 55 +- .../src/System/Buffers/StandardFormat.cs | 3 + .../src/System/Buffers/Text/Base64Decoder.cs | 2 + .../src/System/Buffers/Text/Base64Encoder.cs | 2 + .../Utf8Formatter/Utf8Formatter.Integer.cs | 155 +- .../CodeDom/Compiler/IndentedTextWriter.cs | 11 + .../src/System/Convert.cs | 112 +- .../System/Globalization/CompareInfo.Icu.cs | 4 +- .../Globalization/CompareInfo.WebAssembly.cs | 74 +- .../src/System/Globalization/CompareInfo.cs | 22 +- .../src/System/Globalization/DateTimeParse.cs | 75 +- .../src/System/Globalization/Ordinal.cs | 213 +- .../System.Private.CoreLib/src/System/Guid.cs | 1 + .../src/System/IO/File.cs | 6 +- .../src/System/IO/StreamWriter.cs | 30 +- .../src/System/IO/TextWriter.cs | 25 + .../src/System/MemoryExtensions.cs | 24 +- .../src/System/Number.Formatting.cs | 18 +- .../src/System/Random.Net5CompatImpl.cs | 21 +- .../System/Reflection/ConstructorInvoker.cs | 4 +- .../System/Reflection/Emit/AssemblyBuilder.cs | 6 +- .../Reflection/Emit/ConstructorBuilder.cs | 15 +- .../src/System/Reflection/Emit/EnumBuilder.cs | 6 +- .../System/Reflection/Emit/EventBuilder.cs | 6 +- .../System/Reflection/Emit/FieldBuilder.cs | 6 +- .../Emit/GenericTypeParameterBuilder.cs | 6 +- .../System/Reflection/Emit/MethodBuilder.cs | 11 +- .../System/Reflection/Emit/ModuleBuilder.cs | 6 +- .../Reflection/Emit/ParameterBuilder.cs | 35 + .../System/Reflection/Emit/PropertyBuilder.cs | 7 +- .../src/System/Reflection/Emit/TypeBuilder.cs | 6 +- .../src/System/Reflection/InvokerEmitUtil.cs | 13 +- .../src/System/Reflection/MethodInvoker.cs | 2 +- .../src/System/Resources/ResourceManager.cs | 4 +- .../Runtime/BypassReadyToRunAttribute.cs | 10 + .../InteropServices/CollectionsMarshal.cs | 36 + .../Marshalling/SafeHandleMarshaller.cs | 199 + .../Runtime/InteropServices/SafeHandle.cs | 2 +- .../Wasm/PackedSimd.PlatformNotSupported.cs | 186 + .../Runtime/Intrinsics/Wasm/PackedSimd.cs | 795 + .../X86/Avx512BW.PlatformNotSupported.cs | 229 + .../System/Runtime/Intrinsics/X86/Avx512BW.cs | 229 + .../X86/Avx512DQ.PlatformNotSupported.cs | 421 + .../System/Runtime/Intrinsics/X86/Avx512DQ.cs | 422 + .../X86/Avx512F.PlatformNotSupported.cs | 1746 +- .../System/Runtime/Intrinsics/X86/Avx512F.cs | 1746 +- .../X86/Avx512Vbmi.PlatformNotSupported.cs | 66 + .../Runtime/Intrinsics/X86/Avx512Vbmi.cs | 67 + .../Runtime/Loader/AssemblyLoadContext.cs | 5 + .../Any2ByteSearchValues.cs} | 4 +- .../Any2CharSearchValues.cs} | 6 +- .../Any3ByteSearchValues.cs} | 4 +- .../Any3CharSearchValues.cs} | 6 +- .../Any4SearchValues.cs} | 4 +- .../Any5SearchValues.cs} | 4 +- .../AnyByteSearchValues.cs} | 4 +- .../AsciiByteSearchValues.cs} | 4 +- .../AsciiCharSearchValues.cs} | 4 +- .../BitVector256.cs | 0 .../EmptySearchValues.cs} | 2 +- .../IndexOfAnyAsciiSearcher.cs | 13 +- .../Latin1CharSearchValues.cs} | 6 +- .../ProbabilisticCharSearchValues.cs} | 15 +- .../ProbabilisticMap.cs | 20 +- .../RangeByteSearchValues.cs} | 4 +- .../RangeCharSearchValues.cs} | 6 +- .../SearchValues.T.cs} | 20 +- .../SearchValues.cs} | 64 +- .../SearchValuesDebugView.cs} | 6 +- .../SingleByteSearchValues.cs} | 4 +- .../SingleCharSearchValues.cs} | 6 +- .../src/System/SpanHelpers.Packed.cs | 5 + .../src/System/String.Manipulation.cs | 19 +- .../src/System/Text/ASCIIEncoding.cs | 35 +- .../src/System/Text/Ascii.Equality.cs | 366 + .../src/System/Text/CompositeFormat.cs | 82 +- .../src/System/Text/Encoding.Internal.cs | 26 +- .../src/System/Text/Encoding.cs | 21 +- .../src/System/Text/Latin1Encoding.cs | 26 +- .../src/System/Text/SpanLineEnumerator.cs | 2 +- .../src/System/Text/StringBuilder.cs | 12 +- .../src/System/Text/UTF8Encoding.Sealed.cs | 4 +- .../src/System/Text/UTF8Encoding.cs | 35 +- .../src/System/Text/Unicode/Utf8.cs | 65 +- .../Text/ValueStringBuilder.AppendFormat.cs | 12 +- .../LowLevelLifoSemaphore.Windows.cs | 2 +- .../System/Threading/LowLevelLifoSemaphore.cs | 204 +- .../Threading/LowLevelLifoSemaphoreBase.cs | 211 + .../System/Threading/ThreadPool.Portable.cs | 2 + .../src/System/ThrowHelper.cs | 15 + .../src/System/TimeZoneInfo.cs | 42 +- .../src/System/Xml/ValueHandle.cs | 3 +- .../src/System/Xml/XmlConverter.cs | 4 +- .../src/System/DomainNameHelper.cs | 16 +- .../System.Private.Uri/src/System/Uri.cs | 8 +- .../src/System/UriBuilder.cs | 4 +- .../src/System/UriHelper.cs | 22 +- .../System/Xml/BinaryXml/XmlBinaryReader.cs | 16 +- .../Xml/Schema/DataTypeImplementation.cs | 157 +- .../src/System/Xml/XPath/XPathDocument.cs | 4 +- .../src/System/Xml/XmlCharType.cs | 6 +- .../Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlQueryContext.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlQueryRuntime.cs | 18 +- .../src/System/Xml/Xsl/Runtime/XsltConvert.cs | 95 +- .../System/Xml/Xsl/Runtime/XsltFunctions.cs | 6 +- .../src/System/Xml/Xsl/Runtime/XsltLibrary.cs | 6 +- .../System/Xml/Xsl/Xslt/QilGeneratorEnv.cs | 4 +- .../System.Reflection.Emit.ILGeneration.cs | 5 +- .../System.Reflection.Emit.sln | 42 - .../ref/System.Reflection.Emit.cs | 30 +- .../src/Resources/Strings.resx | 37 +- .../src/System.Reflection.Emit.csproj | 4 +- .../Reflection/Emit/AssemblyBuilderImpl.cs | 35 +- .../Reflection/Emit/CustomAttributeWrapper.cs | 179 + .../Reflection/Emit/FieldBuilderImpl.cs | 52 +- .../System/Reflection/Emit/MetadataHelper.cs | 78 - .../Reflection/Emit/MethodBuilderImpl.cs | 72 +- .../Reflection/Emit/ModuleBuilderImpl.cs | 294 +- .../Reflection/Emit/ParameterBuilderImpl.cs | 63 + .../Emit/PseudoCustomAttributesData.cs | 495 + .../System/Reflection/Emit/SignatureHelper.cs | 81 +- .../System/Reflection/Emit/TypeBuilderImpl.cs | 145 +- ...cTypeParameterBuilderSetCustomAttribute.cs | 11 - .../AssemblySaveCustomAttributeTests.cs | 462 + ...=> AssemblySaveWithVariousMembersTests.cs} | 145 +- .../AssemblyTools.cs | 135 +- .../tests/System.Reflection.Emit.Tests.csproj | 3 +- .../ref/System.Reflection.Metadata.cs | 1 + .../src/System.Reflection.Metadata.csproj | 1 - .../MemoryBlocks/ByteArrayMemoryProvider.cs | 3 +- .../Utilities/ImmutableByteArrayInterop.cs | 80 - .../System/Reflection/Metadata/BlobBuilder.cs | 2 +- .../Metadata/Ecma335/Encoding/BlobEncoders.cs | 80 +- .../Reflection/Metadata/IL/MethodBodyBlock.cs | 2 +- .../Reflection/Metadata/MetadataReader.cs | 5 +- .../Reflection/PortableExecutable/PEReader.cs | 3 +- .../Ecma335/Encoding/BlobEncodersTests.cs | 9 +- .../System.Reflection.Metadata.Tests.csproj | 10 +- .../tests/TestUtilities/PinnedBlob.cs | 3 +- .../tests/TestUtilities/SigningUtilities.cs | 21 +- .../ImmutableByteArrayInteropTest.cs | 66 - .../tests/System/Random.cs | 6 +- .../JavaScript/Interop/LegacyExports.cs | 28 +- .../JavaScript/JSHostImplementation.cs | 35 +- .../Legacy/LegacyHostImplementation.cs | 5 +- .../JavaScript/JSImportExportTest.cs | 5 +- .../Microsoft.Interop.SourceGeneration.csproj | 1 + .../SafeHandleMarshallingInfoProvider.cs | 40 +- .../TypeNames.cs | 2 + .../ref/System.Runtime.InteropServices.cs | 1 + .../SafeHandleTests.cs | 2 +- .../CompileFails.cs | 6 + .../Compiles.cs | 1 - .../CollectionsMarshalTests.cs | 50 + .../NativeExports/NativeExports.csproj | 2 +- .../ref/System.Runtime.Intrinsics.cs | 644 +- .../AddInstanceField_v1.cs | 1 + .../AddInstanceField_v2.cs | 91 + .../deltascript.json | 1 + .../tests/ApplyUpdateTest.cs | 11 +- .../tests/BinaryFormatterTestData.cs | 4 +- .../tests/DataContractSerializer.cs | 3 + .../ExporterApiTests.cs | 1 + .../System.Runtime/ref/System.Runtime.cs | 82 +- .../System.Runtime/tests/System/GCTests.cs | 3 + .../tests/System/Text/CompositeFormatTests.cs | 43 +- .../System.Runtime/tests/default.rd.xml | 6 + .../src/Resources/Strings.resx | 9 + .../System.Security.Cryptography.Cose.csproj | 18 +- .../DESCryptoServiceProvider.Unix.cs | 1 - .../Cryptography/DesImplementation.cs | 8 + .../X509Certificates/ChainPal.Android.cs | 7 +- .../X509Certificates/X500NameEncoder.cs | 4 +- .../tests/DESTests.cs | 9 + .../ref/System.Text.Encoding.Extensions.cs | 4 + .../tests/Ascii/EqualsTests.cs | 204 + .../tests/EncodingTestHelpers.cs | 12 + .../tests/NegativeEncodingTests.cs | 15 + .../tests/System.Text.Encoding.Tests.csproj | 1 + .../Common/JsonNumberHandling.cs | 2 +- .../Common/JsonObjectCreationHandling.cs | 27 + .../Common/JsonSeparatorNamingPolicy.cs | 5 + .../System.Text.Json/Common/ThrowHelper.cs | 16 + .../gen/JsonSourceGenerator.Emitter.cs | 34 +- .../gen/JsonSourceGenerator.Parser.cs | 19 + .../gen/PropertyGenerationSpec.cs | 5 + .../System.Text.Json.SourceGeneration.targets | 2 + .../gen/TypeGenerationSpec.cs | 3 + .../System.Text.Json/ref/System.Text.Json.cs | 18 +- .../ref/System.Text.Json.csproj | 7 +- .../src/Resources/Strings.resx | 29 +- .../src/System.Text.Json.csproj | 22 +- .../src/System/Text/Json/JsonConstants.cs | 1 - .../Text/Json/Reader/JsonReaderHelper.cs | 2 +- .../Text/Json/Reader/JsonReaderHelper.net8.cs | 2 +- .../JsonObjectCreationHandlingAttribute.cs | 51 + .../Collection/ConcurrentQueueOfTConverter.cs | 2 + .../Collection/ConcurrentStackOfTConverter.cs | 2 + .../DictionaryOfTKeyTValueConverter.cs | 2 + .../Collection/ICollectionOfTConverter.cs | 2 + .../Collection/IDictionaryConverter.cs | 2 + .../IDictionaryOfTKeyTValueConverter.cs | 2 + .../Converters/Collection/IListConverter.cs | 2 + .../Collection/IListOfTConverter.cs | 2 + .../Converters/Collection/ISetOfTConverter.cs | 2 + .../Collection/JsonCollectionConverter.cs | 9 +- .../Collection/JsonDictionaryConverter.cs | 9 +- .../Converters/Collection/ListOfTConverter.cs | 8 + .../Collection/QueueOfTConverter.cs | 7 + .../Collection/StackOfTConverter.cs | 7 + .../Collection/StackOrQueueConverter.cs | 7 + .../FSharp/FSharpOptionConverter.cs | 2 +- .../FSharp/FSharpValueOptionConverter.cs | 2 +- .../JsonMetadataServicesConverter.cs | 2 + .../Converters/Node/JsonObjectConverter.cs | 2 +- .../Converters/Object/JsonObjectConverter.cs | 1 + .../Object/ObjectDefaultConverter.cs | 101 +- ...ParameterizedConstructorConverter.Small.cs | 2 +- ...ctWithParameterizedConstructorConverter.cs | 28 +- .../Converters/Value/NullableConverter.cs | 10 +- .../Text/Json/Serialization/JsonConverter.cs | 5 + .../JsonConverterOfT.ReadCore.cs | 2 +- .../Json/Serialization/JsonConverterOfT.cs | 17 +- .../JsonResumableConverterOfT.cs | 2 +- .../Serialization/JsonSerializer.Helpers.cs | 3 + .../JsonSerializer.Read.Stream.cs | 73 +- .../JsonSerializerOptions.Caching.cs | 2 + .../Serialization/JsonSerializerOptions.cs | 29 + .../DefaultJsonTypeInfoResolver.Helpers.cs | 11 + .../Metadata/JsonPropertyInfo.cs | 124 +- .../Metadata/JsonPropertyInfoOfT.cs | 29 +- .../Serialization/Metadata/JsonTypeInfo.cs | 65 +- .../Metadata/JsonTypeInfoOfT.ReadHelper.cs | 97 +- .../Metadata/PolymorphicTypeResolver.cs | 22 +- .../Text/Json/Serialization/ReadStack.cs | 19 +- .../Text/Json/Serialization/ReadStackFrame.cs | 4 + .../Text/Json/Serialization/WriteStack.cs | 6 +- .../Text/Json/ThrowHelper.Serialization.cs | 38 +- .../src/System/Text/Json/ThrowHelper.cs | 13 +- .../Text/Json/Writer/JsonWriterHelper.cs | 19 +- .../Utf8JsonWriter.WriteProperties.Bytes.cs | 6 +- .../Utf8JsonWriter.WriteValues.Bytes.cs | 33 +- .../JsonCreationHandlingTests.Dictionary.cs | 1378 + .../JsonCreationHandlingTests.Enumerable.cs | 3204 +++ .../JsonCreationHandlingTests.Generic.cs | 641 + .../JsonCreationHandlingTests.Object.cs | 1168 + .../tests/Common/JsonSerializerWrapper.cs | 31 + .../tests/Common/JsonTestHelper.cs | 184 - .../tests/Common/NodeInteropTests.cs | 2 +- .../Common/SampleTestData.OrderPayload.cs | 187 +- .../JsonSerializerContextTests.cs | 2 +- .../MetadataAndSerializationContextTests.cs | 2 +- .../MetadataContextTests.cs | 4 +- .../MixedModeContextTests.cs | 2 +- .../RealWorldContextTests.cs | 8 +- .../JsonCreationHandlingTests.cs | 284 + .../SerializationContextTests.cs | 2 +- ...n.SourceGeneration.Roslyn3.11.Tests.csproj | 4 + ...on.SourceGeneration.Roslyn4.4.Tests.csproj | 2 +- ...m.Text.Json.SourceGeneration.Tests.targets | 50 +- .../TestClasses.CustomConverters.cs | 11 +- .../Serialization/CacheTests.cs | 1 + .../JsonCreationHandlingTests.cs | 25 + ...nTypeInfoResolverTests.JsonPropertyInfo.cs | 56 + ...tJsonTypeInfoResolverTests.JsonTypeInfo.cs | 40 +- .../Serialization/PropertyNameTests.cs | 30 + .../Stream.DeserializeAsyncEnumerable.cs | 28 +- .../Serialization/Stream.WriteTests.cs | 10 +- .../System.Text.Json.Tests.csproj | 13 +- .../Utf8JsonWriterTests.cs | 182 +- .../gen/RegexGenerator.Emitter.cs | 51 +- .../src/System.Text.RegularExpressions.csproj | 2 +- .../RegularExpressions/CompiledRegexRunner.cs | 6 +- .../CompiledRegexRunnerFactory.cs | 8 +- .../System/Text/RegularExpressions/Match.cs | 4 +- .../Text/RegularExpressions/Regex.Replace.cs | 38 +- .../Text/RegularExpressions/RegexCompiler.cs | 78 +- .../RegexFindOptimizations.cs | 29 +- .../RegularExpressions/RegexLWCGCompiler.cs | 2 +- .../Text/RegularExpressions/RegexParser.cs | 4 +- .../RegularExpressions/RegexPrefixAnalyzer.cs | 25 + .../RegularExpressions/RegexReplacement.cs | 107 +- .../src/System/Text/SegmentStringBuilder.cs | 98 - .../src/System/Text/StructListBuilder.cs | 72 + .../RegexGeneratorOutputTests.cs | 2 +- .../ref/System.Threading.Tasks.Parallel.cs | 5 + .../Threading/Tasks/Parallel.ForEachAsync.cs | 282 +- .../tests/ParallelForEachAsyncTests.cs | 373 + .../ref/System.Web.HttpUtility.cs | 4 + .../src/System.Web.HttpUtility.csproj | 1 + .../src/System/Web/HttpUtility.cs | 7 +- .../src/System/Web/IHtmlString.cs | 13 + .../tests/HttpUtility/HttpUtilityTest.cs | 14 + src/libraries/native-binplace.proj | 1 + src/libraries/oob-all.proj | 12 +- src/libraries/oob-src.proj | 13 +- src/libraries/oob.proj | 2 +- src/libraries/pretest.proj | 10 +- src/libraries/sendtohelix-wasm.targets | 14 + src/libraries/sfx.proj | 2 +- src/libraries/tests.proj | 4 - src/mono/CMakeLists.txt | 8 +- .../System.Private.CoreLib.csproj | 8 +- .../Emit/CustomAttributeBuilder.Mono.cs | 24 +- .../Emit/RuntimeAssemblyBuilder.Mono.cs | 10 +- .../Emit/RuntimeConstructorBuilder.Mono.cs | 23 +- .../Emit/RuntimeEnumBuilder.Mono.cs | 9 +- .../Emit/RuntimeEventBuilder.Mono.cs | 10 +- .../Emit/RuntimeFieldBuilder.Mono.cs | 19 +- .../RuntimeGenericTypeParameterBuilder.cs | 9 +- .../Emit/RuntimeMethodBuilder.Mono.cs | 20 +- .../Emit/RuntimeModuleBuilder.Mono.cs | 8 +- ...ono.cs => RuntimeParameterBuilder.Mono.cs} | 34 +- .../Emit/RuntimePropertyBuilder.Mono.cs | 11 +- .../Emit/RuntimeTypeBuilder.Mono.cs | 44 +- .../System/Reflection/MethodInvoker.Mono.cs | 2 +- ...AsyncWaitSemaphore.Browser.Threads.Mono.cs | 223 + .../LowLevelLifoSemaphore.Unix.Mono.cs | 6 +- ...PortableThreadPool.Browser.Threads.Mono.cs | 19 + ...dPool.WorkerThread.Browser.Threads.Mono.cs | 122 + .../src/System/Threading/Thread.Mono.cs | 13 + .../ThreadPool.Browser.Threads.Mono.cs | 13 + .../Threading/TimerQueue.Browser.Mono.cs | 6 +- ...WebWorkerEventLoop.Browser.Threads.Mono.cs | 4 +- src/mono/mono.proj | 22 +- src/mono/mono/arch/arm64/arm64-codegen.h | 55 +- src/mono/mono/component/debugger-agent.c | 405 +- src/mono/mono/component/debugger-engine.c | 10 +- src/mono/mono/component/debugger-engine.h | 4 +- src/mono/mono/component/debugger-protocol.h | 28 +- src/mono/mono/component/debugger.h | 1 + .../mono/component/hot_reload-internals.h | 2 + src/mono/mono/component/hot_reload.c | 166 +- src/mono/mono/metadata/appdomain.c | 4 + .../mono/metadata/assembly-load-context.c | 16 + src/mono/mono/metadata/class-accessors.c | 14 +- src/mono/mono/metadata/class-internals.h | 2 +- src/mono/mono/metadata/class.c | 2 +- src/mono/mono/metadata/coree.c | 2 +- src/mono/mono/metadata/icall-decl.h | 3 + src/mono/mono/metadata/icall-def.h | 10 + src/mono/mono/metadata/icall-signatures.h | 1 + src/mono/mono/metadata/icall.c | 2 +- src/mono/mono/metadata/jit-icall-reg.h | 1 + src/mono/mono/metadata/loader-internals.h | 5 +- src/mono/mono/metadata/loader.c | 38 +- src/mono/mono/metadata/marshal-lightweight.c | 21 +- src/mono/mono/metadata/marshal.c | 78 +- src/mono/mono/metadata/marshal.h | 6 +- src/mono/mono/metadata/metadata.c | 17 +- src/mono/mono/metadata/native-library.c | 20 +- src/mono/mono/metadata/object-internals.h | 5 +- src/mono/mono/metadata/profiler.c | 20 - src/mono/mono/metadata/threads-types.h | 4 + src/mono/mono/metadata/threads.c | 84 +- src/mono/mono/mini/CMakeLists.txt | 17 +- src/mono/mono/mini/aot-compiler.c | 83 +- src/mono/mono/mini/cpu-arm64.mdesc | 24 +- src/mono/mono/mini/interp/interp.c | 69 +- src/mono/mono/mini/interp/transform.c | 4 + src/mono/mono/mini/ir-emit.h | 7 + src/mono/mono/mini/llvm-intrinsics.h | 23 +- src/mono/mono/mini/method-to-ir.c | 12 +- src/mono/mono/mini/mini-arm64.c | 244 +- src/mono/mono/mini/mini-generic-sharing.c | 11 +- src/mono/mono/mini/mini-llvm.c | 42 +- src/mono/mono/mini/mini-ops.h | 1 + src/mono/mono/mini/mini-runtime.c | 4 +- src/mono/mono/mini/mini-windows.c | 4 +- src/mono/mono/mini/mini.c | 5 +- src/mono/mono/mini/simd-arm64.h | 4 + src/mono/mono/mini/simd-intrinsics.c | 306 +- src/mono/mono/mini/simd-methods.h | 5 + src/mono/mono/utils/lifo-semaphore.c | 259 +- src/mono/mono/utils/lifo-semaphore.h | 109 +- src/mono/mono/utils/mono-dl.c | 71 - src/mono/mono/utils/mono-dl.h | 2 - src/mono/mono/utils/mono-os-mutex.h | 2 +- src/mono/mono/utils/mono-threads-coop.c | 2 + src/mono/mono/utils/mono-threads-posix.c | 9 + src/mono/mono/utils/mono-threads-wasm.c | 14 + src/mono/mono/utils/mono-threads-windows.c | 9 + src/mono/mono/utils/mono-threads.h | 3 + src/mono/mono/utils/mono-time.c | 5 +- src/mono/mono/utils/options-def.h | 6 + ...icrosoft.NET.Sdk.WebAssembly.Browser.props | 2 +- ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 31 +- src/mono/sample/wasi/Directory.Build.targets | 11 +- .../wasi/console/Wasi.Console.Sample.csproj | 4 + src/mono/sample/wasm/Directory.Build.targets | 2 +- src/mono/sample/wasm/browser-bench/String.cs | 83 +- .../wasm/browser-threads-minimal/Program.cs | 92 +- ...Wasm.Browser.Threads.Minimal.Sample.csproj | 2 + .../wasm/browser-threads-minimal/blurst.txt | 1 + .../browser-threads-minimal/fetchhelper.js | 11 + .../wasm/browser-threads-minimal/main.js | 37 +- src/mono/sample/wasm/console-node/main.mjs | 2 +- src/mono/sample/wasm/console-v8/main.mjs | 2 +- src/mono/sample/wasm/wasm.mk | 2 +- .../Wasi.Build.Tests/Wasi.Build.Tests.csproj | 2 +- src/mono/wasi/build/WasiApp.Native.targets | 51 +- src/mono/wasi/build/WasiApp.props | 2 - src/mono/wasi/build/WasiApp.targets | 21 +- src/mono/wasi/runtime/CMakeLists.txt | 3 +- src/mono/wasi/runtime/driver.c | 84 +- src/mono/wasi/runtime/main.c | 36 +- src/mono/wasi/wasi.proj | 1 - .../Blazor/BuildPublishTests.cs | 9 +- src/mono/wasm/build/WasmApp.targets | 2 +- .../BrowserDebugProxy/MonoSDBHelper.cs | 4 +- .../DebuggerTestSuite.csproj | 4 + ...Tests2.cs => EvaluateOnCallFrame2Tests.cs} | 4 +- .../DebuggerTestSuite/SteppingTests.cs | 12 +- .../tests/debugger-test/debugger-main.js | 33 +- src/mono/wasm/runtime/CMakeLists.txt | 5 +- src/mono/wasm/runtime/assets.ts | 19 +- src/mono/wasm/runtime/blazor/BootConfig.ts | 4 +- .../blazor/WebAssemblyResourceLoader.ts | 2 +- .../runtime/blazor/WebAssemblyStartOptions.ts | 30 - src/mono/wasm/runtime/blazor/_Integration.ts | 6 +- src/mono/wasm/runtime/config.ts | 28 + src/mono/wasm/runtime/corebindings.c | 4 + src/mono/wasm/runtime/cwraps.ts | 2 +- src/mono/wasm/runtime/debug.ts | 2 +- .../runtime/diagnostics/browser/controller.ts | 2 +- .../diagnostics/server_pthread/index.ts | 2 +- .../diagnostics/server_pthread/mock-remote.ts | 2 +- .../server_pthread/socket-connection.ts | 2 +- src/mono/wasm/runtime/dotnet.d.ts | 136 +- .../wasm/runtime/es6/dotnet.es6.extpost.js | 14 +- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 135 +- src/mono/wasm/runtime/es6/dotnet.es6.post.js | 1 - src/mono/wasm/runtime/es6/dotnet.es6.pre.js | 21 +- src/mono/wasm/runtime/export-api.ts | 16 +- src/mono/wasm/runtime/export-types.ts | 15 +- src/mono/wasm/runtime/exports-internal.ts | 2 +- src/mono/wasm/runtime/exports-linker.ts | 4 +- src/mono/wasm/runtime/exports.ts | 107 +- src/mono/wasm/runtime/gc-handles.ts | 2 +- src/mono/wasm/runtime/gc-lock.ts | 2 +- src/mono/wasm/runtime/globals.ts | 70 + src/mono/wasm/runtime/http.ts | 7 +- .../{net6-legacy => }/hybrid-globalization.ts | 116 +- src/mono/wasm/runtime/icu.ts | 2 +- src/mono/wasm/runtime/imports.ts | 69 - src/mono/wasm/runtime/invoke-cs.ts | 2 +- src/mono/wasm/runtime/invoke-js.ts | 4 +- .../wasm/runtime/jiterpreter-interp-entry.ts | 96 +- src/mono/wasm/runtime/jiterpreter-jit-call.ts | 167 +- src/mono/wasm/runtime/jiterpreter-support.ts | 224 +- src/mono/wasm/runtime/jiterpreter.ts | 332 +- src/mono/wasm/runtime/logging.ts | 16 +- src/mono/wasm/runtime/managed-exports.ts | 2 +- src/mono/wasm/runtime/marshal-to-cs.ts | 2 +- src/mono/wasm/runtime/marshal-to-js.ts | 2 +- src/mono/wasm/runtime/marshal.ts | 2 +- src/mono/wasm/runtime/memory.ts | 6 +- src/mono/wasm/runtime/modularize-dotnet.md | 35 +- src/mono/wasm/runtime/net6-legacy/buffers.ts | 2 +- .../wasm/runtime/net6-legacy/corebindings.ts | 4 +- src/mono/wasm/runtime/net6-legacy/cs-to-js.ts | 2 +- .../wasm/runtime/net6-legacy/export-types.ts | 4 +- .../runtime/net6-legacy/exports-legacy.ts | 2 +- .../net6-legacy/{imports.ts => globals.ts} | 10 +- src/mono/wasm/runtime/net6-legacy/js-to-cs.ts | 4 +- .../runtime/net6-legacy/method-binding.ts | 16 +- .../wasm/runtime/net6-legacy/method-calls.ts | 2 +- src/mono/wasm/runtime/package-lock.json | 412 +- src/mono/wasm/runtime/package.json | 20 +- src/mono/wasm/runtime/polyfills.ts | 17 +- src/mono/wasm/runtime/profiler.ts | 2 +- .../wasm/runtime/pthreads/browser/index.ts | 5 +- .../pthreads/shared/emscripten-internals.ts | 2 +- .../shared/emscripten-replacements.ts | 2 +- .../wasm/runtime/pthreads/shared/index.ts | 4 +- .../wasm/runtime/pthreads/worker/index.ts | 11 +- src/mono/wasm/runtime/roots.ts | 2 +- src/mono/wasm/runtime/run-outer.ts | 158 +- src/mono/wasm/runtime/run.ts | 14 +- src/mono/wasm/runtime/snapshot.ts | 2 +- src/mono/wasm/runtime/startup.ts | 91 +- src/mono/wasm/runtime/strings.ts | 2 +- src/mono/wasm/runtime/types-api.ts | 245 + src/mono/wasm/runtime/types.ts | 226 +- src/mono/wasm/runtime/types/consts.d.ts | 4 +- src/mono/wasm/runtime/types/emscripten.ts | 14 - src/mono/wasm/runtime/web-socket.ts | 2 +- src/mono/wasm/test-main.js | 37 +- src/mono/wasm/wasm.proj | 1 - .../corehost/apphost/static/CMakeLists.txt | 4 + src/native/corehost/corehost.proj | 6 +- src/native/external/cgmanifest.json | 2 +- .../external/llvm-libunwind-version.txt | 11 +- .../external/llvm-libunwind/CMakeLists.txt | 112 +- .../cmake/Modules/HandleLibunwindFlags.cmake | 42 +- .../llvm-libunwind/cmake/config-ix.cmake | 21 +- .../llvm-libunwind/docs/BuildingLibunwind.rst | 12 - .../external/llvm-libunwind/docs/conf.py | 6 +- .../external/llvm-libunwind/docs/index.rst | 20 +- .../llvm-libunwind/include/CMakeLists.txt | 2 + .../include/__libunwind_config.h | 23 +- .../llvm-libunwind/include/libunwind.h | 125 +- .../include/libunwind.modulemap | 13 + .../include/mach-o/compact_unwind_encoding.h | 6 +- .../mach-o/compact_unwind_encoding.modulemap | 4 + .../external/llvm-libunwind/include/unwind.h | 8 +- .../llvm-libunwind/src/AddressSpace.hpp | 101 +- .../llvm-libunwind/src/CMakeLists.txt | 99 +- .../llvm-libunwind/src/CompactUnwinder.hpp | 1 + .../llvm-libunwind/src/DwarfInstructions.hpp | 71 +- .../llvm-libunwind/src/DwarfParser.hpp | 9 +- .../llvm-libunwind/src/EHHeaderParser.hpp | 3 +- .../external/llvm-libunwind/src/Registers.hpp | 625 +- .../llvm-libunwind/src/Unwind-EHABI.cpp | 11 +- .../llvm-libunwind/src/Unwind-seh.cpp | 12 +- .../external/llvm-libunwind/src/Unwind-sjlj.c | 6 +- .../llvm-libunwind/src/UnwindCursor.hpp | 811 +- .../llvm-libunwind/src/UnwindLevel1-gcc-ext.c | 40 +- .../llvm-libunwind/src/UnwindLevel1.c | 92 +- .../src/UnwindRegistersRestore.S | 376 +- .../llvm-libunwind/src/UnwindRegistersSave.S | 221 +- .../llvm-libunwind/src/Unwind_AIXExtras.cpp | 63 + .../external/llvm-libunwind/src/assembly.h | 49 +- .../external/llvm-libunwind/src/cet_unwind.h | 2 +- .../external/llvm-libunwind/src/config.h | 15 +- .../external/llvm-libunwind/src/libunwind.cpp | 23 + .../llvm-libunwind/src/libunwind_ext.h | 4 + .../llvm-libunwind/test/CMakeLists.txt | 20 +- .../test/bad_unwind_info.pass.cpp | 80 + .../apple-libunwind-backdeployment.cfg.in | 64 + .../test/configs/cmake-bridge.cfg.in | 36 + .../test/configs/ibm-libunwind-shared.cfg.in | 25 + .../test/configs/llvm-libunwind-merged.cfg.in | 42 + .../test/configs/llvm-libunwind-shared.cfg.in | 37 +- .../test/configs/llvm-libunwind-static.cfg.in | 38 +- .../llvm-libunwind/test/forceunwind.pass.cpp | 4 + .../test/frameheadercache_test.pass.cpp | 9 + .../llvm-libunwind/test/libunwind/__init__.py | 0 .../test/libunwind/test/__init__.py | 0 .../test/libunwind/test/config.py | 71 - .../llvm-libunwind/test/libunwind_01.pass.cpp | 45 +- .../llvm-libunwind/test/libunwind_02.pass.cpp | 13 + .../llvm-libunwind/test/lit.site.cfg.in | 58 - .../test/remember_state_leak.pass.sh.s | 12 + .../llvm-libunwind/test/signal_frame.pass.cpp | 8 +- .../test/signal_unwind.pass.cpp | 6 +- .../test/unw_getcontext.pass.cpp | 10 + .../llvm-libunwind/test/unw_resume.pass.cpp | 34 + .../test/unwind_leaffunction.pass.cpp | 9 +- .../test/unwind_scalable_vectors.pass.cpp | 50 + src/native/external/zlib-intel.cmake | 4 + src/native/external/zlib.cmake | 8 + src/native/libs/CMakeLists.txt | 2 +- src/native/libs/Common/pal_atomic.h | 4 +- .../CMakeLists.txt | 30 +- .../System.Globalization.Native/config.h.in | 3 +- .../configure.cmake | 3 +- .../pal_calendarData.c | 2 +- .../System.Globalization.Native/pal_icushim.c | 1 + .../pal_icushim_internal.h | 2 +- .../pal_icushim_static.c | 6 +- .../CMakeLists.txt | 1 + .../System.IO.Compression.Native/pal_zlib.c | 11 +- .../zlib_allocator_unix.c | 153 + .../zlib_allocator_win.c | 181 + src/native/libs/build-native.cmd | 11 + src/native/libs/build-native.proj | 23 + src/native/libs/build-native.sh | 18 +- .../AssetsComputingHelper.cs | 21 +- .../ComputeWasmBuildAssets.cs | 9 +- .../ComputeWasmPublishAssets.cs | 42 +- .../ConvertDllsToWebCil.cs | 100 + .../GenerateWasmBootJson.cs | 5 +- ...soft.NET.Sdk.WebAssembly.Pack.Tasks.csproj | 6 + .../WasmAppBuilder/EmitWasmBundleBase.cs | 2 +- .../WasmAppBuilder/wasi/WasiAppBuilder.cs | 2 +- .../CoreCLRTestLibrary/PlatformDetection.cs | 1 + .../GenerateHWIntrinsicTests_X86.cs | 1060 +- .../Common/XUnitLogChecker/XUnitLogChecker.cs | 67 +- .../XUnitWrapperGenerator.cs | 26 +- src/tests/Common/helixpublishwitharcade.proj | 54 +- src/tests/Common/ilasm/ilasm.ilproj | 2 +- src/tests/Common/publishdependency.targets | 2 +- .../test_dependencies.csproj | 2 +- .../test_dependencies.fsproj | 2 +- src/tests/Directory.Build.targets | 2 +- .../Interop/COM/ComWrappers/API/Program.cs | 125 +- .../ReferenceTrackerRuntime.cpp | 1 + .../physicalpromotion/mixedpromotion.cs | 65 + .../physicalpromotion/mixedpromotion.csproj | 10 + .../physicalpromotion/physicalpromotion.cs | 85 + .../physicalpromotion.csproj | 10 + .../X86/Shared/Avx512Verify.cs | 186 + .../X86/Shared/ImmTernOpTest.template | 325 + .../X86/Shared/SimpleTernOpTest_DataTable.cs | 77 + .../Sse2Verify.cs => Shared/SseVerify.cs} | 2 +- .../X86/Shared/_BinaryOpTestTemplate.template | 57 +- .../Shared/_TernaryOpTestTemplate.template | 65 +- .../X86/Shared/_UnaryOpTestTemplate.template | 67 +- ...ertToVector128Int32WithTruncation.Int32.cs | 375 - .../Avx512BW_VL_Vector128_r.csproj | 14 + .../Avx512BW_VL_Vector128_ro.csproj | 14 + .../Program.Avx512BW_VL_Vector128.cs | 16 + .../Avx512BW_VL_Vector256_r.csproj | 14 + .../Avx512BW_VL_Vector256_ro.csproj | 14 + .../Program.Avx512BW_VL_Vector256.cs | 16 + .../Avx512DQ_ScalarUpper_r.csproj | 14 + .../Avx512DQ_ScalarUpper_ro.csproj | 14 + .../Program.Avx512DQ_ScalarUpper.cs | 16 + .../Avx512F_ScalarUpper_r.csproj | 14 + .../Avx512F_ScalarUpper_ro.csproj | 14 + .../Program.Avx512F_ScalarUpper.cs | 16 + .../Avx512F_X64/Avx512F_X64_r.csproj | 14 + .../Avx512F_X64/Avx512F_X64_ro.csproj | 14 + .../Avx512F_X64/Program.Avx512F_X64.cs | 16 + .../X86_Avx512/Avx512Vbmi/Avx512Vbmi_r.csproj | 14 + .../Avx512Vbmi/Avx512Vbmi_ro.csproj | 14 + .../Avx512Vbmi/Program.Avx512Vbmi.cs | 16 + .../Avx512Vbmi_VL_Vector128_r.csproj | 14 + .../Avx512Vbmi_VL_Vector128_ro.csproj | 14 + .../Program.Avx512Vbmi_VL_Vector128.cs | 16 + .../Avx512Vbmi_VL_Vector256_r.csproj | 14 + .../Avx512Vbmi_VL_Vector256_ro.csproj | 14 + .../Program.Avx512Vbmi_VL_Vector256.cs | 16 + .../JIT/Methodical/delegate/GSDelegate.cs | 53 + .../JIT/Methodical/delegate/GSDelegate.csproj | 13 + .../Methodical/delegate/VirtualDelegate.cs | 24 + .../delegate/VirtualDelegate.csproj | 13 + .../JitBlue/GitHub_85129/GitHub_85129.cs | 47 + .../JitBlue/GitHub_85129/GitHub_85129.csproj | 9 + .../JitBlue/Runtime_74635/Runtime_74635.il | 30 - .../JitBlue/Runtime_74635/Runtime_74635_1.il | 72 + .../Runtime_74635/Runtime_74635_1.ilproj | 8 + .../JitBlue/Runtime_82535/Runtime_82535.cs | 131 + .../Runtime_82535/Runtime_82535.csproj | 10 + .../JitBlue/Runtime_84522/Runtime_84522.il | 52 + .../Runtime_84522/Runtime_84522.ilproj | 9 + .../JitBlue/Runtime_84693/Runtime_84693.cs | 2 +- .../JitBlue/Runtime_85088/Runtime_85088.cs | 50 + .../Runtime_85088/Runtime_85088.csproj | 9 + .../JitBlue/Runtime_85225/Runtime_85225.cs | 107 + .../Runtime_85225/Runtime_85225.csproj | 8 + .../JitBlue/Runtime_85226/Runtime_85226.cs | 36 + .../Runtime_85226/Runtime_85226.csproj | 8 + .../JitBlue/Runtime_85602/Runtime_85602.cs | 50 + .../Runtime_85602/Runtime_85602.csproj | 8 + .../JitBlue/Runtime_85630/Runtime_85630.cs | 181 + .../Runtime_85630/Runtime_85630.csproj | 8 + .../JitBlue/Runtime_85645/Runtime_85645.cs | 41 + .../Runtime_85645/Runtime_85645.csproj | 8 + .../DynBlkNullAssertions.cs | 2 +- .../CctorsWithSideEffects/CctorForWrite2.cs | 47 + .../CctorForWrite2.csproj | 9 + .../coreclr/GitHub_85240/test85240.cs | 33 + .../coreclr/GitHub_85240/test85240.csproj | 9 + src/tests/build.proj | 13 +- src/tests/build.sh | 1 - src/tests/issues.targets | 47 +- .../GenerateUnmanagedEntryPoints.csproj | 3 + .../SmokeTests/DwarfDump/DwarfDump.csproj | 1 + .../HardwareIntrinsics/X64Baseline.csproj | 1 - .../HardwareIntrinsics/x64NonVex.csproj | 1 - .../HardwareIntrinsics/x64Vex.csproj | 1 - .../Preinitialization/Preinitialization.cs | 18 +- .../SmokeTests/Reflection/Reflection.cs | 30 + .../SmokeTests/UnitTests/Generics.cs | 92 + src/tests/profiler/gc/nongcheap.cs | 55 + src/tests/profiler/gc/nongcheap.csproj | 21 + src/tests/profiler/multiple/multiple.csproj | 1 + src/tests/profiler/native/CMakeLists.txt | 1 + src/tests/profiler/native/classfactory.cpp | 5 + src/tests/profiler/native/guids.cpp | 1 + .../profiler/native/nongcheap/nongcheap.cpp | 179 + .../profiler/native/nongcheap/nongcheap.h | 27 + src/tests/profiler/native/profiler.cpp | 4 +- src/tests/profiler/native/profiler.h | 6 +- src/tests/run.py | 4 + .../eventactivityidcontrol.csproj | 3 + .../tracing/eventcounter/eventcounter.csproj | 2 +- src/tests/tracing/eventcounter/gh53564.csproj | 2 +- .../incrementingeventcounter.csproj | 2 +- .../incrementingpollingcounter.csproj | 2 +- .../eventcounter/pollingcounter.csproj | 2 +- .../eventcounter/regression-25709.csproj | 2 +- .../eventcounter/regression-46938.csproj | 2 +- .../eventcounter/runtimecounters.csproj | 2 +- .../EventListenerThreadPool.csproj | 3 + .../eventlistener/eventlistener.csproj | 3 + .../eventlistenerenabledisable.csproj | 3 + .../eventpipe/bigevent/bigevent.csproj | 5 +- .../eventpipe/buffersize/buffersize.csproj | 3 +- .../config/name_config_with_pid.csproj | 2 + .../diagnosticport/diagnosticport.csproj | 4 +- .../enabledisable/enabledisable.csproj | 3 +- .../eventsourceerror/eventsourceerror.csproj | 3 +- .../ExceptionThrown_V1.csproj | 6 +- .../eventsvalidation/GCEvents.csproj | 3 +- .../eventsvalidation/GCFinalizers.csproj | 3 +- .../tracing/eventpipe/gcdump/gcdump.csproj | 3 +- .../pauseonstart/pauseonstart.csproj | 4 +- .../processenvironment.csproj | 4 +- .../eventpipe/processinfo/processinfo.csproj | 2 + .../processinfo2/processinfo2.csproj | 2 + .../providervalidation.csproj | 3 +- .../tracing/eventpipe/reverse/reverse.csproj | 3 +- .../reverseouter/reverseouter.csproj | 4 +- .../rundownvalidation.csproj | 5 +- .../simpleprovidervalidation.csproj | 3 +- .../nativeruntimeeventsource.csproj | 2 + .../runtimeeventsource.csproj | 3 + .../Linker.Dataflow/MethodBodyScanner.cs | 10 +- .../ReflectionMethodBodyScanner.cs | 4 +- .../SkipKeptItemsValidationAttribute.cs | 2 + .../AnnotatedMembersAccessedViaReflection.cs | 77 +- .../DataFlow/ByRefDataflow.cs | 2 +- ...ompilerGeneratedCodeInPreservedAssembly.cs | 11 +- .../DataFlow/ComplexTypeHandling.cs | 27 +- .../DataFlow/ConstructedTypesDataFlow.cs | 1 - .../DataFlow/MakeGenericDataFlow.cs | 15 +- .../DataFlow/MemberTypes.cs | 64 +- .../DataFlow/MemberTypesAllOnCopyAssembly.cs | 5 +- .../DataFlow/MethodByRefParameterDataFlow.cs | 9 +- .../DataFlow/NullableAnnotations.cs | 4 +- .../DataFlow/PropertyDataFlow.cs | 49 +- .../DataFlow/RefFieldDataFlow.cs | 75 +- .../DataFlow/StaticInterfaceMethodDataflow.cs | 3 +- .../DataFlow/TypeInfoIntrinsics.cs | 1 - .../DynamicDependencyMethod.cs | 2 +- .../TypeHierarchyReflectionWarnings.cs | 12 +- ...flectionAccessFromCompilerGeneratedCode.cs | 63 +- .../RequiresAttributeMismatch.cs | 23 +- .../RequiresInCompilerGeneratedCode.cs | 23 - .../RequiresCapability/RequiresOnClass.cs | 33 +- .../RequiresOnVirtualsAndInterfaces.cs | 48 +- .../RequiresCapability/RequiresViaDataflow.cs | 4 +- ...uppressWarningsUsingTargetViaXmlNetCore.cs | 3 + src/workloads/workloads.csproj | 2 +- 1416 files changed, 65827 insertions(+), 28930 deletions(-) delete mode 100644 docs/pr-builds.md create mode 100644 docs/workflow/ci/analysis-check.png create mode 100644 docs/workflow/ci/failed-build.png create mode 100644 docs/workflow/ci/failed-test.png create mode 100644 docs/workflow/ci/failure-analysis.md create mode 100644 docs/workflow/ci/issue-impact.png create mode 100644 docs/workflow/ci/known-issue-example.png create mode 100644 docs/workflow/ci/pipelines-overview.md rename docs/{ => workflow/ci}/pr-guide.md (72%) create mode 100644 docs/workflow/ci/theory-azdo.png create mode 100644 eng/common/templates/steps/component-governance.yml create mode 100644 eng/pipelines/coreclr/templates/build-perf-bdn-app.yml rename src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/{ParameterBuilder.cs => RuntimeParameterBuilder.cs} (61%) create mode 100644 src/coreclr/jit/promotiondecomposition.cpp rename src/coreclr/jit/{unwindarm.cpp => unwindarmarch.cpp} (99%) delete mode 100644 src/coreclr/nativeaot/Runtime/amd64/GetThread.asm delete mode 100644 src/coreclr/nativeaot/Runtime/arm/GetThread.asm delete mode 100644 src/coreclr/nativeaot/Runtime/arm64/GetThread.asm delete mode 100644 src/coreclr/nativeaot/Runtime/i386/GetThread.asm delete mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs rename src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/{TrimAnalysisReflectionAccessPattern.cs => TrimAnalysisTokenAccessPattern.cs} (76%) create mode 100644 src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ByRefTypeMapNode.cs create mode 100644 src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVarianceNode.cs create mode 100644 src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/PointerTypeMapNode.cs delete mode 100644 src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/sdk/Sdk.props create mode 100644 src/libraries/Common/src/System/Net/Security/TargetHostNameHelper.cs create mode 100644 src/libraries/Common/src/System/Security/Cryptography/IncrementalHash.netfx.cs delete mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/gen/PopulationStrategy.cs rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/CollectionSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/ConfigurationSectionTypeSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/ConstructionStrategy.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/NullableSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/ObjectSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/ParsableFromStringTypeSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/PropertySpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/TypeSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{ => TypeGraph}/TypeSpecKind.cs (100%) delete mode 100644 src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/ImmutableArrayFactory.cs create mode 100644 src/libraries/System.Collections.Immutable/src/System/Runtime.InteropServices/ImmutableCollectionsMarshal.cs create mode 100644 src/libraries/System.Collections.Immutable/tests/ImmutableCollectionsMarshal.cs create mode 100644 src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Arm.cs create mode 100644 src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs create mode 100644 src/libraries/System.IO.Hashing/src/System/ThrowHelper.cs rename src/libraries/System.Memory/tests/Span/{IndexOfAnyValues.cs => SearchValues.cs} (83%) delete mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayHelpers.cs delete mode 100644 src/libraries/System.Net.Security/src/CompatibilitySuppressions.xml delete mode 100644 src/libraries/System.Net.Security/src/ReferenceAssemblyExclusions.txt create mode 100644 src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/BypassReadyToRunAttribute.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.PlatformNotSupported.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.cs rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny2ByteValues.cs => SearchValues/Any2ByteSearchValues.cs} (90%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny2CharValues.cs => SearchValues/Any2CharSearchValues.cs} (90%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny3ByteValues.cs => SearchValues/Any3ByteSearchValues.cs} (91%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny3CharValues.cs => SearchValues/Any3CharSearchValues.cs} (91%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny4Values.cs => SearchValues/Any4SearchValues.cs} (94%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny5Values.cs => SearchValues/Any5SearchValues.cs} (94%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyByteValues.cs => SearchValues/AnyByteSearchValues.cs} (96%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyAsciiByteValues.cs => SearchValues/AsciiByteSearchValues.cs} (96%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyAsciiCharValues.cs => SearchValues/AsciiCharSearchValues.cs} (95%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues => SearchValues}/BitVector256.cs (100%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfEmptyValues.cs => SearchValues/EmptySearchValues.cs} (91%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues => SearchValues}/IndexOfAnyAsciiSearcher.cs (99%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyLatin1CharValues.cs => SearchValues/Latin1CharSearchValues.cs} (94%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyCharValuesProbabilistic.cs => SearchValues/ProbabilisticCharSearchValues.cs} (78%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues => SearchValues}/ProbabilisticMap.cs (96%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyByteValuesInRange.cs => SearchValues/RangeByteSearchValues.cs} (91%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs => SearchValues/RangeCharSearchValues.cs} (92%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyValues.T.cs => SearchValues/SearchValues.T.cs} (78%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyValues.cs => SearchValues/SearchValues.cs} (69%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAnyValuesDebugView.cs => SearchValues/SearchValuesDebugView.cs} (62%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny1ByteValue.cs => SearchValues/SingleByteSearchValues.cs} (90%) rename src/libraries/System.Private.CoreLib/src/System/{IndexOfAnyValues/IndexOfAny1CharValue.cs => SearchValues/SingleCharSearchValues.cs} (90%) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Equality.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphoreBase.cs create mode 100644 src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/CustomAttributeWrapper.cs delete mode 100644 src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs create mode 100644 src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ParameterBuilderImpl.cs create mode 100644 src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/PseudoCustomAttributesData.cs create mode 100644 src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs rename src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/{AssemblySaveTestsWithVariousTypes.cs => AssemblySaveWithVariousMembersTests.cs} (56%) delete mode 100644 src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableByteArrayInterop.cs delete mode 100644 src/libraries/System.Reflection.Metadata/tests/Utilities/ImmutableByteArrayInteropTest.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs create mode 100644 src/libraries/System.Text.Encoding/tests/Ascii/EqualsTests.cs create mode 100644 src/libraries/System.Text.Json/Common/JsonObjectCreationHandling.cs create mode 100644 src/libraries/System.Text.Json/Common/ThrowHelper.cs create mode 100644 src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonObjectCreationHandlingAttribute.cs create mode 100644 src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Dictionary.cs create mode 100644 src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs create mode 100644 src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Generic.cs create mode 100644 src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Object.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonCreationHandlingTests.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs delete mode 100644 src/libraries/System.Text.RegularExpressions/src/System/Text/SegmentStringBuilder.cs create mode 100644 src/libraries/System.Text.RegularExpressions/src/System/Text/StructListBuilder.cs create mode 100644 src/libraries/System.Web.HttpUtility/src/System/Web/IHtmlString.cs rename src/mono/System.Private.CoreLib/src/System/Reflection/Emit/{ParameterBuilder.Mono.cs => RuntimeParameterBuilder.Mono.cs} (82%) create mode 100644 src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoAsyncWaitSemaphore.Browser.Threads.Mono.cs create mode 100644 src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.Mono.cs create mode 100644 src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.Browser.Threads.Mono.cs create mode 100644 src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.Mono.cs create mode 100644 src/mono/sample/wasm/browser-threads-minimal/blurst.txt create mode 100644 src/mono/sample/wasm/browser-threads-minimal/fetchhelper.js rename src/mono/wasm/debugger/DebuggerTestSuite/{EvaluateOnCallFrameTests2.cs => EvaluateOnCallFrame2Tests.cs} (99%) delete mode 100644 src/mono/wasm/runtime/blazor/WebAssemblyStartOptions.ts create mode 100644 src/mono/wasm/runtime/config.ts delete mode 100644 src/mono/wasm/runtime/es6/dotnet.es6.post.js create mode 100644 src/mono/wasm/runtime/globals.ts rename src/mono/wasm/runtime/{net6-legacy => }/hybrid-globalization.ts (63%) delete mode 100644 src/mono/wasm/runtime/imports.ts rename src/mono/wasm/runtime/net6-legacy/{imports.ts => globals.ts} (82%) create mode 100644 src/mono/wasm/runtime/types-api.ts create mode 100644 src/native/external/llvm-libunwind/include/libunwind.modulemap create mode 100644 src/native/external/llvm-libunwind/include/mach-o/compact_unwind_encoding.modulemap create mode 100644 src/native/external/llvm-libunwind/src/Unwind_AIXExtras.cpp create mode 100644 src/native/external/llvm-libunwind/test/bad_unwind_info.pass.cpp create mode 100644 src/native/external/llvm-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in create mode 100644 src/native/external/llvm-libunwind/test/configs/cmake-bridge.cfg.in create mode 100644 src/native/external/llvm-libunwind/test/configs/ibm-libunwind-shared.cfg.in create mode 100644 src/native/external/llvm-libunwind/test/configs/llvm-libunwind-merged.cfg.in delete mode 100644 src/native/external/llvm-libunwind/test/libunwind/__init__.py delete mode 100644 src/native/external/llvm-libunwind/test/libunwind/test/__init__.py delete mode 100644 src/native/external/llvm-libunwind/test/libunwind/test/config.py delete mode 100644 src/native/external/llvm-libunwind/test/lit.site.cfg.in create mode 100644 src/native/external/llvm-libunwind/test/unw_resume.pass.cpp create mode 100644 src/native/external/llvm-libunwind/test/unwind_scalable_vectors.pass.cpp create mode 100644 src/native/libs/System.IO.Compression.Native/zlib_allocator_unix.c create mode 100644 src/native/libs/System.IO.Compression.Native/zlib_allocator_win.c create mode 100644 src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs create mode 100644 src/tests/JIT/Directed/physicalpromotion/mixedpromotion.cs create mode 100644 src/tests/JIT/Directed/physicalpromotion/mixedpromotion.csproj create mode 100644 src/tests/JIT/Directed/physicalpromotion/physicalpromotion.cs create mode 100644 src/tests/JIT/Directed/physicalpromotion/physicalpromotion.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmTernOpTest.template create mode 100644 src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs rename src/tests/JIT/HardwareIntrinsics/X86/{Sse2/Sse2Verify.cs => Shared/SseVerify.cs} (98%) delete mode 100644 src/tests/JIT/HardwareIntrinsics/X86/Sse2/ConvertToVector128Int32WithTruncation.Int32.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Program.Avx512BW_VL_Vector128.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Program.Avx512BW_VL_Vector256.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Program.Avx512DQ_ScalarUpper.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Program.Avx512F_ScalarUpper.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Program.Avx512F_X64.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Program.Avx512Vbmi.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Program.Avx512Vbmi_VL_Vector128.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Program.Avx512Vbmi_VL_Vector256.cs create mode 100644 src/tests/JIT/Methodical/delegate/GSDelegate.cs create mode 100644 src/tests/JIT/Methodical/delegate/GSDelegate.csproj create mode 100644 src/tests/JIT/Methodical/delegate/VirtualDelegate.cs create mode 100644 src/tests/JIT/Methodical/delegate/VirtualDelegate.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.cs create mode 100644 src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.il create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.ilproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.il create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.ilproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.csproj create mode 100644 src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.cs create mode 100644 src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.csproj create mode 100644 src/tests/Regressions/coreclr/GitHub_85240/test85240.cs create mode 100644 src/tests/Regressions/coreclr/GitHub_85240/test85240.csproj create mode 100644 src/tests/profiler/gc/nongcheap.cs create mode 100644 src/tests/profiler/gc/nongcheap.csproj create mode 100644 src/tests/profiler/native/nongcheap/nongcheap.cpp create mode 100644 src/tests/profiler/native/nongcheap/nongcheap.h diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index a59a763744b62b..e8658e3172e405 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.23212.1", + "version": "8.0.0-prerelease.23253.1", "commands": [ "xharness" ] diff --git a/.github/ISSUE_TEMPLATE/04_ci_known_issue.yml b/.github/ISSUE_TEMPLATE/04_ci_known_issue.yml index 110ac830cc4fbe..17ec4e5e5ec930 100644 --- a/.github/ISSUE_TEMPLATE/04_ci_known_issue.yml +++ b/.github/ISSUE_TEMPLATE/04_ci_known_issue.yml @@ -10,7 +10,7 @@ body: id: background attributes: label: Error Blob - description: Please identify a clear error string that can help identify future instances of this issue. For more information on how to fill this check https://github.com/dotnet/arcade/blob/main/Documentation/Projects/Build%20Analysis/KnownIssues.md#filling-out-known-issues-json-blob + description: Please identify a clear error string that can help identify future instances of this issue. For more information on how to fill this check our issue triage guidelines at [Failure Analysis](/dotnet/runtime/blob/main/docs/workflow/ci/failure-analysis.md#what-to-do-if-you-determine-the-failure-is-unrelated) value: | ```json { diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8e440a1f6e23f..85827fa62b5186 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,7 +61,7 @@ The best way to create a minimal reproduction is gradually removing code and dep Project maintainers will merge changes that improve the product significantly. -The [Pull Request Guide](docs/pr-guide.md) and [Copyright](docs/project/copyright.md) docs define additional guidance. +The [Pull Request Guide](docs/workflow/pr-guide.md) and [Copyright](docs/project/copyright.md) docs define additional guidance. ### DOs and DON'Ts @@ -113,7 +113,7 @@ We use and recommend the following workflow: - Make sure that the tests are all passing, including your new tests. 7. Create a pull request (PR) against the dotnet/runtime repository's **main** branch. - State in the description what issue or improvement your change is addressing. - - Check if all the Continuous Integration checks are passing. + - Check if all the Continuous Integration checks are passing. Refer to [triaging failures in CI](docs/workflow/ci/failure-analysis.md) to check if any outstanding errors are known. 8. Wait for feedback or approval of your changes from the [area owners](docs/area-owners.md). - Details about the pull request [review procedure](docs/pr-guide.md). 9. When area owners have signed off, and all checks are green, your PR will be merged. @@ -165,9 +165,9 @@ The following file header is the used for files in this repo. Please use it for ### PR - CI Process -The [dotnet continuous integration](https://dev.azure.com/dnceng/public/) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean. +The [dotnet continuous integration](https://dev.azure.com/dnceng-public/public/_build) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change. -If the CI build fails for any reason, the PR issue will be updated with a link that can be used to determine the cause of the failure. +If the CI build fails for any reason, the PR issue will link to the `Azure DevOps` build with further information on the failure. ### PR Feedback diff --git a/Directory.Build.props b/Directory.Build.props index 0ba2a79969bf1b..cab8c8df24eb3e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -177,89 +177,89 @@ true - - + false true + - <_hostRid Condition="'$(MSBuildRuntimeType)' == 'core'">$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier) - <_hostRid Condition="'$(MSBuildRuntimeType)' != 'core'">win-$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant) + + + - <_parseDistroRid>$(__DistroRid) - <_parseDistroRid Condition="'$(_parseDistroRid)' == ''">$(_hostRid) - <_distroRidIndex>$(_parseDistroRid.LastIndexOf('-')) + <_portableOS>$(TargetOS.ToLowerInvariant()) + <_portableOS Condition="'$(_portableOS)' == 'windows'">win + + + <_portableOS Condition="'$(_portableOS)' == 'anyos'">$(__PortableTargetOS) + + + <_portableOS Condition="'$(_portableOS)' == 'linux' and '$(__PortableTargetOS)' == 'linux-musl'">linux-musl + <_portableOS Condition="'$(_portableOS)' == 'linux' and '$(__PortableTargetOS)' == 'linux-bionic'">linux-bionic + + + <_portableOS Condition="'$(HostOS)' == 'win' and '$(TargetsMobile)' != 'true'">win + + + + + <_packageOS>$(_portableOS) - <_runtimeOS>$(RuntimeOS) - <_runtimeOS Condition="'$(_runtimeOS)' == ''">$(_parseDistroRid.SubString(0, $(_distroRidIndex))) - - - <_runtimeOS Condition="'$(TargetsMobile)' == 'true'">$(TargetOS.ToLowerInvariant()) - - <_portableOS>linux - <_portableOS Condition="'$(_runtimeOS)' == 'linux-musl' or $(_runtimeOS.StartsWith('alpine'))">linux-musl - <_portableOS Condition="'$(_runtimeOS)' == 'linux-bionic'">linux-bionic - <_portableOS Condition="'$(_hostOS)' == 'osx'">osx - <_portableOS Condition="'$(_runtimeOS)' == 'win' or '$(TargetOS)' == 'windows'">win - <_portableOS Condition="'$(_runtimeOS)' == 'freebsd' or '$(TargetOS)' == 'freebsd'">freebsd - <_portableOS Condition="'$(_runtimeOS)' == 'illumos' or '$(TargetOS)' == 'illumos'">illumos - <_portableOS Condition="'$(_runtimeOS)' == 'solaris' or '$(TargetOS)' == 'solaris'">solaris - <_portableOS Condition="'$(_runtimeOS)' == 'browser'">browser - <_portableOS Condition="'$(_runtimeOS)' == 'wasi'">wasi - <_portableOS Condition="'$(_runtimeOS)' == 'maccatalyst'">maccatalyst - <_portableOS Condition="'$(_runtimeOS)' == 'ios'">ios - <_portableOS Condition="'$(_runtimeOS)' == 'iossimulator'">iossimulator - <_portableOS Condition="'$(_runtimeOS)' == 'tvos'">tvos - <_portableOS Condition="'$(_runtimeOS)' == 'tvossimulator'">tvossimulator - <_portableOS Condition="'$(_runtimeOS)' == 'android'">android - - <_runtimeOS Condition="$(_runtimeOS.StartsWith('tizen'))">linux - <_runtimeOS Condition="'$(PortableBuild)' == 'true'">$(_portableOS) - <_runtimeOS Condition="'$(RuntimeOS)' == '' and '$(DotNetBuildFromSource)' == 'true'">$(_portableOS) - - <_packageLibc Condition="$(_runtimeOS.Contains('musl'))">-musl - <_packageOS Condition="'$(CrossBuild)' == 'true'">$(_hostOS)$(_packageLibc) - <_packageOS Condition="'$(_packageOS)' == '' and '$(PortableBuild)' == 'true'">$(_portableOS) - <_packageOS Condition="'$(_packageOS)' == ''">$(_runtimeOS) + <_packageOS Condition="'$(CrossBuild)' == 'true' and '$(_portableOS)' != 'linux-musl' and '$(_portableOS)' != 'linux-bionic'">$(_hostOS) + + + $(PackageOS)-$(TargetArchitecture) + $(_packageOS)-$(TargetArchitecture) - - <_toolsRID Condition="'$(CrossBuild)' == 'true'">$(_hostOS)-$(_hostArch) - <_toolsRID Condition="'$(BuildingInsideVisualStudio)' == 'true'">$(_runtimeOS)-x64 - <_toolsRID Condition="'$(_toolsRID)' == ''">$(_runtimeOS)-$(_hostArch) + + + - <_toolsRID Condition="'$(_runtimeOS)' == 'browser' or '$(_runtimeOS)' == 'wasi'">linux-x64 - <_toolsRID Condition="('$(_runtimeOS)' == 'browser' or '$(_runtimeOS)' == 'wasi') and '$(HostOS)' == 'windows'">win-x64 - <_toolsRID Condition="('$(_runtimeOS)' == 'browser' or '$(_runtimeOS)' == 'wasi') and '$(HostOS)' == 'osx'">osx-x64 + To determine _portableHostOS we use _hostOS, similar to how _portableOS is calculated from TargetOS. - - <_toolsRID Condition="'$(_runtimeOS)' == 'android' or '$(_runtimeOS)' == 'linux-bionic'">linux-x64 - <_toolsRID Condition="('$(_runtimeOS)' == 'android' or '$(_runtimeOS)' == 'linux-bionic') and '$(HostOS)' == 'windows'">win-x64 - <_toolsRID Condition="('$(_runtimeOS)' == 'android' or '$(_runtimeOS)' == 'linux-bionic') and '$(HostOS)' == 'osx'">osx-x64 + When we're not cross-building we can detect linux flavors by looking at _portableOS + because the target platform and the build host platform are the same. + For cross-builds, we're currently unable to detect the flavors. --> + <_portableHostOS>$(_hostOS) + <_portableHostOS Condition="'$(_portableHostOS)' == 'windows'">win + <_portableHostOS Condition="'$(CrossBuild)' != 'true' and '$(_portableOS)' == 'linux-musl'">linux-musl - - <_toolsRID Condition="'$(_runtimeOS)' == 'maccatalyst' or '$(_runtimeOS)' == 'ios' or '$(_runtimeOS)' == 'iossimulator' or '$(_runtimeOS)' == 'tvos' or '$(_runtimeOS)' == 'tvossimulator'">osx-x64 + + $(ToolsOS)-$(_hostArch) + $(_portableHostOS)-$(_hostArch) - - linux-$(_hostArch) - $(_toolsRID) + $(ToolsRID) + - $(_packageOS)-$(TargetArchitecture) + + + <_hostRid Condition="'$(MSBuildRuntimeType)' == 'core'">$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier) + <_hostRid Condition="'$(MSBuildRuntimeType)' != 'core'">win-$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant) - $(_hostRid) - $(PackageRID) - $(_portableOS)-$(TargetArchitecture) - true - true + <_parseDistroRid>$(__DistroRid) + <_parseDistroRid Condition="'$(_parseDistroRid)' == ''">$(_hostRid) + <_distroRidIndex>$(_parseDistroRid.LastIndexOf('-')) + + <_outputOS>$(_parseDistroRid.SubString(0, $(_distroRidIndex))) + <_outputOS Condition="'$(PortableBuild)' == 'true'">$(_portableOS) + + $(_outputOS)-$(TargetArchitecture) - + true true true true + true + true true true true @@ -279,14 +279,14 @@ $([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRefPackDir)', 'ref', '$(NetCoreAppCurrent)')) $([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRefPackDir)', 'data')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'microsoft.netcore.app.runtime.$(OutputRid)', '$(LibrariesConfiguration)')) - $([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRuntimePackDir)', 'runtimes', '$(OutputRid)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'microsoft.netcore.app.runtime.$(OutputRID)', '$(LibrariesConfiguration)')) + $([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRuntimePackDir)', 'runtimes', '$(OutputRID)')) $([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRuntimePackRidDir)', 'lib', '$(NetCoreAppCurrent)')) $([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRuntimePackRidDir)', 'native')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(OutputRid).$(HostConfiguration)', 'corehost')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(OutputRID).$(HostConfiguration)', 'corehost')) diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index 06c74d4c2547b4..13c41e47495386 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -1226,3 +1226,46 @@ https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp MurmurHash3 was written by Austin Appleby, and is placed in the public domain. The author hereby disclaims copyright to this source + +License for Fast CRC Computation +-------------------------------------- + +https://github.com/intel/isa-l/blob/33a2d9484595c2d6516c920ce39a694c144ddf69/crc/crc32_ieee_by4.asm + +Copyright(c) 2011-2015 Intel Corporation All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +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 +OWNER 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 for C# Implementation of Fast CRC Computation +----------------------------------------------------- + +https://github.com/SixLabors/ImageSharp/blob/f4f689ce67ecbcc35cebddba5aacb603e6d1068a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs + +Copyright (c) Six Labors. +Licensed under the Apache License, Version 2.0. + +Available at +https://github.com/SixLabors/ImageSharp/blob/f4f689ce67ecbcc35cebddba5aacb603e6d1068a/LICENSE diff --git a/docs/area-owners.md b/docs/area-owners.md index 5ba554d1417408..6a2e4e3714e5af 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -65,7 +65,7 @@ Note: Editing this file doesn't update the mapping used by `@msftbot` for area-s | area-System.Buffers | @jeffhandley | @dotnet/area-system-buffers | | | area-System.CodeDom | @ericstj | @dotnet/area-system-codedom | | | area-System.Collections | @jeffhandley | @dotnet/area-system-collections | Excluded:
  • System.Array -> System.Runtime
| -| area-System.ComponentModel | @ericstj | @dotnet/area-system-componentmodel | | +| area-System.ComponentModel | @ericstj | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms | | area-System.ComponentModel.Composition | @ericstj | @dotnet/area-system-componentmodel-composition | | | area-System.ComponentModel.DataAnnotations | @jeffhandley | @dotnet/area-system-componentmodel-dataannotations | Included:
  • System.ComponentModel.Annotations
| | area-System.Composition | @ericstj | @dotnet/area-system-composition | | diff --git a/docs/coding-guidelines/project-guidelines.md b/docs/coding-guidelines/project-guidelines.md index 8bb511be52f906..0d76e3276cd62b 100644 --- a/docs/coding-guidelines/project-guidelines.md +++ b/docs/coding-guidelines/project-guidelines.md @@ -29,7 +29,6 @@ The following are the properties associated with each build pivot - `$(TargetOS) -> windows | linux | osx | freebsd | ... | [defaults to running OS when empty]` - `$(Configuration) -> Debug | Release | [defaults to Debug when empty]` - `$(TargetArchitecture) - x86 | x64 | arm | arm64 | [defaults to x64 when empty]` -- `$(RuntimeOS) - win7 | osx10.10 | ubuntu.14.04 | [any other RID OS+version] | [defaults to running OS when empty]` See [RIDs](https://github.com/dotnet/runtime/tree/main/src/libraries/Microsoft.NETCore.Platforms) for more info. ## Aggregate build properties Each project will define a set of supported TargetFrameworks @@ -63,8 +62,6 @@ A full or individual project build is centered around BuildTargetFramework, Targ 2. If nothing is passed to the build then we will default value of these properties from the environment. Example: `net8.0-[TargetOS Running On]-Debug-x64`. 3. When building an individual project (either from the CLI or an IDE), all target frameworks are built. -We also have `RuntimeOS` which can be passed to customize the specific OS and version needed for native package builds as well as package restoration. If not passed it will default based on the OS you are running on. - Any of the mentioned properties can be set via `/p:=` at the command line. When building using any of the wrapper scripts around it (i.e. build.cmd) a number of these properties have aliases which make them easier to pass (run build.cmd/sh -? for the aliases). ## Selecting the correct BuildSettings diff --git a/docs/design/coreclr/botr/clr-abi.md b/docs/design/coreclr/botr/clr-abi.md index 14801dd8b6b897..1e5730f54d334d 100644 --- a/docs/design/coreclr/botr/clr-abi.md +++ b/docs/design/coreclr/botr/clr-abi.md @@ -696,7 +696,7 @@ The extra state created by the JIT for synchronized methods (lock taken flag) mu ## Generics -EnC is not supported for generic methods and methods on generic types. +EnC is supported for adding and editing generic methods and methods on generic types and generic methods on non-generic types. # System V x86_64 support diff --git a/docs/design/coreclr/botr/method-descriptor.md b/docs/design/coreclr/botr/method-descriptor.md index 35fa91c85263c9..496ecc792af6f3 100644 --- a/docs/design/coreclr/botr/method-descriptor.md +++ b/docs/design/coreclr/botr/method-descriptor.md @@ -206,10 +206,10 @@ For example, it may be a bad idea to use the temporary entry point to call the m The methods to get callable entry points from MethodDesc are: -- MethodDesc::GetSingleCallableAddrOfCode -- MethodDesc::GetMultiCallableAddrOfCode -- MethodDesc::GetSingleCallableAddrOfVirtualizedCode -- MethodDesc::GetMultiCallableAddrOfVirtualizedCode +- `MethodDesc::GetSingleCallableAddrOfCode` +- `MethodDesc::GetMultiCallableAddrOfCode` +- `MethodDesc::GetSingleCallableAddrOfVirtualizedCode` +- `MethodDesc::GetMultiCallableAddrOfVirtualizedCode` Types of precode ---------------- diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index fa6bb18b114c9d..2c63997332e487 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -798,6 +798,8 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, + READYTORUN_HELPER_NewMaybeFrozenArray = 0x6A, + READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/docs/design/coreclr/botr/shared-generics.md b/docs/design/coreclr/botr/shared-generics.md index 14ecfa1aa70cac..153ab429725d66 100644 --- a/docs/design/coreclr/botr/shared-generics.md +++ b/docs/design/coreclr/botr/shared-generics.md @@ -25,7 +25,7 @@ Without shared generics, the code for instantiations like `Method` or `M ret ``` -With shared generics, the canonical code will not have any hard-coded versions of the type handle of List, but instead looks up the exact type handle either through a call to a runtime helper API, or by loading it up from the *generic dictionary* of the instantiation of Method that is executing. The code would look more like the following: +With shared generics, the canonical code will not have any hard-coded versions of the type handle of `List`, but instead looks up the exact type handle either through a call to a runtime helper API, or by loading it up from the *generic dictionary* of the instantiation of `Method` that is executing. The code would look more like the following: ``` asm mov rcx, generic context // MethodDesc of Method or Method mov rcx, [rcx + offset of InstantiatedMethodDesc::m_pPerInstInfo] // This is the generic dictionary @@ -34,9 +34,9 @@ With shared generics, the canonical code will not have any hard-coded versions o ret ``` -The generic context in this example is the InstantiatedMethodDesc of `Method` or `Method`. The generic dictionary is a data structure used by shared generic code to fetch instantiation-specific information. It is basically an array where the entries are instantiation-specific type handles, method handles, field handles, method entry points, etc... The "PerInstInfo" fields on MethodTable and InstantiatedMethodDesc structures point at the generic dictionary structure for a generic type and method respectively. +The generic context in this example is the `InstantiatedMethodDesc` of `Method` or `Method`. The generic dictionary is a data structure used by shared generic code to fetch instantiation-specific information. It is basically an array where the entries are instantiation-specific type handles, method handles, field handles, method entry points, etc... The "PerInstInfo" fields on MethodTable and `InstantiatedMethodDesc` structures point at the generic dictionary structure for a generic type and method respectively. -In this example, the generic dictionary for Method will contain a slot with the type handle for type List, and the generic dictionary for Method will contain a slot with the type handle for type List. +In this example, the generic dictionary for `Method` will contain a slot with the type handle for type `List`, and the generic dictionary for `Method` will contain a slot with the type handle for type `List`. This feature is currently only supported for instantiations over reference types because they all have the same size/properties/layout/etc... For instantiations over primitive types or value types, the runtime will generate separate code bodies for each instantiation. @@ -89,7 +89,7 @@ Note that `AnotherDerivedClass` doesn't have a dictionary of its own given that ### Dictionary Slots -As described earlier, a generic dictionary is an array of multiple slots containing instantiation-specific information. When a dictionary is initially allocated for a certain generic type or method, all of its slots are initialized to NULL, and are lazily populated on demand as code executes (see: `Dictionary::PopulateEntry(...)`). +As described earlier, a generic dictionary is an array of multiple slots containing instantiation-specific information. When a dictionary is initially allocated for a certain generic type or method, all of its slots are initialized to `NULL`, and are lazily populated on demand as code executes (see: `Dictionary::PopulateEntry(...)`). The first N slots in an instantiation of N arguments are always going to be the type handles of the instantiation type arguments (this is kind of an optimization as well). The slots that follow contain instantiation-based information. @@ -97,17 +97,17 @@ For instance, here is an example of the contents of the generic dictionary for o | `Method's dictionary` | |--------------------------| -| slot[0]: TypeHandle(`string`) | -| slot[1]: Total dictionary size | -| slot[2]: TypeHandle(`List`) | -| slot[3]: NULL (not used) | -| slot[4]: NULL (not used) | +| `slot[0]: TypeHandle(string)` | +| `slot[1]: Total dictionary size` | +| `slot[2]: TypeHandle(List)` | +| `slot[3]: NULL (not used)` | +| `slot[4]: NULL (not used)` | *Note: the size slot is never used by generic code, and is part of the dynamic dictionary expansion feature. More on that below.* -When this dictionary is first allocated, only slot[0] is initialized because it contains the instantiation type arguments (and of course the size slot is also initialized with the dictionary expansion feature), but the rest of the slots (example slot[2]) are NULL, and get lazily populated with values if we ever hit a code path that attempts to use them. +When this dictionary is first allocated, only `slot[0]` is initialized because it contains the instantiation type arguments (and of course the size slot is also initialized with the dictionary expansion feature), but the rest of the slots (for example, `slot[2]`) are `NULL`, and get lazily populated with values if we ever hit a code path that attempts to use them. -When loading information from a slot that is still NULL, the generic code will call one of these runtime helper functions to populate the dictionary slot with a value: +When loading information from a slot that is still `NULL`, the generic code will call one of these runtime helper functions to populate the dictionary slot with a value: - `JIT_GenericHandleClass`: Used to lookup a value in a generic type dictionary. This helper is used by all instance methods on generic types. - `JIT_GenericHandleMethod`: Used to lookup a value in a generic method dictionary. This helper used by all generic methods, or non-generic static methods on generic types. @@ -117,9 +117,9 @@ When generating shared generic code, the JIT knows which slots to use for the va The `DictionaryLayout` structure is what tells the JIT which slot to use when performing a dictionary lookup. This `DictionaryLayout` structure has a couple of important properties: - It is shared across all compatible instantiations of a certain type of method. In other words, a dictionary layout is associated with the canonical instantiation of a type or a method. For instance, in our example above, `Method` and `Method` are compatible instantiations, each with their own **separate dictionaries**, however they all share the **same dictionary layout**, which is associated with the canonical instantiation `Method<__Canon>`. -- The dictionaries of generic types or methods have the same number of slots as their dictionary layouts. Note: historically before the introduction of the dynamic dictionary expansion feature, the generic dictionaries could be smaller than their layouts, meaning that for certain lookups, we had to use invoke some runtime helper APIs (slow path). +- The dictionaries of generic types or methods have the same number of slots as their dictionary layouts. Note: historically before the introduction of the dynamic dictionary expansion feature, the generic dictionaries could be smaller than their layouts, meaning that for certain lookups, we had to invoke some runtime helper APIs (slow path). -When a generic type or method is first created, its dictionary layout contains 'unassigned' slots. Assignments happen as part of code generation, whenever the JIT needs to emit a dictionary lookup sequence. This assignment happens during the calls to the `DictionaryLayout::FindToken(...)` APIs. Once a slot has been assigned, it becomes associated with a certain signature, which describes the kind of value that will go in every instantiated dictionary at that slot index. +When a generic type or method is first created, its dictionary layout contains 'unassigned' slots. Assignments happen as part of code generation, whenever the JIT needs to emit a dictionary lookup sequence. This assignment happens during calls to the `DictionaryLayout::FindToken(...)` APIs. Once a slot has been assigned, it becomes associated with a certain signature, which describes the kind of value that will go in every instantiated dictionary at that slot index. Given an input signature, slot assignment is performed with the following algorithm: diff --git a/docs/design/coreclr/botr/type-loader.md b/docs/design/coreclr/botr/type-loader.md index b2d5d6032bb4ca..e8ccf1181d60bb 100644 --- a/docs/design/coreclr/botr/type-loader.md +++ b/docs/design/coreclr/botr/type-loader.md @@ -306,14 +306,14 @@ type, they have the typical instantiation in mind. Example: public class A {} ``` -The C# `typeof(A<,,>)` compiles to ldtoken A\'3 which makes the +The C# `typeof(A<,,>)` compiles to ``ldtoken A`3`` which makes the runtime load ``A`3`` instantiated at `S` , `T` , `U`. **Canonical Instantiation** An instantiation where all generic arguments are `System.__Canon`. `System.__Canon` is an internal type defined -in **mscorlib** and its task is just to be well-known and different +in **corlib** and its task is just to be well-known and different from any other type which may be used as a generic argument. Types/methods with canonical instantiation are used as representatives of all instantiations and carry information shared by @@ -343,8 +343,7 @@ of all these types is the same. The figure illustrates this for `List` and `List`. The canonical `MethodTable` was created automatically before the first reference type instantiation was loaded and contains data which is hot but not -instantiation specific like non-virtual slots or -`RemotableMethodInfo`. Instantiations containing only value types +instantiation specific like non-virtual slots. Instantiations containing only value types are not shared and every such instantiated type gets its own unshared `EEClass`. diff --git a/docs/design/features/hybrid-globalization.md b/docs/design/features/hybrid-globalization.md index b7e74af942007e..629d68ef3cc84c 100644 --- a/docs/design/features/hybrid-globalization.md +++ b/docs/design/features/hybrid-globalization.md @@ -181,3 +181,20 @@ hiraganaBig.localeCompare(katakanaSmall, "en-US", { sensitivity: "base" }) // 0; `IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace` `IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace | IgnoreCase` + + +**String starts with / ends with** + +Affected public APIs: +- CompareInfo.IsPrefix +- CompareInfo.IsSuffix +- String.StartsWith +- String.EndsWith + +Web API does not expose locale-sensitive endsWith/startsWith function. As a workaround, both strings get normalized and weightless characters are removed. Resulting strings are cut to the same length and comparison is performed. This approach, beyond having the same compare option limitations as described under **String comparison**, has additional limitations connected with the workaround used. Because we are normalizing strings to be able to cut them, we cannot calculate the match length on the original strings. Methods that calculate this information throw PlatformNotSupported exception: + +- [CompareInfo.IsPrefix](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareinfo.isprefix?view=net-8.0#system-globalization-compareinfo-isprefix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@)) +- [CompareInfo.IsSuffix](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareinfo.issuffix?view=net-8.0#system-globalization-compareinfo-issuffix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@)) + +- `IgnoreSymbols` +Only comparisons that do not skip character types are allowed. E.g. `IgnoreSymbols` skips symbol-chars in comparison/indexing. All `CompareOptions` combinations that include `IgnoreSymbols` throw `PlatformNotSupportedException`. diff --git a/docs/design/libraries/LibraryImportGenerator/Compatibility.md b/docs/design/libraries/LibraryImportGenerator/Compatibility.md index 27cf3fa45e0fd3..cd2e31f429cd07 100644 --- a/docs/design/libraries/LibraryImportGenerator/Compatibility.md +++ b/docs/design/libraries/LibraryImportGenerator/Compatibility.md @@ -2,7 +2,13 @@ Documentation on compatibility guidance and the current state. The version headings act as a rolling delta between the previous version. -## Version 2 +## Version 3 (.NET 8) + +### Safe Handles + +Due to trimming issues with NativeAOT's implementation of `Activator.CreateInstance`, we have decided to change our recommendation of providing a public parameterless constructor for `ref`, `out`, and return scenarios to a requirement. We already required a parameterless constructor of some visibility, so changing to a requirement matches our design principles of taking breaking changes to make interop more understandable and enforce more of our best practices instead of going out of our way to provide backward compatibility at increasing costs. + +## Version 2 (.NET 7 Release) The focus of version 2 is to support all repos that make up the .NET Product, including ASP.NET Core and Windows Forms, as well as all packages in dotnet/runtime. @@ -11,7 +17,7 @@ The focus of version 2 is to support all repos that make up the .NET Product, in Support for user-defined type marshalling in the source-generated marshalling is described in [UserTypeMarshallingV2.md](UserTypeMarshallingV2.md). This support replaces the designs specified in [StructMarshalling.md](StructMarshalling.md) and [SpanMarshallers.md](SpanMarshallers.md). -## Version 1 +## Version 1 (.NET 6 Prototype and .NET 7 Previews) The focus of version 1 is to support `NetCoreApp`. This implies that anything not needed by `NetCoreApp` is subject to change. diff --git a/docs/design/specs/Ecma-335-Augments.md b/docs/design/specs/Ecma-335-Augments.md index 8847ab7285d8ae..e3ad8ad854a89f 100644 --- a/docs/design/specs/Ecma-335-Augments.md +++ b/docs/design/specs/Ecma-335-Augments.md @@ -12,6 +12,7 @@ This is a list of additions and edits to be made in ECMA-335 specifications. It - [Default Interface Methods](#default-interface-methods) - [Static Interface Methods](#static-interface-methods) - [Covariant Return Types](#covariant-return-types) +- [Function Pointer Type Identity](#function-pointer-type-identity) - [Unsigned data conversion with overflow detection](#unsigned-data-conversion-with-overflow-detection) - [Ref field support](#ref-fields) - [Rules for IL rewriters](#rules-for-il-rewriters) @@ -925,6 +926,16 @@ For this example, the behavior of calls on objects of various types is presented ### II.22.27 Edit rule 12 to specify that "The method signature defined by *MethodBody* shall match those defined by *MethodDeclaration* exactly if *MethodDeclaration* defines a method on an interface or be *covariant-return-compatible-with* (§I.8.7.1) if *MethodDeclaration* represents a method on a class." +## Function Pointer Type Identity + +The unmanaged calling convention of the function pointer type no longer contributes to the type identity. For the purposes of type identity, the only important bit is whether the calling convention is managed or unmanaged. + +### I.8.7 Assignment compatibility + +For the purpose of type compatibility when determining a type from a signature: + +iv) ~~Any calling convention~~ _Whether the calling convention is managed or unmanaged_ is considered part of the type. + ## Unsigned data conversion with overflow detection `conv.ovf..un` opcode is purposed for converting a value on the stack to an integral value while treating the stack source as unsigned. Ecma does not distinguish signed and unsigned values on the stack so such opcode is needed as a complement for `conv.ovf.`. diff --git a/docs/pr-builds.md b/docs/pr-builds.md deleted file mode 100644 index e7d6e5968b0f65..00000000000000 --- a/docs/pr-builds.md +++ /dev/null @@ -1,98 +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 "Evaluate 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 ILLink 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`. - -## Analyzing Failures - -The PR Build Analysis tab has summary of all failures, including matches with the list of known issues. This tab should be your first stop for analyzing the PR failures. - -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, amend 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: - -* If the failure is identified as a known issue in the Build Analysis tab, no further action is required. -* 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 possible, please [update the failure signature](https://github.com/dotnet/arcade/blob/main/Documentation/Projects/Build%20Analysis/KnownIssues.md#how-to-fill-out-a-known-issue-error-message-section) to have it automatically identified by the Build Analysis as known issue next time. - * 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. -* If the failure is occuring frequently, please disable the failing test(s) with the corresponding issue link tracking the disable in a follow-up Pull Request - * 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. diff --git a/docs/workflow/README.md b/docs/workflow/README.md index 7f5d80edc41f58..dbef0e3e7a533e 100644 --- a/docs/workflow/README.md +++ b/docs/workflow/README.md @@ -1,10 +1,13 @@ # Workflow Guide -* [Build Requirements](#build-requirements) -* [Getting Yourself Started](#getting-yourself-started) -* [Configurations and Subsets](#configurations-and-subsets) - * [What does this mean for me?](#what-does-this-mean-for-me) -* [Full Instructions on Building and Testing the Runtime Repo](#full-instructions-on-building-and-testing-the-runtime-repo) +- [Build Requirements](#build-requirements) +- [Getting Yourself Started](#getting-yourself-started) +- [Configurations and Subsets](#configurations-and-subsets) + - [What does this mean for me?](#what-does-this-mean-for-me) +- [Full Instructions on Building and Testing the Runtime Repo](#full-instructions-on-building-and-testing-the-runtime-repo) +- [Warnings as Errors](#warnings-as-errors) +- [Submitting a PR](#submitting-a-pr) +- [Triaging errors in CI](#triaging-errors-in-ci) The repo can be built for the following platforms, using the provided setup and the following instructions. Before attempting to clone or build, please check the requirements that match your machine, and ensure you install and prepare all as necessary. @@ -91,3 +94,11 @@ And how to measure performance: ## Warnings as Errors The repo build treats warnings as errors. Dealing with warnings when you're in the middle of making changes can be annoying (e.g. unused variable that you plan to use later). To disable treating warnings as errors, set the `TreatWarningsAsErrors` environment variable to `false` before building. This variable will be respected by both the `build.sh`/`build.cmd` root build scripts and builds done with `dotnet build` or Visual Studio. Some people may prefer setting this environment variable globally in their machine settings. + +## Submitting a PR + +Before submitting a PR, make sure to review the [contribution guidelines](../../CONTRIBUTING.md). After you get familiarized with them, please read the [PR guide](ci/pr-guide.md) to find more information about tips and conventions around creating a PR, getting it reviewed, and understanding the CI results. + +## Triaging errors in CI + +Given the size of the runtime repository, flaky tests are expected to some degree. There are a few mechanisms we use to help with the discoverability of widely impacting issues. We also have a regular procedure that ensures issues get properly tracked and prioritized. You can find more information on [triaging failures in CI](ci/failure-analysis.md). diff --git a/docs/workflow/ci/analysis-check.png b/docs/workflow/ci/analysis-check.png new file mode 100644 index 0000000000000000000000000000000000000000..4b24e83c5ba58d256806e24cdd054d8fd692fc54 GIT binary patch literal 3619 zcmcha=Q|sY*T$oinh|NWh!vyN60zD)1c~)EYLD6!t=(1?v1;#8t(K}08i|!syGHG* z^;L;IYF1OksMz&*{)FebuHWy)`JC&1bFTZ%xzBYHj10BeS$J6h006tL4%!3&pgS*s z>m|l>3eI{Oo;SLuCfXW+$|1Kn23r)b;gErVlXit&&fOkW$DUl6A_CUdPPOzsVS7Lumb)EZ3^H8fBoc zp;d&bge>tada%9vii8e4Uu!HQiBiCd>w9}fxuCDd%bLHGjR>~pAJ2*=JxhYCoG{7) zbB%iMe^p^L<(BRt(Y;1&dF$?m-9wXZIGjbm>@zH03;i5rTR)L!(j?PelNY-P1e!iI z*k+H-Pva4%+Edh~;VCKV`K7XEX4#-Cf@P_5&|n6kufyQE*1RMaaB7GkGa0-{>{{;L!FE6PExJ!Of2j^VUzF4%{mOT+x&Z0t%zf!v^)%7xg zJv=)}%u~+EI4)ji{!BZKgkrGrM;0`31~GZXajkxEAvd{a{5yENPAcV&Be_|0+6YGO z4xB8iEE=kqe=rd0)Y1^w;5K;c?Um7FUf2V+%}XD#Yg?+zf>K&3?hMY_Ws1UoMqV$5 z5gmg=WKBl9Lc3c=?R7NE^Oe*Y9(RC;T_$;_XG+H%I#1%9f8gBson=t=Z6Vx8c#)kc ziGH%oerr5tk*I^Qn|0qanGqBn2DL@iI+uqr`Otyko{hn2JGGMfv5$E{wK|`fewhwS zc10KKdicvJ)-T7rA>(60oV^zsf@L;Ynv;-^Ni+R~TyS-Qv%d>=)E7&)Hs}vnpGEGM=BYaSh`CdiGOkjq1lU6UZ0~P&!b1x8i3s|yS=iC{0c%W|Z znL8ehps$sK-Iq^!&U5C!RqTckjJqJXffmy6DR4t`Z-^)Hb zHMdCY#;K3sZEEHQi(DkS%Fbb7Q`t-i@H|=IVKR!!64!S>K3B!HXQGnwj{vRQE@1qVOXW1)t;M9fxq0t|!XHWS=&?|}+CetFbiTmRZ3XCiw zo>P!NnAx+OLaw+QB4SKdfKVS^86^(mY6|PSWO)}tv%qLvQ$PK+AmY;o%Y~_nm`Taa zwUael$v&5trZVA&o>o;Rl8u5*gv-wmnJ;WXsbLu|T|25QRT*xiT!eFU;4k-gDFPcC zOQs*a_JSpYprAR5Y#i5m$aAJdNxDV)wV>iYTKC$VM{4|iEGoEoual&Ru5aE?RVwo) zU!z+|$fJo>d}ga%RkVS9Ll<%R+b)ewf6ll*yBVLt4Awi4UFN$|9oml~yxjo5pLk%S zmiV?2AjfsIFx5JEFrD+-idI#w!w1b;cDRhylB8<)BysK&G{ORKQtK7H>9v2YC9P|? z1Xs-4rImO-_0HQ8#xEz`^bfk3)qFy?BjtuxQRZVF3@SvMX~!`TmLWKAZft#Hr!-y~ zs&(C^CsGvMU}OBppi;)%U&|u1Jw7x<7JAg{^sSlM<8Y=XXC@>Ud=~rHM+TRc3fj+) zD#_#}aLj^13RclRk70E@=hmmAi4VAAyM%=CG=gQ+NsCHKcm>(qnKOpRh3_z1!yt9N zlTpZL2mVL0zq3`OZmFwx26 zHR%(;J@L%^hjf=wE(_M3n+@g!Tg710#+^*-ycO+_CXpHDwiic#hz?}uC#M%RR<=E) zCa!>+cLQKU*2mBQHx@VKkCdppyS(ceIX&}I8W6;rd{e5Yro}QuH6b4qfj^*go(X&# zc1UeOSW4VP8E3}lzh<73~)xAUtYnZvovqFwci6X;>V$-JQl`5Q3XNibRJk%O1c1n&EzNi8OMlae<{gY>45^` zQWol#k$3XS6AM_?XC9F#+kjzPTx1<#rP^E3%a@Myop*7eo|qkGAeDVIP^LUDD4}r zuoZh#2J{IQkuiqO>UM5py!Onqw zRom69#eO(De%@^>X8zK(ey^Zm7EoQPMRdcQZNzBL3_2IaIi7~U`qrdf*h)VGuDIuD zK+m`k+^+qRK?>|-UAZY;w~nGDH|b~M+KcMMUdHaQD5#Sjos4Lo7SNmA6{V@5d5Kg@yWL0_ntEpIWFRPyldZzcb8LY^8KdIE2dtZ5ZCXsV# zgXVGH&X=+QZN9@x?5Dyo03L7AY}PMxGqjS32Yw3u$7zX4dT-k>Pq-gFRfc zhr#2N=o+?DIgF7weY5|?)@cg>kx++`C)IuQI+Gf5$=Uc>)6E1lzBP#{)`snAP+MuP zEx=}FjMEn@a|J`51hqdJ(xAXg$M`l#l!|DsSO;S^`9lpDk4LKXd|dw5TlkKUV~ zt9TEC-NWF#UEnjnvmz=??1WXx6l4vHpE>{3WNAmDw}-Cxe09>lEe;{Ok^jW5#k1Dx z9WPDu5+dFQf0X?qRdTzOSv{8UIITi0WXZ|HY`Yr;y4mpxFZX&Gf?kPmGBp3G36Uw) zI(93w(0c;u%`puPC=LLc@Dx-AV~3okrie(z-FQLitYzBD9u90%918| z0^)kLt2&tN!~^w}CRC=bb?Zx2IdKJ>Kbd}H{xQUl?B_QSW z^Qh<8wij0{HCjSN;YZ(hZJV~h2iC0Z)m_OOm!6g)Y!*FM_AjlwP(x#dZy0UVeL7!h z-|%vo3nX%s7*Fv|gK~)i1o$pM*i7}|VO-1b!{46RfG~!enlTfSJzPO;m)xd9i501hS@=Cfzda1`WaG@m_t@#CqE zM1TEs=BN7j`|0xBRTJ>}Sp}40|EYmyEu|v$>{)d**1g%Qr#6POyuRzRXShB8j^_hT zMPHvild({ck<#)qIbOl?(%#A7d~iaek9mecP9w$eov@odEb!~Y@IF0Lhz?eLP6N}{ zpE`fHUE8X3$>E66HIYSLk(WHu4B~~zI!c@H#awfCE!OsGH`i=S3^|_c~Eo{-Z+_Sy$a&_*t%u|W)OMQ)#T60}9a&=11 zXEVOKxjAITi~m&I&4`O1(_c}IJb(Rx5zgZ+UUvQV>9$5v0r?MMVPVLjXZNk(|9H^2 zg~sdTXrWW|%~5Z&EA{R(yaVxnvj6|`|6Abyodxvi2ks?vgA+}?q4x^^L}kp#?mqsj z#9Pk4rKhE(9oDo*CwPiNOJ)JI&|klP)ew^Z_}8x=h9mXVox?Vp50)rcnlDs;fQwf@ zHmBGKe-+3iM!EE$9)DJDT8h>DWvELjU!1pW@|kizmrEB7jT>|N0&}AJQ>`}E@RN41 zGyv1mbTKqTGA-OfHri}E0<^voQe`;?Iwx)HURwKPJLGZX=l2me&EdhZ#}X_`93=YQ zZ2A-;xP<-gWR4$ZKG15Fwu>>|yg>48ErZF%kL*;evDdHQ<+ifynelaw)A@L{`z5cH zg|CX-*$Q56QM5NJG}Eyw=J8I*qoWpTuaE4y(ZE`JXU7!_sM5t~nVH7Bij zH&S_>8N-Js+vA$?lkuS;Nzj%^E+R77bMxHdrf#Fr#;6{Rk=Hv(nS@g&)IA%&Ye}8& z5U&Z5xUehk?9%n&Vl;YvGt;W)_S>yW5e4?qQq$@Rx|>kPrS}nX>wLbp`PE8zDfbb% z>*Uyx65Ef=7<8YDgXoiHD_}uHX2e5#)W+ZUYII!LxY%m6&4IrSlcU3ZuQ5oSn1wnh zRbmBNADYMjYO?BHJ(BA+1ht$g5`n*yAkoVv#A!IBGcmB`&;?6NSlZH=_ZlX4<{1}a ztb;QzfY;fU+u43eQH^e5V`6EJA8@`dY5te1mXrPL(jsX#3bDj}9T6vlEJz4RBg=Qu z3t$}Xlo&ZW^z(`E#-sz8e5&5o7{)a&qS1?Jd$`@3TWKR2fT?teh8JWN57`T;$tkyx zp;VpvkdjnCP?_K%8SV06y)Zjd( zk(5M(iD6rDnJz{s?F>J{_dpN&QdA83MW4sT4Hf}WwT^uTss`t zY0Rk-nz^UVvv8yg@I%d8*5}@PjEZlONGv(-Z0r(uhWL+tYNUa6aXT**yK%-s?N4s0 z#Iv#XU+|&L&J2(@A=ARS);VDt2X{IO;6$M5^vBqL-3q(Vf=FOH4dpA&WPcFt|-L-iE(($E=g{|YM^8LN!NO- zw%+O=?KR)mFF9PXcdj9kQ>PU@+BK&K&4*l{{a23=x}n1{N$WRvhZ^8TdrZO@%neqi z---v*4waif7q^=o8TLdl%NwbP1|b*N{iBh6lMH6>pKYtiO7bh7J$!54&+C^IBhJ-L zzzFGG8Z@-ZEyM`%7Y{52aVs8o`U^}r3A`RhzO3Nc@W>COWCT+6ulpXkrugM`*eU(i zAvQjXCb??VAuILI?eGa%i2D?M_?A?MRxmNrX2ISetW!r#$Zu*~HfVCYz7#G`fsMD+ zt+foV**dG?cIDpoWicXf@`UANC9OKB5Dy7xzqhac3(tZlL11?w#z4p8qie2UrTggS zNlwQK>5Um;uHpE!QuxF3o({3uqjT12+r&ot7I)xEew>hnr-&vqr2XX68Ft)&7FE?D zUZ3FOW#iROgml-8cGJ}AHOkt#Sll!18_M|&<_N;Y=MYpEoI%#sR9I0oo*pk(6}u;b zlwV%lh=C*nM$62$TSmf^{^46~7IBMqL#FFG;keG1=Wn4@L1 zS#rBt{?M~px`-x3+P%b9xn27r5mossYqb=~AY(a>yBcj>gAMsu4q6wX8Fxo6m@SW- zQM*>yvR!8PuT#ST^_^RUnT}Uk@ez8M)u4y9kw%jHh8)_PXz9u^*E8r=@kK|l#d>{V z)#*N<+SM>z%Q?=a58R4t^Wf=sF`c0P(r&(%fcoBz!y|>%srptExqo2` zh`!s?7skIGl4I87wqdE*>%8+nL=$6{qTevs0 ze_SxK*S{1{-BA?rJC@L8h&SYLxkOOLTKml%q7}@_EC^#Its#lFAqziWFEs9WI<22m z?S4EhRO6Q`8a}%VclLgiJ2F0Fin1~nSA())>zIw&b$y?WHXj+r*%JU!EDGjQNj+ld zZtgizcZWEg^fpUusq-)|*G&&eiU(QQMs7z#BJa~TnA);2+a-L-MZu?y4^=PPktZ_K zSgvPXoSD6h07T3q{JP00xx-Q<2=P7(zT=ADY+#~2!sVr{Xdx@h^u_c0?EPxer|B(-6FtraG&&6q<6weAc z61Xze2W=Pq>~D89wH z`iMw9Bt$7J2$sZvJw&hCZr(OL+EQc6wZI~f2Stc9N3R^kN!Q*U66aUW4QCFl;&mIp z2p#@3fZKH{->If@9OH)Yd6nk7>KK0yzbX@e&wuA7ehDzi3=bYF>2bk^w9$L-Er17Z z)AzEmwz~Pz@aD|MMV-6l{qednvaE67K3XK=&To=YusN# z(W3f?xOF6dTC_r>&VyBiA~S`Sswi4lO+&Yw*a6`kT^At+8wsKhtW0~8KMIKWzd>g-S6+D@M3)@OW!-f-6eXp}(n8(URsiGOMW3y4(`%-H$UDRuicC)K35O<1j`bCK zh&YsVg>;(!*oyUFY?#aPPO?Ab9h{XHxtlznZ}lzohQCkOiCe)buYI#~gZJgGq;Tvt z^(4O>t4mcmT9UsVb8v)0dCnz&3t0@6W?uy)x;=JHl}{{;vJ-5G_~M)18v}bZtvfP_ zv~X9;%~!#^{Db)IZOfk;(1^>(K^h`8UFNREUa7F~ckHE_`FQ2-=HC+>A@48DS8e$s z*!bJHbyuLL$h7x9XH`pV!*4YEi-RDOM2Dcxp8HjOD_+fPdiq3n;K;sWbn#Nbk%+NV z_qIO;FisvTy(^EYX}V{OSswxq!yy$iBUt<`%K2^qV}M{^V;lE79H)AD&PxNC;JrW_ z=(i-%fSTsrh3tx3uNCDZzb(@A->y{Pt+jGXuAo4QTVA2ZT@z-?@N^5IzX)Z&sVcI8 zwIsP=@J$jp374hQHe`Uxxb>7YB9#Z1n0ocU;90d)|6vKfM>7o7!*5Aq##4A94(~a% za|1L5ox(G>9QhRB>t*TJ7q=lie%i9r0dyO;f=8fphA$GC+OI8n2`w)NP)x)puZR9or-b}5;P z%q?PF@%CVhpkOwkoIbXt3?G5W#dUWhsBablH^H`<^UlSlHdp=6s+_BxotwMx|0ZB z3bbbm?jWrJh>?Y&q~>C9B% zWIodO?EV0AND82}cp-yVKkl5^I?wNf?mk9LG}gDX=J!08-lQ`9Fdzp;kPddGJ21NY zn_@ABNQsN`p8Y_n9Wad(ZIpCbH5fOKoKbGOK5x!6{q?&=-ThbH_I_-DP{i|{y;~b_<{kF#{Q$kYp4%2Xjq=j~!B42+ZLWH=+U$P+sg{Vk;wl z%WD>V^*GGNY<1C?4{E)0R*XDo^;w?XOK~POKzo%NTzK|doM#Gu~JDX4?vUD?|9E z40d>#0G3<0(M+!Zzo32qajZUWc~db9p~S8v&c&kKsiUS0%NUQ|6*e!OSzRu~3ElgS zTZ558Q8&AifLn=1Ty{>?E?>1#*`7B8zYQg@^0$Hu-2(FA+FKK>`8&i@Bzof1zNwsY zT{w8_nnP8gmC_VOKQh#`l`OUt{JydM7}PzH?)CKY3YkSeH9cT?BYszM;nWq1n)9uU zuMl?P7`9pt9_(AHK5P!DI%W)?I6As#aH&zzw$e1Ap!~|}cRUewr;OaFrhcyn>;8pYB7xj1dZRJhtM}`+@hzbuYxjd*zha$$BEw`MSw0X> z`xqwrHbsQ|C4qQmq99fh?lCEnCT7ov9o6#2yF-wa+nFUez+C{bO%~qa{suGujgS2_ z;y;Zqw%EnNIe8nT7`?Lj*Jhu7xksvY*X1arbTW^wu)g`TtML+8(k<*dpvxyGL`Zc^FCnVi32 zhZ9@&SgIM$i8fBCCbEzQ1(OqZN<~M15`V3Srd?)iZTHEpMi-_pD;|olmkD*C};9aj{RUTZ{sFn7;3t zF`m0aw_xf=KJ3H|Z@OY8jBdEfoTeP~+fG{hE}=Pa$LX3?kvAQIPGx+KZIIVEZ+9e4 z;%&zdwGUYG2@|M;Pa1W;EA-XPx*!Km3cl-MQ+fJOJI!r)Rk|>t=4d03Cw@j6KA4PJ zh4a$l^qMh`qzxSjH#GQ$5R7kaoh`)D6*1(Xa}mFr(U%2)c0%9B53o#LblE2;^jFfZ zrz>k;gc{O;RGXij_z|8@BYc#$CfB(&o@-mVurDo1|06@FPFP=UmcY0&-xR2^Zjww` zYsZhf>rdIULl({{8fkGV@jd#og-6n3F;aTLl>M{*tpLTUgGW#TSGj@n$4*6R-x<@D zz#p~bPm2v;4CLfsp;$Bii4QEu0dJGwKAurmTf`AvO;;)*`6#8MX&TLXjo0K>0Zu~i z{TW^EP0!Ap<~HZy`LPY>-1nTcLKlUNv+OMvbrRoK9+}U4hMch<=6aYY|Gvj9s!uXN z^A=o=%=w{qHbnhiVbw6Qpe0gh8ZHw5;CW}eo;>%c7ilp-_e(yL;_TAS`99bAmSH*y z#y-FZxsri&HsQT0-xw);*w5He+xojtfE}B*R&**6QB&O~)rM@@2e&f(&^S7MDs6n91ouX&|WQXKlg_W(ZJ#FGX4KSI* zns|de+lK6#k31>md;2wB;ekYlp8_rsKxLRHNw~~xpUMeq6IkY__99a$IUy4wrR(6O zPJ$~~3kKm!@kxZ?Ju=~p-(zBTSV}047* zr8hHMYg7-fW|Aj~rTN1;P$aLZOv0{BM%R&_Xuti+T2CbA%B#Yqz890C3;(tEVo%Ht zt#i<4?I%XA&rcuuJRoxnm1`%qB>iU@M`n)B540i>AzJx=WL^IMy8dsHc74Gg{!z_| z=F-2PI6Wq%YMTEk=Kq`56D%Ge8qy<`V%87zIUd6!BR$ur6;hB@|Izo2NhT(tkN1^6 z=TT33wP8)YWotv>#3v3?17K!{K)m&)`eus=yX#WD{Aw?t^9K*{p(c*`hnmXEW-WBu45M~rYd5R>&qig_e4@1iB zDiX%^(h@jvn0v+_VQLeNS(OW$4O_X!UPo*1^Cn0lc9N2h=WlP6DFjZL^bU4-Yu!+x zg=bJ#rP0JEdDd?2;-(cDDF2*_^&cuYrLRXspA*?0_x-sE|G}Da>fUIQT^x3JW_K3l z!*0qbxEsR#wQRxjc@g>0Y~#4V=_aKqF9Vn3{kBSKWKPfc-r>ksIxc;orPADJ>cai! z_TKkmf-e$0trZu=e(vTDIi{Cz?>eFdyC7%aUhCk|9>}A9{sKW1DE@$lrZOY4N5kjZ zVvzR^+PVqgMs!#*9VK_z%6X3zf|4WC`4-v^y+R;ye4>?+pDg)PGh^>-tkS&IWQ=7C z4d~`82l7c`Br#V$UibSy(ou(lkQRul$s#hI7m^uk#GO8Qf)5XANn1CTmO?JF#j64! zdBOAJ-+9~<%jnxzl3*fFzzBQ9das$z#6pSgsnSHdFWx=)d^guzD`+7#wWqSOCsZQv z;urlBmmG~Hz;EOx6o6Sv|M>0xl5ZXAa!UG?sx&Z+IWL^)c?DSvHIjv;$}^f zy`RC`I%nwt@dlvLxgR0?1CO6ww|SgDa!b53^MI6m65Luacyv04*NyJ$BkU;RD-gWw z$%r{BdQF&?s_ISBOkF8`GXLak&uhwx{tx`@j$Vb&`E`?L&pLm+vlGbq63g#SA{yd; zpR+er{hp5#@?&oDn|KiUq>&!`U73T*%N5{u1@qT|y1bn38Ie)tHF6yx6}?plsYyLy zovmpv_@xwLMasrQnRQpifEjLjOj7^%CodD#RjIRAbbiH-wksRt9MCv0^})+$*>5eA z?5f!@;r+vH*SRqRhm&^&FPTJNs=-J(|AZ20SElJ*4gq9iFfEIji) z_GicR8-_rs4|t&r%oTPBBc*f4bS9A#Ro@IM5NVH=aHeQyZxTl5;q}_dLxuT39G!`g znWs@4k4LeQZ=8{6VQ^?mm?}T5*Yvh@HraQ)2Y>q|>+<%oM(J3^in_0&sVbJ0taA0M z1IjTD{(?U=;ck`?Pz1@9jyf&QMQaRk+ z;nLhV$GJ?8$6j}f32IhDhVX(E&;)OI`;^GiOmt-jnj8RhR?zQBPqP0BPw z9Z%jh1G2SA^^cZ})LAGgfZX>mn=$j9;d|CzS*+M#N<{TdLZkE9lXb+HR?iJ>p8;;v zBHD@j`sNA)Z%rFpo+m{)xb)5%BBzJED}htRf1wc^QbO(rgaRFR-%k(!(oiD#^j*Gt zCbg1%58bT$GS&VOJY?7G=9WjXa97@+K!rn@E`6K6GQ(TW{iN!il){TG1y z?Z}Exj$5TqhN$db%D7Zxi;!B1n=w9nLc?Vbb-3I9 ztABosre$%`A?RH1voDvia-PW+S%+?LXhG*U0BZ}Ii?vgxQz*j!G!Utvmc5VqR!bs^ z`>F$Z1QKU7O^jy-qB-kTm3Vrz2pw zjdf`Zfs#9q?Sx+GN$US%VJCa zHGLtIuq+V1QimTW7(P3KY z4Pc7r2&$J?l1FI*gf1=&YF_(dBF;Ib`sOt{D!g+ z3!SJ)?Xf*%Uj9*_UQ_05HOVe0e_3HDXe<}_t@giI6s9PQS$RphMs$?uM8q{HQn`haI7BACc|#Ue>KDxVB% zS8dw)mx}1{bq3x`zVd|r`a6;FkgEvve)&MJe55`@Z3l-;dVc|Tkljl8ll!BfiROLU z^Tp5!5w`StL}UErlEvC=B=k2fxM*%&1jdr;L#ME%$}ZY9;d@CoJ5LZO^P`)D!UNT4 zu^(PhnSjQg1XAMXdF4Qx5Hx?NaD1LSBp|g3iMe6q7>8L`? zq%R@*UmU@Lqj+Nmhi}Vm(`LxIY$p!=(huqLVNM?VuT`^CKG*a($!T>5O;cI&4`gDt zLs>pbL@8pG$7J7ZF^VQq-$n(X|M3HKn&Y9NVKtqg?kEOos2-~1q>uVz{V8Et+TCQi za>OgJVv`hQ)6U|J2wR_LqB|ntRz-535JK9NMSFZr0bH~VbE*lv>mC2>y9vT|I?0QvYPd$Qj{FEq1z+qz zWzd=KeifV<(TaqQE zan6CU#xbtb%}7#l0#Cm~o%E_|2h)Zd z^2N^-Nowht9iu9IsrC=T7qnJ6oLsZn6X7Rum#t+nspmY3${A7hW%L<^#p7>gw+9% zd!7HbP_(3$*`k+#X=G5YE+sKZdyM8s{p+i)g%^i{_sstU9^}*@-sJy#lnD#+KRiZ@ z^}p$+{{`UgDZAX1(?eeAI&`=7eHwc=JO7yL?NzbyafYp#RL=zu1T%o>d--F5sP9S1 z%AG8YhAv(ek+!qD!qv?Z4_m-zBZ&T%Oai-Tn?EHBSnAfR?go}?U3j}%Ii5XAyCUXp zenjQrOPL)0Z5aMzqFE09>{Q+!x!#@uT4UY>z_;M?V$FeKukr1bh>}0Yl5JReCByRY zU$u4fmKK(0w?n3rB63muX8~-0-jbTQR59PwZB`rR?zY9Ro5{3AEs|Pb2^LDP5n=!|;Kxu8e^QV3 z>o9L8U()(o(M>tBva<#6CP|Bg1b5@eQw1q4QqNF6XX3TMyPebvJ6WvP@hQ;-%9fk2 zn#7M!3yUt%7l%uhygQzd4^dJF&B7UP>w81zpatKDnPR>$olM*Q+B{Ef{g(nBGOHP0 zbS%|4mzo-uBG4HX+l}d?F4-5XO39zpfUP5{G7yKyiXSwj-}(`% z4cl|h$G_GFvVI@C{6^u9;wQN=IBGdDZNnk4mq;ccGDS@?dE0N_VAisWC2)ed#4k_t z86{R$EQM5BpqU{hHcnC}fa{Vwja{~jfH&P&l1{mCU9I? z;KEs}F~69`+0gUzBLB_;eP0rl>wRjssmtx`a70pSz@o9mW+>uNF7@$_wCS%lPg7W#J(QuHQX4$412 z)BXM&zgc(@=cNN(rf);7?$-y!e!Mqxol`Wq?b^BuFAw-<|GRlHkWy>UM48b^;jV0} zVOqBz3{+mJO*y#Fa1zY^EJERaU}fu=QvnTGp3hV&IR``H@szLp?EmpitDzK_$^h&+*{~PoRpLa1OwlDMHmsr9Rs%vT%8w`a zF~_;eMdp<6r|RzWL*8bP2@J$hRj6|L`fSwyx}a5NX^zVGkwvUrPUS#8++DhjJC19G z)~?_BJ+yOYGGnXFX8`3(bT{@=_OdMj{ojm}9?I5!*TTv8?Un||K=SvP7#8+726%Cu z`uif4ytwz%vdK+`_01H(ivV6rK0Ta~v?lCSs%f+6EXONWlD9ZXvr5x&R~6P*y-AD} z_rV9bL1IP3rG;;gri!~CJqePk&9gh5P6c2cydV5L{0ujeUi;)}cH8$UpuEm0eTS#~ zfFb%j;-`d3Kkd5s);+HkjSklbg{hjc^sEZ&hpjXDw9c%j@=Sb6OQu41sbTIu=LsTn zB=&s!WF*$017M_&cekxt*Phqe_PeIdaqrdt{sOiT3|~?gsC9QYrxiju$tlyGer1&; z7|5M*(@c?j%na^09xIzTtzhHYPgAD(8vE%G`Q-se%1BmF^&?W|@&}Qm2wP@8<77Uc z%l$OBM3naYqwMCPZVmOvNXmhTf~2*2pF=}{_*Mz{C!@(Fce*!^L8kI@`FwE9^bwzc zyWyu6x|38fTe30g6QNMY>pT}eQ%PEv>N#%yqdVcdbc}9xaB+>{?2)_@@wu^UXVq3? zL$k><9jprDWE3RLq}Ed5sAK8ixqU@I^GM?Riy%HcpyQu1GFzAX#qi904WBL zR-ZNXi0F2BM-dy(ojXl&d~mVNoc5PuJ{$*Np);0^gs{W!MtIQ-|Ha%@p4KvRFp#@cAN~r{e z6|w3sIAR8J*n|9YAIbYZlq=E#V+TVEVuDUS8DU-srqnQ_GmgU46>!{!#ml+`E zho@fCi};w7j7|*UHJ-mV5203dHb%a;l30n;=3G zYdb*;T~i{co=CBCL$UMgcvJoat=5NMMvX+#Iy?3&Ocp>U&W+!yU=&gL*VGcNa{ow6 z7B&zn=kit?N3)|~)keY=i{)JB;RpPNdw-Yn`gSJ%s3h_1n{mK&5(YGzUIEhE=B`ra zV$`TdMto>U=>lmosgl>rm_7s@Xm(FKrN-Ow=i4?c66{JRVQNJUbD!4GR-KxtY;sfj@u#P>K6;6z$=-2X7wL9&-Vmvp0j;>dAE*yp<}xt<^Zd7A?2e1`fQeaBYi#=WO7VIN@%7x;XD% zrYldH)pIblm^eVwY7p8|6%u7YAaI%ZPb5iNJtzxiD68oUsG^EMC4(5u6S`?wi@0-fzy4adx6HP5O8BTDwidlB_%yFTWh4UHl#v= z(~_yEvCL=6VXSpb6g)KCHv8;bMEAnfsA(4*XsO4aIwRk1`-xEu5PLDywC*FNfg^oL zgHMgz-J!a~NW;_i+i8-soY8`Keq@MyaZo`~+#2k2kjzKl@uoQV^HCc#A3yX}#NIJT zDlNB*(4G#rjvnL|JZRU7t6(h=aTTmxbpO?p!;g9}*7aiKjCw;kyTc_8(L5tM5%+@s zv#q2Ukzmf@(UHQ!FLHHI=Mf2hoo}WUJuQ=qF}oe7LXn50elfB9n_4*XII%MmiK#@y z$N$2%gWO*>WOXc3rePm*&JjDfg~Rg{7@5Aenle6SB8g&v7p;g<@P8+2N>%(#W$dQ6 z8sJ?Z%KMp&k~83E*YrtJWG45lP{8iy%c`HXB8(l}@rt+n(+L$x zYg+mwG$V5525gcJCU@t$$>+uU0j)jpep5-XIDUmK3Tw5Y2d{cTk15H}Y{|IOdkJfXg1;zy~h_P+H=v66UL zs*QZW@#p&rGbWY{y0Vh*^o@>>HwcT%{&IY*>v|R+mQk%2B~w~BFW0EjZ2tx-Tz5mB$6YmYUrWkk=Yz^EwI zyrR(dbDcPJ;Gg1-d4VbZ=$nR|=#YI!cPN=|Q#le!mW`8w#~9VWPFM1Lv)DG>&Vo0f zJf*yK6KyrHE!R;egCfy!uz9Xlk)rfYBNl29KfDD}oLc(O2s@W8w8d#x{zFBRa5v6w z8fN%|Ag|qwJw<}^$`~N6SU%Qp`tA(ggwa?kgjeRYDXQbq?x4UBfmi@&y_^oC=2yvh zr#D_CMRJY$>|T>G!l5-FEK-|2)nh&8z_T*;*vhfbe+|S5vYj(TeO3PwZK$IE{NTF$ zy&|3tkPe$=Lry8$!#0Pi9B;q;w3Efd(Vq=AHaXN{#;FCwMV8v2evB$A9!@Kd1QBjX@hh6EZ1fr@F+vHir?U!p(mx3L4m7+hiaB4}q6KZ#7z-EG z8_Z6T_!A@`mupZ9-g*qD77${VfGNs$g&fB-CyfoiP1QbFpwwCZ10uND#_b~p)xa;Kj%(cWcI~Wt7m=)va`gVp|gk?=d!)wk~6#G(h6Ja?(=k5*+8QqM@*Wz#v)adJF~w6md5YAwfo#|?F^KitJ=_%J`G8;z7frisJ=eHk zmSZ>*elZQ0b!F}EJs=Z)EV%@5<;x#q0XUnT``Q-|bUF0|OZu+}?fmcvBrMtQ`?8uT}yn z)@lU~)>I-u>W3r@8Ia#exZ&1Afn+p+d;~dbo&%mFpr1ODU7WYfa`|IzH*(570$&pO z+LQrvER7z1XZW(*q{0a~#e;HMp3QnJj{6NtxmB!3g>hc>C1OARc73HdIH665h z9Vb9p96rPCa``#MM`Rjx&OTG`zTzwGC!YGA`4A7+@0H}J%t~6e51mpbnIrW|uDhzc z8@{b+Ql`n71ioTM0+Jc`dM5qyxBN;a?+Q9$fLchf7C-!u>2{ts$m@Gi4Za5p>$?^i z$}J#gUVUD05l}OCBr2qSs@_A&itKwy+>RhSFmf&v;Q-d?*dBxM;!e>PU)}Vw>>M_6$@pa1RohRJsf|! z9G@3@9Mgn%vXk9y=rHW931~^~3BT)%SSkeXO+UPWiA$~?;sTq%5dIU99Qx5~#pKe{ zf$l>*_cLk?oqhh-878Dtk%YC4RvY4Oq1Zk{+P^B;C?y#2jn$<;A{Pz52 zpy1cc+Rx$kab88~AUH2=IOzA|7oQ;SBxcTBomtZ%GAD%*z~B~|I%QDMWDEa@(XSRp z#g)hR>mF-RFHj9T&ca(UCoQ!{s|!O@a=}>j#`%aFoTx0%LxCAl-$*;Kl~2r+9x#`6 z5-N@);&7#nX%xU^yA#ZlKj6Yie5*%hcGl2He( zzRPzw7vM`=Iohv!i?3lF^N*!q)`n}9@sH6(R?6oeH5ODK3=BB=R&=>yi~A!zYgSsc zI=7k%o@=Sus-n41+L}-!d3WYF1%t94R^|^4m#53FxW%WV&ZbQRfbZrmvHjRP;D-+# zm(4M0sKRXa=L4xWDmaykMp4XHO!;X zly~06(W%KTy{}*|uwVn#HxQEfBjYVj`qtW4e#nYZbig~7e7Y}c3!>wk8^+Z*bcMp_ z(Qu#Rzpb0VB<0P_bo|bxP;Ck6^AsB= zEK4GOQTpGT+S2F)az@C1bidQhl&BPC@`SzuF5nlA$XvsXKS0uPi$M46P>j@yC zmigF|B8}?Uu1ocNPPb?L?_gM9QT&Vczac|~RtXXHP1-buwD1JoKHqElvY(oo>Y*(6 zQ(?7zAi^p9>y}M*95hkYokeSgrW2U~meP3g61qsk5%o*|n-k{+{YzU&+5;d824hai^5qo!+ypX2;_7#5+!;)~gG8 zueE6I9g?(lC?sKg;4>W|vX4>C%hMfr$SV3L`W+`}IT6C*7nhJazDV5qrYPAC?3|U0!-Cz<5@KA_g!@^n`%UhA+q|2wiDsh`v({WR z^D*Ow{iY5z4pBUvQ6K*kuJmzeQ*?})3@*}kDO}--&s^ZSYt_^{qz^#i)Kv_L8b{Vw z%4@IzEGKXTyQ*jI3;<*>Cy5`cvbxFF-Dk$)m*p(jzNzimRE7q3=IdV$**``}h57|p z*1b@l{`+U}Y`-9=cVly2rQ>Yu*adhRSt(5R+y$O=%Bf9MhW}CRuFA1Zhir*+mMIc3 z29N#tZMwu+tAA1`$*UMkUtx|tQE_p0-ed5~V$cxq;p_uZr^BWVwnWb6+KCl|0vH2Q zOS5UZ0Z)C%7YRcevah}pt!AZIUecS_?8z6Zhpwm z<)}kgpH800*>Sm2MtRx#d1P!;zbpLK@wmjLCE~LtHCCr|wmSuR6U>_!Eud%;*=IPM zr}5U|?HmGUu#;y>f} zb0F^K@&lX;Z2rl1jl~#9zE(H_DcG(UZ`Gb}zuuXqLuhU&`s)2fzdGdsi_EYmnq(2e zibJ7GjzlDH&!V73`#-c;=SgOP4beMP8)r5)-82-v&z*v7;<1mMA`vn@mXzbOLJA3~ zs7b*cGZ@33bpa?frf&OS@@>>`BtV%NZX_o zvHVTRLh=2|9-AQ>6Gf3y=U1=a_a^Q4qu!{j$`eSI@HV~pXqw-;w< z;D)x^Rtp(6$*81VMN0_jHr_M}xfwGc_g@!+UlqxD%u`w$lQ-57ayI5@aBp^`fYmYzz;Hsk9o+r+6>Hl)s!8r+YS3XhuPxWgc?n!~CXu@1FIM0!LIFk&-ojZ89X1k!*6uY7$STHwUXBnMtPFX^tnIvgcH)!W*ySbebJ z=xSkZI~E16j5y))`Ya!z({?2R6yi}9Zk)dw5z|CI!ZI&7S>+_pt>w;RO_4&-9Yd%?OC~zL zNdfTf@G}R2@&# z&b);>o?^x_IoX^W<|hm}_t!N7RG^sA(;f`%9oj|y7Ibr`#0cnCL~LKnISthGVO6oU z?2afwg&D8>SDx*cX%5jzSk`?-db;_PAokJ&DpSud_j**b-L+QCfiRYxK5svMenSG< z(*h1}3C+Vd<$hl)rN&hMAx$p+A7=!h#F;M}XtfG?SMT zWCA4`?fr#8IU9+t6)1G90u(*3ZBmRF!~SEgxmZy_X-{4!1-R2d*AA>>40glO`gk5o zVJBd;zuMGo;A;z1QUq;u1n7##Fa=zVR5PSceVv}Uo=W8aUZ(rRF1xV7rXiopbG16d zTbzG@jfxKS7}hHF&8ek|yo{M$m?Hy?S>GG%-yT(}KmMYy#-$%Wo};d{?|nWa)KQ73 z9(rk;6z%Nhoy3zftk5JPk|4GTl+#8IJzo53?G5rDTW!Nvjcs8_$#Wrxgt)hqJTi{7 zD*PW?`BeRCnB2C{C6j8FTvLhq=>hC*uRQ0jzkFg_e9p>m;!Y3u>o`qGyj0!$`=`RL z4>R;!zOYVb1+J_3;+pO|aZBsGC}kxju6E@nm$`jWb^^Z(Bad2db(_oL&eHjUyAOI^ v!O@k8pgDUTTnimwGwAq_Jy^r?=fBD$mHLVE=A8kaLBina>gTe~DWM4f1F_4Z literal 0 HcmV?d00001 diff --git a/docs/workflow/ci/failed-test.png b/docs/workflow/ci/failed-test.png new file mode 100644 index 0000000000000000000000000000000000000000..462fd797324eaf3ca16746c3cbb351930a4fc7f4 GIT binary patch literal 84781 zcmd43XEdB|^!KYoiJC-<7DVr&MsLx3?*>t$_d2==qPGye_ud(zgkh9K@1jL?Mi~s| zjNkJ==l%1n^Ws^SWpK~9@B7-b_jiA<&laPpu7Hn2frEmAg0H0bK^p}H%>)Gnof#Vw z`IG0`nIXt8sGiyiGAMPERQt$pp4myONu!`NCgR>(Vmuw=rfB4efwEo*7FCA!#b>Edo+&=GSQbTT-4`Tmlk<)GwYArX=Ih$! z_W2D*=hoW!Mgs3DS$9%7t!G)!tn=&!(oml3$Y6d(+}5oE*MvLw)JO532TA%*rUt@< z1C5a%$H1w&-@TsosWRAfkuPMdWYji7{(JZey~63`)1#pmY$nLxVAH*e93y=?MiH;D zN$%7&L(@*^UZUBi?-(DCcpTzM!bw zY)j$VA(dxf4&#eSjDvOFgTp&FMgv_zf8nGiNeRitBV#I45}XEWe$Cci|8}}{WajhM zpsO1QwrD~cXy;JIN)E3qg`l%3cXbALx(bszbd9yJqC;^#;0mBuMvyH68&=^4*ZMw; zRr)d>FNOwv(B>YKjljfzaFC*w$rYR1CC5n<8WR?>3;A(<_IuXX`dWxDXu~SbA@xs$ z?|O=-LV`r;E;;8vxXaybE_5?wgP=Nhwknf>npu+bN}G4*tSzePe65=UR!#*YxT8KY zgXSH5b3cFr%C#IvJGPWY?+>Ot{2)R3jz$zMqAJUYA-bRD>khMQ;aTI{G^wjs0Qj!O zM@UJLG{tfPP_s=v(C{Kv5W1k*76%x%MtNu zHq+qnevuVZyJIzW-g0lfq9`3Ty(yNK0^{xcv%?SLQq2}8PRAWalTfxggtbo7N-U`2x#;pUjT-lk1V)lP*ris7R9gH4C-YM{XD+_Cc3Gjg2nKVhq~*iA zA5?A9?OHxmI~|)q0ZZ*iKySW?yGN4z8!RueOu;RerFR#u9{2yGy{nxD^xE*K>u$P< zcbqPC+l&*tGz39#6;`n%a!rC^POiennve^9AQy2VahXNrp^#y374A!J`jhchCfOE;vl=;dHQs)bxCvkOlf)xp@*os8)cUK)t!_}cGBM2DC%EdM-&E4rvBJ%W;oTX_wJ~)7_(&^gymg^nK}044wDM^9Fz*c@f{^ zvZ;LKBM~y}o$YglH!0$i1$d0_=B0jzdysq`vD={YHPNvEEMN2|%K~%}*If1N!?cn? zMl#WvGTFcR=JpvQ=CLA-i~CJNYKeh-iIvla&AriVJ$A+^EjGOU<7E}&LocJF8=>3A zUE-S67wbNDe-X_qr)l%f%OaaC=aPV8d9^7Ilm|?L6#3Ek-4*hgD|l%0XXRjX^GZ9Z z31fj$SA_KB&|97DO1WGy%WwGFgYNU;w!LV(jS zq4|)?4T3>6F_kHSjww8~lUbE1FY(29T5qB9{#~fN_BxYu4E_ORNJ;0iS1EC{xxdcy zi`|bubO~SEGX3k!Wx_Arp!%k!3_`0=PoqBD_>4XW<`E4l14$+qdVp^(pF^nRjxfkM zu=B57d(~DM(=6-j&KDdcwfq<=r{ zSOJv%Si^ilb|5k~1}^e!KY45myR%=`=z#Kdz|nSIUQ)g{jKzt&w;`?AcsKjCnq4j6 zYwEqYBZH)4ErahHR&Sl<(Mcl>$mmDOHc=r~5O@0ILJtS$=k*eU2YnEu-4#CwD+(X> ziCHk?YfMN+hTR5}8r+l#OK3c08-p>G)zEI5`yO=XJi9M8Y9=JRjZ5ls+@&<#0e>yr z;$KHhy;$hdfN5iTZ2+97R@grIxcjY`hk9B2E#SMzs6)zZ@VA}1N7H;?NIxcw!dqe^ zeK?bUa#q?vbgF*ll2&8XjLQwWp?pdWf&6Yb;$J?ISI6jFnF|@bmM!%G$!7yr4}G>n zO6EHIG$q}HZm~1!4`g&Hcgi*3i?B-m8A-Td0u`4@C&&*m^vFxf#lbCKWxsSuE1G znksDmVO~i-BdODuC<$#Kz_hhpW&-7QZN9nwSTGY#6Pkd&F#)_E@%1va%?P9wQsAWg zW=VmIeNUgzT5a&pS1j(PzI)%NbAkMYs)+Mf(-#V!BM5}p{glA$vp_VDCfFJ?7#Ntq^Aq2_&d`$rFaFl*2AAPk zn!U5cWOw}4W5a&CfkpGHMe=H4Bz#_&5=_F|Hi#p~u!}GM^)3b>aX>jXIBWT*&a?l= zA3_^E9A!((LV{l?h{p0?V4``F&@jr~?Kuf)Q`4SV*G0`!X`isM4P2c(!!BH`A&gxV z8w{gMZ{m+F?qH&QS))Z~)G1l>vJL5npH01H=0Hrmw2m8*(wZsrAI8xE7@blH4J>Ge z!?cq3Sm3Fb!M1!H_ zBNbK{r30Gmb$JXnIh^eI-wR-I7oH_o7_fcun~@8*Xhh9z{oR^ulp{Lqt`>eb7{+V8 zRiTJOc^>(hn+KI zXr)8y+>f$GJQ2xcUx?0E(D5)Gy`(e=f)VAC)zcq8ZuLjmpyG85OQvCr-z1kQPDkPY z1$Qq2tnRHgqLcZiqZ%Suaj?lYzu(ZRa2SyL7t;%%GfscX!+nOy8hT?X#}jFcb|G`9 z6x8z<-y!tK!}EIIZs)nbY$sZMli;F9jKF3_J1TlkXCmV4;{gx0?w$;4>FcZCY2uIE zaLZ&sUfD5ieBm;)b{o`0~HHU$Jh3xnl_i{5-| ziV<Ol5wNaF1sW3^TLspmp@6<|b_TU@4ioB!ux3FEF>@<~8G%-?`S(?Xgb4)N1sW z^~pyX;xw|P?rRkwQ;r+{4T10Kh^NKrmM=enVU$%=;{eH<#k!5g#>dFig~-1)5G-2f zYv^JBgy(&%2}?r=?hkHjFOip5)ik~LNA%_4Wbj^plkNe_n6g9AXOB>K6Wxy)e{ge8Md6nU4Bpr>=dyzQv0}7eXrFAVM*g z=e+=2s~7zi;YP*yTR3w{Qo`@%iG>!azGeYvRnk!T?CL>Wn`O9tcLTonY!fJbZiAm) z=y7+1JC#zkm80i zUZBobv5I?h_m!;SbJm`y>2;*>gN&u%=%7aCAppjac%VExHs2qCMU8Pt^w8rpYGu@F zl@**o472r%2%HJ>mmVByiZm(<6{c)1bdxUsJXxy(OIhkQB9LNs$_PKgMVG_`+;3qs z1$Ib3AA@Bb{&p`!Z?^Np^x`*HMjaS>W!sQI=@4#%M(tG+`JHQre53KJeHz70)Erh* ztIbQNtP!soL!ah{KfEfAXK_5Vk{m*j+8uw$_ySV}!E~#PJfVz&&B^3sHMol_;nFWW zguGD$zl;~WuBn0GW)w)-7%_!9lRPhD#fdv(d;So98AO#84*4c(9OWA73kU7^;4I^xi!Sz|$30gn_Unf4Ltu$4yn> z)<2az&UjZ1o>AJ2HC{sF>$^9-K3Zo4$UDs8TviX3$N3)GX(r>4VVas4h1$GL$!gZB z`<%zulNR+X;`uf0vrm^NBJ=i=WmQ1^WZslKcv&}`DG{l?=; zF2RkBuXXF^w*Gi+5`{a^y4~D(fhqj9SBkc`+O=beraspfES|&2a}yNp+NQSrqqa{RvO^_W$8=_AQS2CR6b%@7Dkn)ulADz!2h{_`8po_fp?h@;SC#`}zNAm&?5|6!S6#c~kV2{T#z0zxw(8FS^; z8$2*IDadFeXg9N!t6P{i>|WJO7C7V!#+{-g*!g|a?`uc|Q7M2%dPLu6GfJ>TFV5({ z2_Gfgl)SVb9THgWrPV$QKzEXg#=wjXM@0wTEp8kl&=32PnZ&uZ19=;-D3cbMz$Q6t3Ug9Rf^-8_NcdZP!NnnZ^2==ZXJlj0*WpvlLPn5&*F|1+)#u9HX9 zE&0)6Z|m&%QZFHUTp+0{@pF!;hrQO6iFg$1oOjOO$+WY{w2GR4(0;ag7Yf2_YaQ$% z#8y$qgqMECri`ExvA6+lm+rN0=e+~%WU^rzVjbOtJs-g?Y_ ziD?Q&pQm|<3_CI|VJ%^*=j(K?(DGx=^9yZ*G?NBK9**`!6|OL7 zOjjuC5(_SNb3=vVR*v)v3vS_UwBLp bq7bz627cQm+#za`rE&3*AdA!We6tR7xVa+Bzf$!7LkIY zD&82zds27Na73Pk67)HzKrD;r7t00Hp>Y@u zc^!bi{#`FdRn)49>~>Vt*u#?rC^7U}qzV>f{!Coh@izR@{ktAB6XurrL(#%;uLvvl zSq2P^wQ*+_-H`zEdcGF2LfS+U|X_M{^2q5e<)piKNsKoH^M-D|tJ|@wz3NP3a^9(D z+-~Yqjw=+}w;3tM3SGa+Xc2*_BOaEoC`Jo88TVAO{MJs+ux^QWTwoB67n@^^C3txY zyzkBZ3?Vw|d6(ll-l(?+0S}JT(4!UQ(L|(&7$cx%(&lFPciEth%Ujdhqx|A3RBY(7*-lKIzgZ5`BdYhEYC~%W@!V+Fk*eX1MvFFU;VXx_uBnNlEZ*y-WT@S!mN{? z=)e-Gwc-5(-_dQ^%ccwB{ME6Tb}9Y7_oE>jIp`R2&w0%rFJFTIecpf&b7O#8zI6y9 zpfW;s?ZexV6y6RVdp|vl9o$`<+i0{~qw5|20DE?%&8eNG`;Yf+jrjZ33q$h+{$qd# zZ=ioD8d|J}?*XC;8}qL1BTd?IK0>Khx{zhj;QBITu<@QsSl@7dE0Sm-(V9zZmjI^m zevH;SqCv$8FIu@=Xfg?(y(Zk)#l@m5aUn zyN7LwExEfcQ-tdT8Psl7y5syQlGCN5SWWP!u`1+nRdh8w3SKbqpB{9Z$bibIt@qkB z_B|$-LjdI}pA6^wQ?gb>B2Epj*~B_jGAA2`qWfEr-3V8CKjD4(C8%a-ty4rj*qBqw zmi**T*{StLl?Eg-BCN|2ZaE1Xy<2UYdUO4gBG7GGEDgoX$BUK!N_$zQUQ}WM-lmOi zB-Pe|74>|6aL45%W60EU5(F5w^Ti{~DajYy^uEuEBe}p_`SVWAz3QO+s%B6DOE&MI zgb)WXVDmaLpfzwZ?v8ptQN_LnG6#ksBXcf@F2vSIX!_>q4Qi-EH%3ZK%_81lkIG^y zhvlQ3Qv7Ri=h$=;F9kPf<1JRiew#zc*=f2+hkpW_cf<9!2dnPA-U>wj$Y9+2 z%oN4O%j;C$OdtOP|9{KVSSFLkX{d}WrMvCRe+Hly9(&0o5@1V*(V?(idKNVlbeG|OMe159tRlO{!uu$l}z9K3V1=pg7entxFxa=5Stox`^s|DsGZkV81 zuZP5Hz8^r1%}J)u@cf9HW?@)#6o3k$I*46TAjR1!hg{X)K48IL%E%2VAn&3sKS`03 zv}Nd)1qXM>IFvXej17lHuAv}{@ht~U7J$GCK*aHSlZ{fdBSYN3mrJenwa*2sR)u|wp@VcOoco=QSQqX=|nc6GQV?{d}t|^EV ziOs>$1J*l^X~yjye=#j(Sp}5ySo_>UX-bw#h?<7quyZH*?4bHT*CiMRIh-&Ho|Yk3jABvNHaI@IzkAN#_keHFi=gz^5pFEw1g7b}24#(dV*L_3=|Vwe z*_3*!{}gE`^q0#(aTm?#P5&c5i#k&eC(SBASs3@(2|Zr(?ELmT;icZIO%!s=sWc_# z;F=c)-elm2rBy=7jw6tLzmx=_b6z#%=h=e8m}e>RM|kh8fR+E&|GKO3*SUeYmp}r_ zW;`2q^m1HHJd^+N==-!kdW!5lsD|z$FSVp8X1OU!ZSJ}|ULA|)#me^+(0l5O;4XAV zk(~B>B4ipNQPa)fd@6@8UcDiKI{sG~U%Yz#e^MDY1KY5L;}so$YX?6zujFV5C{uC7 z#^UV$Trf|e?)JSkeTqg*Et-W0A@^<59(>o0mr$`@Xeb|%dqV!iI^*ei2MHF{_}2?G z-zk5(qh{)OvBcfI43Y22X_($rPC+oP2Y}JHHj`yK}6QNH9qJOPRlD%s+CodqBJ3#Wyv%WqAU(HSc)1h`eCPkdNK8V2_$gbN3R z&D|86$a-J4QN1uf{N0yaoBwFe+jk#w&{rf?p82cj`+S_?ug%y#;Z5H}qZ=2^HuGId zl^4thei3aE48B);sE`UTIQv;=#;-;*EOG&85VEjPu}d&15bQ!KJf~7I;z+@T^wB`y zp32x`Ze25W2O;jCJr8<}v~fU{@;mspCQw&yJE5-$yBzdFo225GxJmqWwsPj(TFLxB zOpjCXt6lCs#pK`A-H^`XE^u6*TFL_Am(-)3b~crBIvqysN|i~wPis)`;PzR@ZA!am z)U2ArsVCj$tNc}E1ljJ%EMjN8$S26TGE-B7f?qLZI4naq5sKaCh(odbLKo%)67XNb(@YV36MJKIVw&_JQgL1N zc#&L#s?{Xdq5RvqeD4=nCtfExw}cL>+XK9t%&jy`-jwC=%-hwb&>Es_-{frfs~kV$ zN}8cfJxrIg9O_=tjWQ0j&OwUVfLUPE{u- zN}~)3{_eEeG`jcdwNCj_mv7ZF;CH|Ho$4Bs^HraT3+>%C>?6fn=MW!6s2$3xS}vzU zgs*76`rRSwj@`7?as{2HN$V+AmFH;gBrH>>JMOU_A;AOG5T)_%`#adSNKaf`IljW*- z(nYRb+@o=d>g8v@+7W$-lzcw&i&9Q$R5$Nn=bdYj3auaC&8i$TAiY>xM?j~s;Qij- zGI=rj&_!Dj#xK+w;I1(%QqTxK!rokc6bY#J+6p=8s-L5VUHEXp@R*6gr{_gt__&X+ zOs;gZ=yGoo&YlG7M$DW?T5`u7E8~=?%fA}}m+Wl~758AI+>}(xmwVqzL$@4wVERjOLGr|=HlDxb6lRy4v0L-Nc{bqs?#NaxUn%4~8Pt2$$4wN>qN(8%3{Tt8 zsOZ{~D+t2!B#aWx7wx<4MrwAl(gRcf(FtK%_KZ3LKN1p>+q_t+5^+B`oNfFXR$N5l z0ynvUrUzhDIew;DnV7_00Vq+pNlste!3ck_FffVDCa0|vUB2NN`wXPnM^AFCzBrkF z4?2mi^0Xg0kzk`RqFL`%WLCty#Q)awtqC^39=};4{^E@65Si?1Dm87YeO6-{h-t+-ceeBiPd}#y^6dJhB)QMUK zDCH)$OfGG9k-X~I?yYT+dd{0c=Sj0KD{{X2w5xqs3zzs(HYrE%xT;{(@A1q+jZ36~ zkK<6w+mSnRC>uwwErF_vEV&4yU9eWx_x@kQJIaA^%;rzyUMLit6x`#G*Vt~}-TTz# z=+3(v`8$~K^k15&X)nfGjxj@O&XU$gcn#%VvgI=Bm!&4aP4_(>4j-d_&RjJPKl&F@EM(cUs{I#f8aOsdLG`+UojyZtM*v*sO*sWSi^d3-O za9-RvQ1X?WRRp)$)IxQ;Bb-y9&{J*%<5wld!L#3}dOHO)>LQKh=q?QmmgGfZ)WQBN zONq^E`SKhJiv@#`qSvY|)NqT%Tp)|pJMc2{f}E81;ILB6B*mSueu9WM*S{C{e?&E~ z#ny-iqI1!0iFhzoumJjO;ehKP9MIf^pE=~JY4^$(%xSK3(BMkZsW7R6=)&;9(nY9*lDJ&#+X$DF0U zCq(-b({Y;mgWwqR1wqA%Nq%11SC{DBDig}8mE~H?9z;JH{?Whn_(`X83Fj}!7sNE{ z8+nB-n2078VTY7ihj>&gyJu~3lV635jPXE9r|3cQBV;b+uL%05V@~%c|2VI%H7}1n zb7-)ezez}#|Mldf<IIDeL3f7 zf#feF^Mq8`1hL7`m7^hfXWS}&r9|fz5nb*IGmaUs+9NWM%d8J1 ze^SW7RZc=qmuDf`a9G{t5!!EB@$D+>yE%MQu)&gKzD~ zB6T@5OL*WTP0BpMP9gC@T#>qBn${_zi8ziQ?<;9nuVuiMOiWl>Gfi^f%0j#LJm?uh zjJDNr;kxsgZHRi^Dm>&-aw#9a&FdmJcx{kzV6`;BKp{!|BTp0-_x(9tG7*tY9MbQg zi%iojq}+M_gpMgX{BNLW|Nj7O|2MqKr@Bdj+Ul#x4$LQ+Y$f<)gu$YkSPtf&m_@m=? zmv^sdn8RX2GQYBV#vMN8ooR4Muob$}r=8X64b4w;b-SLmh6P7!{-+Pq&Ax!q$#r@_ z@O4a(&;{k_l<3>1coEl=;1%&sd08C%HkyDsZSV2iz^KO}kKbWh_dv*=1&KLai0j=- z-NKIt6P00kpsPTe|8-iq$kP(A2lI4VjkWf=+GN4j+Ig>zg@7B%A300{ua8pf5Z7e+ zjysDPwH(YfhOcPIxZ786RUCfvs;vVL1)dC>wYA*k>F`d&Q+9A&j6qLmO$MwPZ{t5~9>s+}(Hms$* zhFzIl#w_jYSL|1a|A8Ob=!J^k({YOjTqlo@JM$hF!^C%kkqDCqbk1n-nNgrm^;_Wa zlnbZc=YFWmSkT5g$KF^*?*rE8`8KoldXDREDhvU!QAFOHa&ax^q>qx|miFKkxC)0)Zu}R5e>&E?d>W~|Pqzfv(la0oIukdypxptPwY_iC5 zAHx??0u6mogRi*uyk%C;NmHr6sSLTrXLt`2^*-iuMZj&0_E{nfU8sZCS&ZI?)TsjZ z)Q~ivK4fV|LyReqdUuFv+AA=ur$yP3Gvsz=u!;jC6`8yqV#~1hW$w&_A00-gAh0N1 znGS!~xvqFNqk7PNPw}tau>v}~!)aDz;_~PsN^ffQ9}Fv;Ti%OmZtIhpED6BxcV{)tjD_ampM`y|Rq@IB+$7Qja~cTypmR>%*;Vr7{Go5LM=vAY)lgkNQfoV7cx8Q1mQ`rJw;ij~cC8TO5#XAFL| zLWzr|D|O)0qxCsm-S>R?AXiLw>+hd{_&D966gySQ5jG%}6ezW;(`SjEA6M)oys=4; zAUZZXicRW9uhvdBl0c?nzD~Cx#M-_(I1%{xJ4m5ZtSX;Q0~vces&t=haL2|k9rFL} z*{G00sz@N0p8S8j(H7SI;#%y}nGnDWf!o94kfaGpp_>zZ4lKeQMblhAhwSC?y|>aN zmH3AXRZ-;{ePPpF#l=&t{EKnAVuOIy&AjW#%4xveFbz17%1csT6jc z8{7=%A~6)qj{o+gbR$>U=}({Pmp2pgOvdk_o=eSvnL*@Xdh9Q}4`;nGj{-i$u!-o` z#Htw|3ifuBK)M8~b5$3T+_$+?A0sAH^1pU}z{I22>Nd%c#UcQ=140eZ$y%@L??xd}lVHOZDGEW=43m=%6J*lMKnmm_U-k?eNsf&A-WydIqgwBs zh(gT2x43_Sdn{DUyOFJ{_I$3_?a;9cMB33>V2Nz>B=6rM6>G5YAa&H%H)0Z!(Yw~_ z-3@MW=AS?15{lj#m6`e$vr)PYf?{cNyh6^;qnlhe%*p-cUjW5N{>D?5f|XLqHo?G0 z-)06ogt=Y`W{$ut()>zK_C>CIiHJ_6Yf^ozMdk4UrEALMS^)SvH>lwILN)rFz}i!^ zX35v?q|HVLoRZrI0}CrYE!P`^*N6C+klaCY$PvjjGqB0+GRR1XaoL3mMx-+AWZ`Aau@aS35<-1 ztKaryMYSyEpd$if;*97Ct=GV4zdHu|#MPMg>Yjq`w)hg7dm&kMhXvBIUsbn{WsA*xJHs_)x!+?>~Xlpgms6~@33FFgLf)Um1dkIR5w z0M?m99!EUyXf{SGNAQC4L++(DF1e50CB3T(J59=vk`5h) z;y9hyKg~i~&L^)GF>r*LAqws{w9^-kB}v1Xr89IooUPn$w=U#5UTSXsT14z3F5_o$ za%42!>Dc~_{ea2LwdXSYkuXvV#n)-$z>^iC!9`JzSkte8tp})OaNL_uzR?m`L7^*w zJ^|;(ysdGl3+rCrTOj`m@>3~=GDtaRkd%Dqowzm+t!nRG06B2;C$H0uf0ON;@~Efn z((Ccl`zu6+Xx&%!T$|tF{s&mOSKJ{NCQ7a=>setN2Yq&Ma`%1>hQKM8(aGiF;9s5V z-Wv}d`z7pG!KcCK)<36dN@UBqQj)$^Jc0&Vm0TChr;W=YRwLp_QXeQGWY;&0?%02p zOa?|`+jkdfvn)nPId($0B8Ho^u4G_VzTdHf6d0Q~F?XF66`H4(F@uxnKb$CVPI`e$ z2MKPcp0*pT6WT~sV#R!XY`v^NWB)qr$3;^A>Jpy-_u+gE8%Zx}#Bpf9thL==pQT>! zxT)62falMriw*L%9q<`^@z#;>`23X6`W-I0&}Nf1Om_5{WjCbOWi7ztXPTq(Z6kT$ z`7>d6Xr$`H6lLlC+x1{{Oh_62p@1ZMF7JTdtbov3!1eXQbIR_c?X7J{x)7Mm!7*i8 zx6BmQ%=_rt4L3mQYDtG9Bz@Rj@TUSv#it+%Ym@nUqiv1$O3#xPw2sZD8Rr9xu`>>Z zcS6Vb-mVJ?)Jm!cvxN2foa7^@Rd5=>IrCrsB@#Benl13kE5_WXvPu$q#C@*`Jv zK`s>+3)i>N?;XFgum-4IN-SKlYMz}D#>s4iMGP3b{BR;y5&ot|4>BiZ3(9}@z!$Qf z;+Eqw`K(=WS$tY9#KYsQH^`T|NRlqc_egqJUko?lo(v^9k8Me zdrqg9`i;%RM9}#X$R^#F|J6xSLZpXDOuzQ^aAMXQgfGR{}0E z8QCqC9*X4RM>K@Reo>V6(fE(XNXrb8-kTlS2SSNp#G1AWI;L+&a(Mr5yswI~Cyx(R z&!W(`e$u)jgI(_&N@4Mm>vhQO4sXQg+M~{NU9a`4Lm>{vXy_}|6BOtWA@&g*Y*Jol zb`{983Nb?QzcOxzO-!nv_gHfA6|>vI^Pz=K z6W{+J@}5o-8kUyk-rF&5SS+of88S>S?b@be)L`;?U?C_?%(ObTu)vV+Quf_7WpETO zlG)Rq#nCY|v^|rx`;suX_Hr2sw+>JJDYS!giu567@)>K@OyaR}Nkw|4#`N^iaye=+ zoR`~hMGoa9cn(jOn+>w0(R16hhMgEmAhzH92Lb-O7Grg`_|Ms3QnW5tKVxc{1k#2_D9gBoZ6Q~G=Nr^9ZevEe68KyPdh=H&WCS~5ry{X|ebP>oP5;DJH zOe>|E?m^zd-M+y3^(qwUw#|8ZFs?pFGxZPC3huUakymI}ls>r)=~O~r2vyP=9w|z( zh%kbD5d)-~ew_YjVAKq4SjjJo1&k7M%JX9Y|JFdFzzagUlDk*Py88A<6Pj(pBHXg$ z&p=$u;9yf2XyG|EnJVJ7B1nY!rvIzxuTXoz#%ustSR6O#ZPlcN@wn>JeG%^dhX8y< z++Y_%#=os0;`JF=^&oRw&A~igJPsy65-Tyz1+}HjyMco9`D*S?k-O+!WQRo%xp^`t zogMP9f+e6{tcpxAKWOa{pCBdp^Pe?&-@(J2e(I!`iG-zdhT5<>?F^&fRp)ErB&nBB zl9GZM7P;rp=E%}823l*ScSlY5rNTbs*k-+QkP&@n5t0{}Xii%|E2ZUDzQzF~hg6Ib zZaJ*?q>qt$Ga8D^7?JY* z!de#R8=yO!R7tjmR)1)A6TIkL%T#$#jhd}GPxrw*HviInf&^~~(_orE?reyG?KR1S z?M-A{VPnH)%(Oy*7m~!>H(?u!Qe9dGp)t5*%L{kP#HnkXraR#{jduX7>?wiJ7Bp`IYYI+Me|B9Hy`?)uqU9R(j-mxWV>i^Q=w z#Qk^k8`IwpPqi?tLH$l4(WI<ClBb5(o%~hsOS73E+s$nbVx}4bH1eVuKST;W6;@&sJfrzdniaBIcoct#oPT; zVc_OI^IS@qrCJWdgh^XkcI&6geDQ9dG4?5h4#69-*JqC>x!pT+WO@2OJ&$fwYIxW>VPMp}J&2v<~sjPLP8yV8_7&}MFIx5;XhFnfN|tb5FMM8n)XFNe>n zWH@WSEWXCLQT5YY4P&iwyZgX8_mejDc%UCth|gGdKj*!GaF-w}_jHdO?*25Wyv%u+ zEPvFo{pi-Oi%oittZW=< zu6C-h(}nO9RNi)J%f+|O%XSqh?);J(>%k9t`?Iazz5dP0WpEoYaNl2?b{*aH2O^Tu z6W;P%=6F&^Sta&dEvsl3f3C3dUe!`g*r9gcQcg`})~K?=U|%e!QB4OWyfWyMmQ|`S z&^Tb6^(F2WX`0jegEStd)y@|+d~VL@g#CC7x~>j5k5_!Xi2G@F;xhqh`!f<5au<6d zkFQF-zqfTU;QXuwYYDCg?E=(q5b5642Ey*KRH8nn7s$bmYU=Tc^qicBCYuX+hm>hm zPR)Gad%c7CT4sC-{-lS5BK?10`=N?_u$IDR;Ne{6tnz$`gO0HK{kP&B>SVtWjreSV zoerWY31*FkF*-spAy_hdkEI~1>6a4s4qCN|rDa&p-2h*cUw=@gQFli1<Upk`)TcDpNM~hJEgiw2gxuL# zU44K~7yxcyj+RUK77_Q$0@WohxdGbc>Snj6A?vz~#lUFwsvlDOjY7Z6g=0+~J}XTR zXjQ!lxa5BFEe=^Yymtm+>&a%KzKYGWq#pmCX1H$xffDP_o9l`hc4&l)ATh|u%-H%U zm!Pd}6~+r6EjY5s!aJ8KH0lm0l{7a@Q_p$Ng@K{KC?KGBz{F57=hQtFJI5w&hJ%wh zmbYdDGtD|HqzbD|Xu>!ouQ5E^DAHrE+%9n~FZL32S^c1$E$DgAFbeDoG&}+Rp?gT* zLi)wvCK^%*g+e8K6OJ)mCyTX*)DRvRy?0wW@syBs-&N0gmtogAku|N^>`|l}X|tD* z0&;L(@l9H8-Lkf`EkpF?CT4J&sMKZ)*sNrzv0<^8+vNxLiXq3~z(0w&7x;VO`3tkl z|0R+|L0@XPM9c42lrar*zEh7 zETMjZ-NX=mdWp8!7gY+PSAcrO@F07U2a?SUHOkB0MpJ4DKg~?xHQM{-^Yf}dq5ltO zZy8qQ+O-QyOB*0vBAwDDDIL73B}htlNVjw&jij`6cTc+aHC^j@zW3KYzWw@3 zJrr){eZ?4OjktmM{-eXDIqMnoG5Gl6m`e9cIVwGNcI&xXt9WrQ@3xq_x%Ef>V*(Yq ztg98jn!}{FdzH^z-Z&9$%4@-PH|vkLF`6ry`E>~j0HsDT2A+5oA$a+pjZQ~9YAA3E zy%2h=_61(&BErzGq3o?l!0tQmJ;Jnpou2^^;->SzMNU`HmrDyrkbvNJaY*GFj462^ zgr2J-h6GR`xwx2E8DDL_b(Sv>loqJ3B zK2q4%gMrkG`Kp$8QaRl7qu}^_N1iR*T!Y^79~; zgbnHrou8i^?9cNbmFzCtGh;mpPreawMn|MI?Z!>jmVQUG_y%PUY;8{< zJp)YJi=|T$FQ&2#P43x=E}l`aOMSygIJ*=w!mx^}x^0~A;!Q8&3lPzI-B=-00*20||K&)m7Ch9KQv zjmCS8BX{@6j`zA2?{6d@eN7}wXKRdx z2d$Om)~IyJ0E8_CF6gZsUbRK{y`>1h38^00#BJ)2Tati`skG~6xjyT>d}FfYrSgi` zVRxUp?!f5R>e0DcOrV@L>gHN6;_yAldbyk~(Ik^4qOiV=XQ;fob*(g?mXnl_iDlGr z@6+fE+KVLMu%0Ca2{Na->3>g8(p}CzHAENbce?mDW2}$AozE~nO6pe-e!a94YWF+0>UR`~Ic3CUAmA*Ep+McbO^25K zeTA9*v|4{UCrJyVx5PXk$evoP3+3jG@} zRP^$0(O1>K9gVVh_N0N_uk?S~oBy4`>A(Hb|3)~H zBX&F7B6q{Dh7xj4aK$ewK5jg;5u|065YYAhzLk?#TGw+$0~+_@bqV`GspA;leA;6k zk@1dydbeA{B!gV1@jO;7{V{)J<1E|!l9j|k9flak1K*2Sh6?8Oi5B2C5Gi-pB<>Um0*8a~DRNy0yE{aX;A z-^CO|>Z6+Z`2))aofM&9k2qf5sH)FKaee-Lqoj^|WHOC;Zs=_2EKE8BuZF}NJ32JLy38H#c%;}X^N4(qpc8!mm3 zDD3A{+s0r6zk|jG^80(_-aGZQ{sHhf_pe@2oA#_$bJ9txGU^m%WSs@TPF1XCziuND zX$g2?K9zS)a3-+YKQt7bv;OJV_Jo2!xkioR5njhHx)SZk`x7C}VCVsj9Al=M~|Hgam zPVulY6Yvo6c;2T?!ILD=HeQaX=9`it3BbB2imNBYOYrXJVR8+LmYUuOMd`(kN$OwmQ3VY01?SWBuCB;q2v^~cc0h335 z*}1+^Lw0n8Kyjnf9`t0SwZ-phBuOV5Y*dzCrE*JyW1u{{B)A-t4*?dG?usCxBsFe~ zA7NYEFZiqZd{|Ek7>aYP78>Qef^G)BKu-u-eIpvhqJ{G3f0bTx*e3J;{?Az;^pwp zB4681gDId_fIv=1Qr{w}6Xdq{bv#LuX*d*1dS@?|&@Mx0mP zk~FpaIe5Cfuc}1()Npm3<^>LpUeSo3M{gKG`N$JqJ|=~ zoSGwvmclT#b!rMBUG_nO`R#+6wET*K0)9T*^XXs>s%;qUu4LD<*1LguO;?V z;~zG`CO=uZWEOJBVlxEOVw#AuhJE$Vds|Hge)jMgLIQ7%f1<-58Z2{ESzXnYTKsgX zI{iG-zoOeF1Se^prrV#bZ#dg%X$#}KzD8-Xq+3I~+gkWQPq^ZE?Q-!B^VeU1@3_m~0rCI)ZXsoH!;6el|B+N=OT9=uf8-T+TJJ zW^yPu9Im8dmt`HaG1N^FVnU7eLwB020j1ak;VfUZq9>| z{S($P{&)6s9BoEtt-RKgx6$&Yai!mSCRATBrIs%#L^H?0`^;L0l(KJH1sGIKZb4A64BrHNkBILEFszgG%`w@h=4f;LiyOHgTRO?HzM7t>`TUJ-PUhi8MR^U07$Y>n#K7dX{$V6tuEe;Gl7rVY3nh_l?WAw8n$2MU9W33uId zq{`jNri|gKgW-8ZS7QE;%D+wK^_hcS8;nKNswt~4GZDlRAv#Zd$a(479X9WaSeHktL=^`j}>UZ(w4?#=Ss* zPBB8ekJAnGE;bq8K{{Q-#)QCdlrsGwY%ohs-X;0@o2q`Ug13CLtq?B5i&J0_jF;gzpA3083o$qpy1~*M9!BaV?H-kM&n|h{9rowvH_Q(rZq5+)uY_`o^+Sr#C`Q@7&~^z!Yz^WU79y0EWfCa=+|R z{&}#iX*PP znF6;go-z*epKOf8h^MZBkQ)7A`ujt~a7>n;M#f*Wjv@YX?&Cp@FudGM`ZZ7L?p7HO z=;uj2(8MmnIAckwabn9`!ggy50^oSw_r37PuHBslURAS?|0* zRukI+gNi;|XQ^OY$K)_3#%PN9z~8w;{yX7kd6Oaf8xnmc@(vQjXI-~7tkL+~ZYA-T z*Tde`&Tz)lxS7l@p4`ArgITQ-5I8_j?kDJ#8RpvUkF4Y2L3B^})E)16A`Ak2KOLe% zAFe;PU|UH0%tW!ES8Mu11BQzP5Rf+L0i^6=fu>OFNu_X`=En^ty!t4U^@W_FbPEvf zCLdP|IL3NH?z^?+Jqo1>p=yNK=lxq-ZOzjpk?we-6L4tNrZKwbEw|)hhk63_Qw}UYCo55OqHVbNk>2gP7<%P)w2mE|kWid2d6(Z-Y zPtNj_*yRyDs1r=;VPS;wN5ap;GxRe%J4$w~Bi|Ll?ZbIrDbXN&-hjNIAciXgM{Vdl zX5jFP>wp^Aw1kEBa=oV6Lh)`PBmzz=BV2vE0FLoNg{a>VZ4`ZH#ymh6{{zV%nCVYaj*O z6cYXOgQb+xdrJDR#>Z&uy%XFy=w|e^^bch z%nO9(o++DNU&tmq?ib9HY%fxQ+A-`x7Q#}Q0g)Q7bGVZCNU3s&d)0{J6$(jVMyN#3 zX$1|0vMiPwMH|nzONl-)hrKrDfy2VU&)NC&1M^AM^ZM_KjlQZRXlzf|bjNLzwz8N% zIvM!Oy-CHW&K8>0=cwD*L%i-KB{scKR%z$Q@Yz6vgMAU&-Bbxsu4mk-@KqEo*-dOY}fSNpf{`$oMpbny3bxBUt9-NKB-9 z<7#dj*etS^iyeiXGnLNPs*-IQ`DKf!;`{}{Ac1r5$(P0e{y*yQwhenB?PuW{8t!Lp zJ5dvFZ-1B`Xh?nR>y4-)R1$pzKz}!JH=}h4DCDd5eN(wbVH33N{w8<0{iPy?Of# zGy;C%4PMhe`M8thI68;OE|5`MM0ni%3v&!1nZuk?$Ng+#YrnpT1xLrNp+vJmhQpeE z;d*AH!W(L#UJZz6;L%oEgd>`U@s3D6=)*8#+n;}4If4i8cg-CYvllz^ zWb4|NCvj!*WUaU6LH}ol&Gjd{rC=$&6RyA2*mRJ&ZBaNNx_L=fa_` zb537318m)yDh!ByCo-n%2q{p!WbkEf*#z@;EawJ7jif)-j4#TMD6~Z*%1puj%Fppc z8+Ra2pOp)?UiE$LI)30>=$>^-)pHyyZd1Y#{aHg)_aSanm_7$0tvNB9%H8U-DO+)bTdf&R0E`uG0^lS zBgt18%kC^z)$PyKeXzRkX1YH&Iqf-rpjZISBg@^Lf~NI8KUbp6%9h{THMZs~Iqp(> zEc*$Huy@MSF`qGKp>fap%2UQaR8{v?W5%n7OPZrgb*;RcOsP;>4QO(+KhgL zTz-+S9Cp>A-~d*fkV?V_(HFA1G#S5BcXTF8}>^ixZ1~B7Xj#2!7=z&b~Qo>YkKOLt6O z9i`ewFd40v8r0@^YV4`S^bfAU#X+wKK&S!2_>j&#nBjoG@`1uo<)(z>jxpAM+uw24 zIvZUAjIgfao0Is9keGZ4AiCrK3cQ>>s+pYgL8nt%hAJJBkSA3BYp$1b%h8BF{+!Up zGy|P0<9YD$DybP^SBQv$?QDy!IPreG2uO$h1xMGy z+zV-jOFIfz<&~cdm$|K9woS&&8Ju@W9>|9c?p$1X3=laNfAf3UITW(%EBHs=4fNGg zo&FS-eHHfXXiS;(D;m`A^d+>&lUl-bz z6x6F<94u@BNxmC0#T0$26J{p!#^$DkqFtp|WKfHSMy1`3;(b`mS=O;o;n!C=$o+(+ znoy8*GFS6x#_znqB%{^K{3X5U%#6lo7(d`pK>rCLj>jkXr}T(pTxcx59lhhb_onq3 zL+pm89+Bm9{(m47PQQLUn)}(#TAhVK!!!3>6jT(W+bM>zQgQ1VT7*vOk0A1R*PGg5 zC^`2gf%wNI+7wg0$cjCjv?g<-!(O2(_x?5PrYm(=#r(`NPU@f2jUIK#VEWs?0NcBw zg<_J-FUyXY#j5nqSfzyAc2`knAh(&rQk|*c_HuWRR4js+4msj=fb6z>S%o$iuvyI< zQGXopQZMOO5EAnB5U`G5ny6e>dGXYJ{wf4tH&WO0Q%}P9r=3+%IhUESZiPy*NFu5O zR-VsL5Xu8X#RcFXA$%*H`gP%h83H#yPIWx zyqJ-96*;>i(Elq@lclBLd!&TC5Fz?7z${El@Hb(k2)%f9uitKqg}y*(>u) z4r#u-W3A+Lk4$yE;ASzNcX33zcvsg36ey5g)Dfw@GlwKD*U+x+dlzapjQYiDFMs|> z|582Ihm2jXdj^370K)X$9U1Rk3NEL1c)=mvw%+58KtYouN_xKOTrEu5rDs$NzIV&A zr{_ejI?kt-ayQb$u3asciypE)di)y3BdKKOs-?=#w;u0#>Gju_BYLHsdWg0}UR&vp z8LnQN?l#?IfQ88&^TinNhh}>CpF(LhaWhv{{#(-`Hc2zumRt1Sr?BI*IntKmW^Rxl z;-5Cdc34cNWW;T`R@JJ(mZuqccb>DT1$zfL$lyHQu)X!3)l7N`5o+fdc? z?{|rOE4twC&pdj+*^^Y=pTJTJxs+ud7rbGYiZ@BW`|5EziIeP=no)1s&bPDOhZ%}L zY#hKF@dE$d#YaHFq(Bz6%8O-!)9uSFwClupoDONvcPR>lgX(4Y_`ZTLuD&D*HWTvn zR|8+TZ!d265h%YaiHjR>zt;QkIKTCRSX4By()M1n=4l)bHQni^$6vWig6>-lu#2|p zq+DT&31Y`T2qf;>hoA#h$Cuo)>LStQe180Qd5gJ94S+kL?`gor z@56a8RvpZWd&}l8$P#pu^}Z1SeXlCn+zT^y=P(ipC4* zW?}(II|AM0_y?}gU-y?qFN`ik0E2D^?+gXU+gUp6)&K@R0G6P-;#D@l(fgO;Po~nOLmhpWDLf4HodhTn5z7 zu6~v9d$QG}5f^wwo=e$VfcrRm+>|BwG#?Oh!;M?PA;kT)tLPPaRAlKNGXB1^-|hbV zIHM$Jf{7|?^rvJ;PX^pU9bT-6iw->2#!1gky1RP^$_8cbG4#pi zTUeFwIjvUzjFKhc_ z4is!>hjV%yR_ZvA=`Vl0jmCVKYprMK*C@3qQ#i|}^(0=G)_k5GtKJ_N9@BelxG&LY z5XM;FG`(TMWtC&Zbyp~K2hwdw6DB^3vTC_{o&f>r*Z9&gw#YA-%Qff;_h+sJ#(GI3J^yFL*dy}k34yh-GuE;3n z729`EVvkG(?SGT5ROrOSUW&0SyWdv7#n0`v>hc>WGabbSYh=iIo`FHLcJ-^IWbRKM zaWs_{#^vsj?>%ATIN~V@LN8Y-lM|9v-HlMg;jAs4Iknk#_pDoWAg8Bi2V3nw6?k4! z=@c5gAOAUT_LE@t7TgNf#+c$WjSuk|(hF{m-&F@Q=ND`S4l1G5&s+<71Ux?b=4+_Y z*DLt$_KbuS*k+#=SDk(Ooh3omN50w&48>#iBZgMElDD~j!pZt%PkY;Av-d&tEd1i#xSqkF=pQGSS^*}3pNEgMmDXW-vJLl% z4-cS1y-I(Y@wp}JsZh0?b+HMFDuoT-Z$obn`As#&#vm?iQox&qb7FC+o$OFO&;#yp zdg}#|DZMinx)~rpDjf%m!AOzcWGnJ}ancDl+O#Bf9*|VA)3cY610t78dpX{@02Uj_ z*Zw}z{y#zZs6y+u!oM&)82iy1XeZ9sewW#vy~zL2*XcG=592_|B{H6K6utDQIPYChesZEb z4?lF@KKgx>7%^%IfEoV zeBo}mK~_q=?N~uTJe+%z?qiTVoa_T-;ka|%8<{oZ0h4l8!}ja2W2DO)bo}k>IOLF! z2X~GrIAhY8;di`uf)Lx7D(iBmsO_skgGFi_w%IT_qH}jEs|Y>faHZtk_RTyIWcWMR zYqL%5g1S5r@q9GA%yCgolcBpJnU<&TYxnS+x5AI21Tfx-6JaWE&3i@hJ5<=1Crvdf z>)1@wDFyG>I`+P!AbPV)*xz0}oFzl{Qc3milnGOAGEb+(S^-`@{kk85=lS9p{102t ziTOn^tlLhk8~T3btIdgfR@@?%*IKW`SDxYzo17)B`r|c&K z?>aX8H<~*Yhb7adIU|&P_mvBQtULJ6w}(6yH)4EWA36{9WNxdEV4P=tU3<<1uopOI zU2Epv&byxX2Raai_WmDIO80O;yyu|#(=FwGmj&hsh~B`f)A86>!wkIzJ1GIfQs0SP6&_RlV4*Y-BG`}R{`o@sqc z5-%LUdyJ5$gP3W_J*~}J%XCYG%D2}J(;`grkeXc6H4f`wgh);}q$!w?XUEXeGG1`9J$=$Y?Z;hp)x4a zDR5zy?zK2xyIcyVo)?T4&uK7BD9goXGA293LpN3^xN{-SBxhYogu%*;&azmZUKmCA zhFKvycN{$Y^u+6cnnL|j+%@CqF4%1LnO=Sb#tp7dTk1v9NDVxj)n7y%mPr8AklF+c zs|~lDm(pM!)ow%t-Jf)^Ic1D}A=ETZ9)`idehqUS&=JC6whH7)zumKDrE)Uu zdw&KRQ8{ZWU>IKIDr zq&m@VYCqC!<0vOU zKt07k6Ro^xx+KvFW$|=L1tfTH=)X^hN`Wf3IbaKc2T?tY8CBRoun7ZURWMicheOEU zw-oY9SzWoP?cGH|(AS85)kalDCcI|~g%-aho(Uk5D+@Lm+R~+Nkg4@pyeP%y(KDYU(nU_|UDsmCnz$BI+v`^u96`1%0>@DO_5Xk#sK#3gFn56L9GHdFv z^W493c>9kAukL&&D{fyHVYA?37!Bb_N72{ex46gtLb$Hz(~$%(sd&ii06y}GD=iD= zfU{LjXNS`!Gw7?sN(TgIeM7W>0~vObq)BeBevZE%#t~-)tY0k{T{tG=xkJf#m~*r_ zB*9ECYVGEJcI6CgiM*ixT>>Gt`wvFv;qr~l$Tq-n3J##x2LuNWa7s+!AD^MAPmFFF z7}SkxD|nJae2^27QSV`Q{dO*4pO)S6E|8uw48+shRbRdtqT_MDv#1pMxCv;YvQ8$P@DoFj zh#FkOML_SL#^pmOkCS)hWoMDkP%7JqhRgPT!8R#F`nx@p0Uhrnh)?r=+;jEr{R)Mg zKcOH3{@@mM*$eOo<0oxJhyMdr-*tvte_2Smz#v<#*C^{%S21dzhbsYu|#v zrqWCBVXLYyJ^igpsm-A=@VZ6E9T_(J>09G?F|-v2lI8XdgLFZ^MD)U!?K*9nM{S8h@h5WH?!iJzlrcaHzY zoy4bl^ql1cG+8Qxy0F2VbZePPKK2B%d@hn?5gI>*nq9Q&JS80I3&U`ZR=REf3MaWf zcY1!I`vm)%dmftP6vA#YSWGfV_Ja!zXSpO#9cE+mhX6nBc-?_;*3XrAtvU;k=kx^O z#TIoB`WRhW83ytY9CpV_C*Ca^ar-wBrAMbQ;Ap*~R(gVpCs+5uJgrQMhCWUHr|pB$R@nmEhrW?Q zzSsT$*V<{vyHr%7R^~DwhO?zk=9U@-<>bV-%8xrQRN~P}$HqRLbX>b(=0~R}O}5a> z{T#r=@&RCD5ib@Ry}j4Fd;1nO1wpgfYJ;@&ehgBi+nh%*9?uArqD3~Pz-EL=FKd>Z zeF+PLU_2=LQW=JQ2T@+pwvpGT1I~z=hI_{Q1z#))UnJ^O-2>dnSj7`8zSOBmcP^SX zwIeUL7pFp&i0SA)=a)jGkj7|oR@fzAM71UWtajOTs;m=9&dVDWq? zY%4}UAF*8`0!v0o2-F$OQUAgEr8a9zjp&7ZeYy?Pj~Xlz0+C*2f^K(r3&>c{y{WTL zl%fTH`1z@1+vF8P>)jiY{>AorZP~S=je$vY!9rg(+gmLOtP zD*`NvwNSePw4k!kY-``rgkASJ&cw}5XFH|wgK`H(ia@ep@cVEkzZ~O61%djtx?2D& zP>ibsiF|dU#bPk5zfG2@kb*|*esI)@;E9i&VTnRkJV)f_mZYshbWWW)6ZFnPM2~SO z#OSAuZ9YxAYnS>`QFPPFLeCDx&-4ADfWg2RkZCDO`x(o3rxVeCSD`fK#vCw~7u4@Y z{=`s34VAJlxSx;mHI?#2KcQ2%vooymSi$H27~3e~+WF1kCDmQ{-n5j5M>FHl3@#m6 zyn^L`Y7QwOJ+erUe0tXVIox8bcr)^FzUl_L+!RI0k zm~Oz_#y)#>fn$*IJbutmV>F6*A2r3}{CpQvjauL*9dXruFa?iASMMY5VZ#UP7f%od zs0E@K+hzpGx>#O!^lm-?D)ss>R()50sN;cw+S&HRwkVaXT)jiYE&2lV-mwFfM)9A1 zu%UgO0hvqZyg$V}srA0(7gUh$yMzTkzfR`dnoFc@1)u#FoXNxKFDiJ{;uqzJFjzFy z^ecDx(aMAuOiIvLpwQK@TlSACa44$4RHvz^uh5RbwG910O&F{Hnbr}2%<#{M-T$AM z*#)VDg$fCwMEGR}l&p#q`ZuzOF7WD#r}e|Azi*{gOJk+sty6|Hvb+bS zT%+O=zpk=!j+MNhl~Zh%W{r8A8?iyPq%~bylT*S;f^7V``LqzC3Q!$p(Rp*&}KwXfg~EBvV%@v+^9^-(W!FtYNb_Np|6Q+f!WU0DpOEfx|9 zx;BEzOq_SP)nWNKVQQ8bt4x`?>yxIoj>>Wf3Xynk$3aZ!jzbzoi-;XxtPC_X0w^_L zw%l&C`_tos*Yp&V^9tO5UGm+Nprnr1nRPbOx}%{%{7(^W!=edNjh;3viuy^*K~|6mELVXs29^7J)O2qWZy=gaHR6UG9I=toq+)0 zkHbWtF*Zz&BABDIA3++4o`>rXE(%;MDdBFj(|J(^z1CCI5d@wm_$yH4V*`L53VV_* z0q<)FS8mIQlAu0?;+m(uSGWVCKw7+U`axh~1ge+!uIExG2-fQK1c$wwggw`7=P_EW zm|;s5a{PtO+h8?A(-omQrkp7G2$4ep(DKW1pISRr3sxu79<&fU6QI!0J&9k~`JNy#f_U%6n#f%GhsFWm^s{l*eYt{iMVgz*bAArCx7 zf0N-25elRqXb`%JDQgs4bX{X_W2eKCXBozOtGMWKp3BmYiS=CFtz+g$nTWZ+Xhtuv zIkLgjulWJ;^+q#7-!+gvlhn={N(@W%eeI|aG%8MoSF-AtX6v5y3jsc%+vZR8SzJBUsIm(L>3i4d{53fs6cQLd($1L1*m_XbJv%mHat#!} zm1tGXf_en21*)wA_EKj08Nt6~2UHU_YwSQx;m(wOA_Ao=rERg+_!zW^mj|2I*L!m5 zMO^k=K$T@zQm+mnM4-$y3w`7tJ};J9PE787xY8e7R(8IK(Ur|A-!NpFC5XNqrm7psuFhV5e0ZMNIgl#d9xSF}@T; zSx&Y9diTaxk=><_`PysIdF+QY=dYm|rt{s&n1Gv*A{jR8QN^ipoi#I2KZF8VH?6jF z@yO&Phg>gle5=+qD?CoGY)w;{)Slg`G7<44hsheZ5%nmWkqg5Tp4wYds+OJ`#Cb0n z^*(|Q5{D`IhCd3bL210gz*idgEto*P@YQfe@lJpRD7O+SE!tP%2WG*ndCB7HsmhNt z-!kJ%v$j%;S#-d0FS{j3#UL4uk5KbPbS)TqePLExsE~4PJyWGuuM!l?j~ITUyIpS? zlidLeO*LRMO?(5y62N0sEUa1kYA`7m1uqu%_YZqDXq04+{dKH4v?l+Y<{O7Ng->lr z3REf}9e2Aem_mkH{N2sjDA!8FK7-V%#7t-Bc9;(#o3rfO)6G&ynZ#D2(x6C*I^H!L;S<9#cVxp&(%HwsQY@(F!Balf?5ajZskKRN0mtQLQ335f-P{e z7H**LAdX%^4}~IFlUPv7?n=e)c~!%=ORM`%d|*?+A9n>YzndlYSMO zr9V}yFZkR)?8tLjs3p^-z6aX?*N}NtQR8G&%v_*S{U1cDHMy59C{rFbp0XKb8^$%-E2$beX|pA=R_{%j>V&bD3|=Zii_HR2 zq`d2Mb6NB%IUNBNVKV-|3bNP!+Vft5A_0No)72LRH#w5wz0SAn;3mkMpQ0c{2ZW|~ z#5Qh*>0RpQDAk-9Pb`d9k@UZPKJ;hl8p5;Hj{H%CYXl=T6}x8@JHu+Sec9d_B>nMY zb~;63MgkR+z+>1ahus1bn%PA6WvE3IzISACpWgL6&_spISJC-l`^O6sJ@M7m)lcG^ z96J-aDNvHp?bSz8fhSX}sZ6Fe!64%gi>leh`))H#bWYFKHX7=Bd^8yG^&tcsnbfRw zoSjJin=TOdeBSVfTn`hJgIH}vsPf}zr7F4;6BQ>`q5jF(52y1`#Vz{T2cHBz@bEc2 z&xdT^{rA4e{G!YuGK@zCb?<}wV(&6L`}NLDUEB9TLJ&6%i^u1XIGFTKN!R;Y6l6{) zyIm5HW;8$QC2<=z0<{(C>DKU=yS?#{16De@+lu{Ex=vAjiF)n(PK()+BoIk0(V8J3 z4y=vwFRA4EH^cXcM9W&~HO@Q*1@w1T1MzXn;?2xhKmcr|`4)zXA7kSg%k^cOZqx{W zGA)=7AXBt7Qqs0b&`3WgwVhA(#q zV>1D~;X*mA+nz&-WklED|H$^5{}H8pbqjfJP^#IgjcN!o5BaB$eKyQa^U%Hauu9A; zYC#p$(#X`W9;zQ`zL;&)wE{<<)!~LvtN|{&G5Wz4^XR|lGeAL>V4+1^>aW!2{i?&Q zExEBM)Qa*2z$pac(BFV_1my2}F41DD`&V?CFm=PwpBw1KHdHv%GBJ%f*LkqXnbFQD ze*s@1D$!1iTB}0U$YH-^z-}2RWR$b|=WAu#=Jd;7(DNG$V1Efb??vnNTeS51lM}Y{C2vD>rR&XrYhI$}buv1{B&>1+ z0nv+E0&usAH0FQJ_ROdbe5sDLFqd=xTZa9^x~^alZPe)M@1C=an@V8SpaUeJ(k<`=m+T-Oddu*5$Wk%T>qY0qywADT)X92IFy z&<>%gNx=4ZO4M~Rgtp!2SuYTckV{rSYSeDX}M6Xt%ZZhJIgIewS@fGa!9~S{JR#(z8GW3Ss zsPI^spwYj&pYvkMunXt+XAx|^M@r8<1oZ%U?K1@0mjqp?8$-{e3M)##7T_qAH7Se~ z%-1<*gaL>Y`y4=|(!a*b;J|Ex$r+Rr`p}aX; z#=k}qtdsy#daeJSjjL;WSNtl(W|m`M)Ikv_nC0813lx;x&JU=XoUELAmW)}pOAMgF zQ_vir=vNF{l8@~oIY72L@3zI1YoBm9)`y2H7KYCN9a#+^mVV!PLTI4;An0?MuFMif zg)nWPxCrZS;{jk@NQ-D|{a5jI=8(Rz-~mf#ay%GxUbN$saI>y4bG^9axUd^~X&wQr8e6oCX3B!HVPdyap6T@$yF;09jx6 z8!u&?0Pi5Bx#ytb!srCy_-m6;&?e=jeo38zxp*HLPbJvs2R**;Be&%1+%Ig!7jQ^EC5wJGv^#;UWV4m}WD%IZ!8Y90L z@G)iv>9QkpUPUPKQ8KghQ~AJ)WV-mI1igpn`BU}R6`z9d$msj})K5ELre4u=2bw$H zxZP~wlax4Bc;R~YVb1@EMXeAbFf*SjX<&223NQDR4g=VPGO9GQzJib|lir2@O*`aG zJk9u=(Kdvv10_~hE3fT(q4P5tGD7^y=5;)Km5vnrm}l?1OT_uxYL^ucS-28IAWPj1 zYF^cd;ZV2Jmn;I)J^HhOe&O?v_YXcH*4C==P+&q}?iDY1YoOwM;1e39$83k}25LY8 z38PHLYe}{G{^X!nVj`6{zW{k7n_R-pbd~NYL;EE z%4zkV1tP$^cSdngf6d}b&dC2il)YtG6l@nRN=V0mO1DT!cej8@3J54I(%lV1tF&~3 zASDgbjnXaM-QCT3#`pccv(MT4oNMoY#4yY?^Tb;By2Jl^^+(A>E0!F)vL_su>yxvE`}j3}p%#$v#a516WrH=EG^n4@{n9AL zjO`0LM$c}9za^DnG>;Zh;A5j0A0|n6hEC8}#`3MiFk_~aegr-Wih@p$8NvxbCmTDp2WO3p@uUIYx`+(!7_*O z1hd4k{n{iZ*0yDy2{WhE+(3!!qs3Ek!?IR#Iwlz)I}D^@RCO*@!RL2_@LWo;O!9sb z@`us99sp(g3dKcRIm0f{Fp<;97UZy)m!T8vP9a39(r0M4)tP+!%ptCOanL_r-u`&^ ze-Njo=f806M#2AaDd4nr=dz&w;~6b_tJr*Uwdt0|eI^sJl;G3hDsb@SqYfkpYat?I z4SQ)w21i6X4P<;Y?w#y~|Iq??pj%$rlNf$?WG#&g7^Gd@u_6EmMKbJ^jR3MRP`%Dc z2Ha6i?gX;2?FCPTz~*;b2@ndMeH_$FdMvW_10V9@iqt6d0FiAp0+PLvz3q0eD(9TsNR(V_3} zS0c%|Jol(#JIvv-%DJ&|-kZ%dvTp_c(e_sy-P09vE3BUl^ZHVb0{5?mh0VDYdtxkX zM!81AL!zqz(x9pRYNi#DzfSG*;rlA{B9FjQ$Y963#Z%0BOvN;zt$_56g$knsta2lp zgBh*8*r^t^nSvr0)bv?C&q&+M#wjl z>jLRd9zVG~5~E#OMfv4YxZoVZh*{@mAT*$>*##>y?ZiGA2R&N^k z{4}vzjuI;PsHThr9El!`|BPMR{wfoIlM4I)fiF%Z=Q7r@tJy{#JHgdLiuF9>Pp6ah zyoG0BSyF#z4$5TPdz;87&ekW$mM6$=4T7csI=Zv@-7(XGYt1yG6N}0#>S}{OuZ=x5 zX>$QVzFlNq&YXvXIdi_0;IfI#HTv+f64XGVm_gRbvv{S3QJE&JeFj zfji>PaA)f!U5Qi7k z{J~#A`3WyXGK`2>W!MpR;l&7#vfKnf?61T5S>&H?fM{bovq_npSg;49Q1KEIA+cR4gljsqy?=eDq_H2{(=mBIASFrx2_Hu-A6>!wX4BclrFnJ-c z+IW#<)gMYjU*UNHNW5}sgI|aHh&(x~tp3k_DqzaZWRfC>}6@_@cVYl}AdcZ~5Aef0RL3K&|WwS_{{z8vWFVUjh7i;@{R z8_5jZoLn%j9Ew`qY|H!6zBi^Bqt6;B@L3M$(6H0mPu9^tDpa814T5-)?=^XvU%y5J z<>=%W-s0T!OU}Q#tPdSTC6=x3V*-sudcK50mNg)+BA(bY(@`9k9iJ63?j=BLu0hr# zKBwlV49WnE!q-4NJofBS5TEzS@$qdOL(Rjw3*;ugPr|oBBA;Vv>ZzdHJg8^aA-(3- z8IHm*0%=7z=hIh0B(JXg)<6xG))B}D--M_c-%^A2#EF6!>IuwEu@kEFAARYxT|G3= zc>x?6V)XWt$8D4oC0b!%@(X`XZ~t51hnhO*wb~}fGNv#N3~ByK4`?kk%lmSU$Okwb zj0a;tl8q_hWZv9wqEeX%vfK+v5WjSCQ(oc7$;)Hh9x-LPKYwWj)v6d(Bl4Mg?j@4{ zrhK29Be^yzqDiEA$ud&ra#G%=jWfBu+G=ihu(yRuGW9^~d6OcU0?AYU3V3po>4_p; z8aaHgk|iodEoWnY_wzJi#WdtDBt=(Y(rU8A8MQRVIOZrYeB2r#OVg_`ujMkGRPKd0 zD?RzrYiY{6HuTS|>{RI}0=HjUgL-IeSo^GbI|0WSn$ zFiZ>9F>DD_u?PH%p%)PTA7SYK3!7wiM4NQT29p$c)>X%x=|*vK#0w|h1zO-qd#(K% zo9!M5oSJOP;7tw`>b8l6Svpe`Hj%>P&1Q+LBGcn@H_j7FZPgdR?DRPc%e-Ch zUk{#gnk`? zAf3}W8a%YW2fHudN-T5ME}>jx8B;AD4bZ54<8+<01>-g~pQ_*8WN9qi=%hKhXs{S03y69cFxtDas2E`!{l}Wfn=yLN8Gy?O@8@uoO6Ko? z`mrh0QyH7@k|@{_QEQ%e*1rBZABU6HY{M-aea7D~iE$87pTksKU{-$1e+xDF}`ok3j8Sdqp=?Y69a z^iwdbAdUUqNA%}RzhQ+-Xw0;GQC?%iQ+8Mg7cQ?OU zKQDSuo6J+FA!RvGnE3UlNqqKC#dy5lxI90khTH6Fs~_nPXML(1J3FkY_M0yNcK7v6 zQ7FrsLwzmSUhF#5($9ATCbvtM(IK=yx9uJrbSU=Z_qarzsxyiXiU+V!FR5E#xdtoM zn>5c|+_UI^VYv2V1aIYmeS!E!lZbKEF0!S}d0;uMJyqvcaZLhq1emUsyc1XSA0S?j zS>UN{dy^MwGb(jSsrhM zS{tJ{7lF^6^2ssmf|KqXFi(V6)+WDM@pp%`d_jmbiT3IG06<`GQ9wNYA89(@mp}_Q z(L0ZU?7Tm@RK4Hw;e(cfzL|gF1rYhts|CX53)^%vQSeM)EWZTj20QF6yunQ-ZkBYt zLf$MS^NwfjODX)e(g{AZ5kL#Cg-I7tJVqjUe1t?8>BWS(moiDyVY3&CNi(P=Fxs=R zZ!rD{5Ewj7CZ)GL z$_>k;Mpxk;`)|L~u(B!{A%%YUd@GrcCX?TyLbZzJ0~-Xr7%gilx?JJdDrWlj&x=^8 zd{f2N&iaBS4(18!qREpXM%arKN1+OM8-j&mnNWKKkj*&yK-lo)$UncFY9o6xTfzJR2B zOYNnMz(~?HMK4o>uqWlO0{OBM7Var}#eE z2kcJUm@ucufPL>XsO~;7&^~W;9^Z%9-<-I|qY=BaoS5Znm?Gx%-zQtav*^ zIz@anc{4MsuSeVi=kXh8M7``LeVleun`3mnZhjzHZ64x|0D)Q1(i+Omc4>UiDqj4N z;YV~{OP3gK)weeDrIO-m6)Sm{KNpa_A8_RrW3#%4JJPQ zdy~Vo*5J38|Gz$+pNU*u#(}7{vpNyXfB3WVolCr1TD<1^t3P`!9>4}40;FIHZngg} zT=_GSb?O&MBe1vAqt)pkTMS!2*IL-Skl*{);qUM5O!~xMvTzSEYtIAF=(PCqY74$I zk}40v^5*)|`27#A1(0g=>`54wE@hGhO@6&{I~j|AR*)Wbij<2`a*s0Ug)<=b8&@e3 z51WJ6a;|*JM>}qA5SXutYQH=96_TxxBs67)?5w-zm?dvhv*rx67EBJTn!1gvl8QFp z+|DF_3Ki#i4C)?F$sF{0*fg?mn#jjHS*YLacZBPAekUBFw*lkmcV)XM`Fr#VU~k`< zNoM^j6B`t|B1jb3dm@}w>Xhu*Xfq#&y|x2$q;I=&INQY6z6=#wZnG2Z*Q!(#Bz< zh>rt9OugP^@3cNSt9FPrmDfD7JeDYmCrVlA#B$a*CJqB(DCco^2 zTa9_oF&`x)rh3q#|3(QGFvRym{^TEE_loOw3ZKr!)!IUhO}^9EIPU*Zw*0Y$36VJE zgzBBo(C>BwWkZe(H>gN)nmzDs>UBiclA!9mzyADi5&awz!AeaLgNV$K(urc}mi+G9 z%<}pgN{z`REsOr30Al~-9Hq@U$<|)wlCmA?_$)_}Q(|I)@QKU9N!z*MGW!`9or#aw zRffpAz=eR*R?bCeY^!j4)m;18lWh|jP@FG$P5SfTE*89+>n}8W>d{q9H3_>@` zF&6C~WlDLMhZV*2)?ReedJ;FNl1Rb}0)DfK8`Z8kmJl&DuZ1w`ZiO4nlICPHYJEl zhrtNn>g3L$L7z1Wge)icVwtold_XMj>sJ-ybL8fPs{p~|-%Oop?>@u@Abz0(F&CI* z-o>0x-1Q)Y($sr@Y@jbV!FE$W`NPK0eEc#M!+X3|S{@Srgl6%16+F;Tt* z+~%WzW|nI7GunIg2jD3VyjA*|oDE}|=P`vM?OlFe;W$mf-41efKi$vT3ZxmX>N=wk zdI@Z()h%@XmN*GVnW{;g7C9gHrf9$vRPG&i!>xXtsc~urz@{03i#dGunZTao+@>>p z>utPFHqeJVXz2W9;|)Pjim>)ESs*;ho0XOwz%4Ozh50@8MQJz=B%rmwM->H;xq&HC z?U0@+osIH~-C=k1T56%uWWds3)Z(>K_u(sbpBNz9hS(E3j|1(};yuitYOaf<|r}$61nSs_?kfU0bEcca05mmiYmCCP&1gZQ_g zq#PA1bFIG*Jpn zNbjd)*v>(UY|nSOGfraxIDhOyorIqnk5C8u3fMT?F(DPt9g)LQ2EKyN^Tict@^3U;Va@~tF3@X9^DIYPLSwfH0bKu5!^!W*sUXb!_IbgP`;c4y1l zMWcT$e(8miBl*~9b0CuI&v06cOs66`6^_Y9n9vZ6xO$hoAY6C_vl9MpX8t)4VU<6% zm_Z`|OWB7F+9H9=a_BE?_9|JFJe}rIMq1LLa=4P{k;xromrJZ_Q1p(Mf2o4~FDAV* zH9JcR@({)kd~e0Vhr2pM0HDhaahY8iW!BIU(=MgY+JCkHvxjiWb)1&JPUf;&XGk}l zCb;EtxTRJ=g_z01GUEORt~grAcF4 zi&y#rD}z5Gi1@Oa(QwlhTXM#H7Y4q;h49CAXIQ-XQr=_7kNJr@w1sq;W%4Ef%S1%O z=0%nQGU8I}b$}iG9n-b^sYlDc35Cz90W*mM#C453!4tJ?sRWntGgbJ9*u6f&%;yFf zFLTFz7T>8<1a-lii2Xz{@__zqRiPGucO>S~jC)Dg+QNZ@{BY{L=VUyYVeoZea;QvP zwmr0;zLYIW16FsY_+leI7WlxVkw}ApiIyReb&nQ>1^p}FXAzHv$SN%NZ|;by$Vn|D?t zA>>}K<4)LR#Y6!+|A|(XCb9BFW+eQn++UQI%9qb7hM5b;F(zRNfs2wJC#OPkBSIW* zKVdikA(gJB@M%UCG@t){B(~O@Hu)#1R_fzv99uy|WI5)%lUad^E##MQ0=SN-n}o1B zSEc*^tIl=&1*>!0DFb{NhA46WR=KbTF-#j3^ zlU<@n_BWXGvn(5A#fhY%#hj_KJdTOzW~8OkZTYJ25C7PTHj<)}Rr7PCO*R=xJ~h%F z#uYk#MC&PCkp5n;Tn?U&kDsqV09S$lltaQj3YjF@BnI-7gZ?F;fq28;L3;44@Op&B zZX^~=nUY#RIVEEve}vk%nkEj!ckeE_mw>FSU}?-5`B$~Bm+T4vjf(ci=%?h^)rlJ zmHX>e5UeL~zH%K?6M zr*t(Y+xZ$dZB1!n98%K_tB4KTW^4`D6hBS*%@US(ICnY9cObL<$TnT|Z+Cd?r<6)Y zctVAQ`QU>_ov(wGYU;^cKs*WIZxKDO{6>~J+o8uJJ2zz0bkx&a$s&O( zogU~qgpviw%2^t^{@uYT^DWQF7+?~M)ze?Q5o|rr1w=L9l#27mJeKwIZ}cr)56X&^ zL8L|U_3oAeG8O7!puPb4XphBe%YE?4x0L2&-<4MSVzrij`Tcqr0fr2kJpK9s z|F4S)0FxyDH%1-<^hOv5BZS`$>Mc)1;J-UPLO?siZR~>0rd0 zPNT1yD+-k^TJ zT1Uhv`joX-;q_j*RWX~8s8FQg2Jxn81}&U%05!d3kTs8Cf^`&E>pxi4l-KjfSeLS% zE#^gi0Xdw5prh#3iIPuadu3>A&s!^NI03r`}TY*-`UE~`F5hEvjgayNc6UQsdmS;K0*wCa=jjx7f}lPcED$&81i;N z6%}Vf9GUpC!gqW-zW9sw^XtOl`@vi^%x-{-hWkhpe?FPbi1jqn7_O;qBG8oRHT(LX zIb_^ehZ;Sy+jTNNa3w zGue2IvFm_uw^_n}OLX7P|DyAk1=|ryyN-0#?e3wa3v1%DRKAIQ5PUSUF?)qz&D&LD zReydxrN1r9wp&?iw5=$^S7T&y{4t)twD+kU6h>Z5Y{l0qE-eE#-aX_hNuT^gT6XJ$U5|?Xtf3YZx8zZQZLV~snzDEgug7N}IKeyk!oG#f~m$;+vo)akQpsH^moH@{X*E0vr zi0swr_tGifT(A1)+YbkP_D&>{Pixpt(MS)JENT2mT+oN;%OOQ;L&ldcTA6 zDL}yJR#JqPC_Q3y_?!f%>u`XIl~RP1@L<2Bv1dSkW2$3L55Z+RbavMrr(aItN2*aT z)F>Rd4ZUVwYLyrQF{;A!r!z!)-HTN1tBby*Q$HPobMY|@X4F618lM~72pd=^sg6J-KzgB5Lf?GUS9#vpc?W#3+!PeYdLi6yS*77 zsLwl4Z8{Nefz;t0FV?<7c!H52R|)2RDr?g55b5C4CCU|$@%Gvu8OvzsUHdI3$e#X7 z;2C|rN~3zw*PY6`=q%~_%A!6L(w{AH%Ukj*IJ)dZ(f>{l~q^|;yV5WUwhM@tmz z;0n)m?7=iA1<(i6iHhcZ3vmpu|M+d(04f;`I6FlbNqjwaAby%_&$+Rz$e9nvb11Tc zI}HTWQw0>{hODbA+%cpQ0gWu_e(2q70Ul$v!i;nI zH0W3ZzZU^x$^U@ZdU-|+M87;t$?RauOhONXNFUR5wnmmnE<|S|j&CrWkbin19P#WO zP@u0f{4o_v1?<++o~`aq@?m=^L8*t?X(B=RkuMv4zE^xWq`}QLbLFzV^!&ADaeAfq z?0*-Zyo4zYJYKDm%rQWL1Mn z=UWn=an6!yx-0hVaY%ioSTBY#J@8LJ>LmW8#XP`t3_E7WNm5e;d4^84f9+AxpR0^KdDv8L9y)ySVCB4Yht>*zzGgA2q#sW zsOn75N&P3_*P{iU+!WF^>$Q>Z*KX}~+yaPFZf|LGc6ZMM-z@;wr61}jeac5fYhNm< z!d@}9$a4Y@C%TAM-Z_u%PBx2m4R;9V5y<3AxA;8v2%IMra6fRDU2f1`mfDLEf)0S= zYJ0~C8jh#yRIDrU`F9USN!9XL6IhF;V#0TTeRRzato`pI>W07=v?Ihd61)0sSBRJs zi>7FNLc*qe$IQRF){!No?dRJ$WkG5$f&DDDnasOy@{CWIoR||hfgALbPO z8wM&?`f3_Gp<>{b(V}gUJCpE*Q8g!*xC^J8i{nsbUU{AH)IXN-X$W8LikL}ID;ByF zU(WS5>Qf5GMQP_exlB~rbp17`I~p&ONrp&=3b5(WxBC6VD^P2r2LsthUVfJ=CRYS` zd*d9?Zd^eYriKL;(}1Q|9_nwZ_d^;IN7SM!@0^OCiIe$JeG_jF5&=RAk19{X?-m>3 zWOy8i;&guDG;!m>z)^X}e)bSI>y}K!xP|ROx`55tdWIGh#M|ZM0{OP=sgpQ#_qNPh zzAf_4vJ6d9&s=d|31_uU?T}+K_iug}Afv%)U{1YZTI0DB3y$-=zi(YB0N#nfWPI?u zr|X#mFf>W@0|H*IG*Hr5y?}mBGHy^+JriBsHLybs4}(3O%Uos zN8rF`E1i@RWMY6RRpXQio?juaJS0Hh3xE1~%zB&OVw@eTV!g0dOCx@mlf~^X_sK)t zX=P+AqJo{u$%n|{vgl$Y7?3^TTgGtMJ1Bxy$BGb3<_!*jgM}Z4=Xn{?+@f;7JAUz3 zm~1CGv4v7pZ2aE6L5s8Am4Tnshy`rG`vAPui2aI!zvXlivi3S%iD}`a)}OX05|&xc zk|Z(j89qFGIjoANG+eF+xQnuIELFBPe$UIulSb$Kp9f;DMX7&VnN1Mq+nsJ5&BL15 zrbLj-1X_q(vKKwXTj;SG*%07VF`Ha|(w53|i+&!aasT}$KrFkt4){g?@Ni_Y9Z3cF zjHSbf*X^a9!o@(J{G7*!5#t_`62jJd6idFq8(&0ld|VdK!WewQ1L8zzLiXWavkHowqPQ5wR-h}My=nR~OUiTg?&MIq^&eJ3?&-JHLWkpC_bPQOaGU6)8Ing#2CcZfo3XI#s}` znwkm4Z7=Jk5C{`0@WQ(dJc$NU7O$D{{E!*%b&mTUf?t5y03~G` zZaDlZ$ITRqXw!K8b-ne67u6iw0eCeLvs)sw&CVES+60RcY8VSk|wk-Ms}bU~=-uRT;O0fiE?~^HpJ< zsS(D~&)0H>cZJXXOCbl-=vhh_ZRvlnnJCzkQ$S;1^pef$2oTA>aO`LZeTs4%`H~MoqOk+RF1z#P+#bHq6x`WF1)iT42-k+m3r3DS)rMgY?z= z#Dh@#X40~6tzz!&%++!dA3n6Wz>CwuibP=7YA4;~k96E=hgH&aXqiY&Y&%F=7g90$ zV!4aBNK9tuCBpV9 z$bo(x9&EoPqS9VDWjhnB;n4=?J9YWRNc5GJNvTj$It80NrWz3FZQ_#PS#4ED+}Oo8 zhcQ!Jit8C|Q-wd! zR|#(72q=ss4q>r}qbRUFb*4HR;T6V&s5B;~!!!5z+>;N`0*#zgxe-aVDKvXzZXJ>2f|Lx!8SN zVR;csPFM}hi2EIAgHFdleBDaW_EMgH9f=GsB*fs{ z4?L!#BzdIJJ!|8hS0OqO*jWG0rjTpj-Dt39?qU&zQpvc(NEEW`ac((>JSZm1Wn|s? zB#$K{y!GoR0b?ks6(g!~Y72I+)n{}(2-{$S=TfOFRA3JY`%Ld2G0511uZ@TYdsX;SRZ$n*p$`JWKW#sB&{=2i5k2>6#awg{8Pgj8YMW{3=o zzI5e#PIxw+jcbL?p;_ygpM!@#Y`fijgJTCWuAsJ&6xBw&k;z&jujr1=mxG1$$9(m& z2~1EW7$j?-vF^T8O;(H2E0ZB68*Bu!)KfvKe(CYckicJflG* zL?<-6!PL7VOvk6Zyj7l<&W(^!o7y`{FWtL}`ng0N;|pP!bn~7!j#ALOUg6t-M_6=Z zEm_XqAU0&uOF82lmhAU%f(l7TJW~Kmpw`{j5k6pzyxn(hq3(tfS~|Bk$yl99el18HV^OuhQBHj7?$)WYAc%F>=B0{z4rzIacT~~;U|EZ8^e=gc)Z!P&qQ+5 zz;m;rr zHcj%kfAhJ2*9xX4Te^feCu}0qiSoU405JphyOVaZKwI$V&$qW0jlur1)z(wl6}(*Q z2JM4C4uzEyelOyTKcNfXvP2FeT05TWvq^bpq(uY5sjk+l-6?z=&L1!D zHboDa=w@@zGPGCiMwM6`(|q(y9(&ccp|Gs4H#7Z2F|~bZEXPZsW;s_;iy@96?OrS2 zc{vVp{i0Hs)IEepdxnTh)b&Ety#$ODzpjjmcA?$%EM~TI6)A^DN&_iDe>=&Ke)z7i zRL5k=aJxi*pG?gRvJ4iWqiQ>%8!2c8`!l%2T;d-ivn-g`|C0I_&#|qD!eWDN_mD88>n7IMI>C zOVi%-P+Y9>s;36Xs>-$?@pqCcdHjL?C08iQ{UM#(=5XhkA2NhZ4p=McFfh+T!wZ3O z<1qn62`7)fvHwtQ?#qD5M47=wD}IqW1_zKSF&Z0sdU_(fr9=?M|J8(1v0+R)D9d&;`}S ztjBrj`Lst#<9U;bSt{NQXDoc^C*{j-lu4(?LEztLoWW=gJr}Fbn2%&ow>mrpL>|$@ z#!l~>$iCzoKX#~z@Uey4szx&xqqt{I9hAcWVZ=Qck+GapF}G4C0LU%Fr{8UM7%3M*J*btl zU~qirx`a^c+{gE4euD3T01qE|-xfayizEq;_j)@RV;)1B8O0D`qz$9adctKl>`9nz zI|eF|e*{634ej&Qlj!t^Hum$27ac#Ed`av@czuyZ6yUrBPAr4R7Fd zX-;{^q*$-SiZ8>@?^ZgSFv-Qn*-6UVY61i(^`HV-`|o+qY@xoAK?zd7^o*$+OB$uU zIi!*fzqYrdl;AoJj?207s?ATYAM#`>U2o;ad$xr+=w85icvdxrT;2~pOqfy7F=tOr zztjAMzPiP&^sQf+HikPvsYUhCZAYQ)9ph8oJ3@DatE{ldh`D)P2R@;ZE+yekdX$lu zwNMRFY>kN?Wef5<=s*~}m|(%)_!(jWQg+>W|dp zH*0L)?Lb2YJjxzh!>LPvN!E`E_Dzf63Y`^Gh{w=R6t0HZC-2^7)mZHq88H6bn)G^AEv(EV zpEtSQ`P|PNPd5FfjutH~|CxpL$B@%E(iwG7&&Y+u5tWMA&mK@Ml!lgH7}SbKNjOoo z4Hkzuq%Qj^)t2sg5&GSBEw>(t|mNwgtm zDrN`z#BVHo(1;!SnP;7-L1pXKdPsFaN7{5oOvL&xTO-Fr)@dkk%u`P4J0XOg^t>a! zZ!Af6$`*N*+Ahb+-=g(kUuBUEk(&}g(de0lsVBQvK5rvb1(p8BL1XKK z#t{Tqpw#5BCyFbv+19tRIy5!}*V+GW`SIhWXllr#m?uw|)xD~Y{A97xvPf*2#vF#) zoixivMkJTFXBp;1e(G(xwPeo1#_+rsE4 zi>v$CBjfyQ1j%NIhR6_wcIU^4G5&#?%@<@w7!!0yM6|m76hT<0GJlkZ#y2ez`fMR1 zzXQxB+A&74ya*QS54Q^@#C+vvbms?#Z~Rr%)aZphE;zju(C8>OmDJDQ8jo}?B%nI^ zeu>vodYT<_PR}Hyf8U95ETv=cG&3dh;}`pxXqICr%heXb{+kkF-EFDPHsrkxx^(50 zlm+3XAs%rLfLI6+y!!5#riJ53P zKUR+5A{w4uT&A)zU@5LYncI1V!nHkAh--X+cXP*=3*}VY6L92W-7Q(UMLmCCHnP3S zbqj5k{5a(!!tM`0RKX}V$TMY<*1)G?KUr&2s?BTNK&0s`_=Lxs*6QmDh|f1uBBw#Zm^2Zi?O^6llEGirZfhMn zY+I%f3zthscw6&#^i8;%`?rL!7)LRhL+vM~ymD682p)`k2q3oj8`C>Bk#n{Dtqy4P zkRD;Xp3%iAR4YNzD}Bnl`v~tBUSx?oQ%u52@VDMaxpmOk&94yzQff-gdMH;v5s|f1 zlt@-8FK}dJGO0~bm`S#Oq_22yV)o>3Jht7NEMrZ*STlKTc~|Cy&EYHPHNyPI&*bLR zlXx3)m0|e`VsZqetYoTsV+<*Bt#0MA)tnL`b2hKE!M1KHDsg4|kY~}E!1C+z4z+LZYEAs2iKe^b z{Cl3(3|jUl-+ZeLuQ2{x^tFGAk|ZUn{hchgH8TG~`$uH{>n#W^e@do=pkd!gkzvYJ z>l8^!^6-J-?&er-`cnde-V2}0KN46S8|B+@i70Z&^G|D+s-Id>dSbGKj3_x6x?C?nuqb%$wqUv;+vV7Gh%23Q z*|a^2+o^d*QXz51svocO=Z98qxQS@h8NtQm9e@lO)16}a(1sm<>9+8uE6-wg7x4dlc7w1Z=KNcj1yc2ng z7Mi7*wj*qA!H!0esomAz};gLeVUv<(mVpT|Kxh8vhh%pMn_wtSOOaB87Z>O% zW@ME9qImd(QPn!zS1hmo*q%|yj=)HA^corK@uRX9E=tCsV0VN^GEJlD>+;|^)o6aM z^K0$r&Hg-+U1Upw!&D#wrg~znHi?SBq8&cL@e6Ab7s?gl>1WI z0xK?GT=1+y*sV4^)1d^jzwQ~~Enzy<5HmuoIX~B@@5q;roJCOK>YDZS*lHL;$sb`! zmnzc%F@E zP$3q=Y+6<=77sti5t~_32?&Ie5i*-^QYP_+X5S;C^ma$nWv3fzw&X!4FmRhnY(u~4 zxbXvmeMOjfwD7U{$zA2?emHI%v(kfG6_fU1c%{XHI5Ji*M~9r7a^L*%>aJ+QAiyD5 z=oCqL9|*|lBeS#BTW?176Gcu~a+&nHW;Y(ppM8mFHY+C;R#_(Wv0B{*x%ahn>5&)n zX*NBWry`#7K-=EkJ4F;#_Pr*o2n7Ci=SR~i#5far*}6PKze&@ne=bb@hvDY6VPqJQ zOBTDPf!fI5Me~dr-*D&awDhmq=PwmH-M+_+4jdn~UGzJ_QJYCEda4YZldby@GHekE zXM1%%bz5u=UR{zgN#s;U{}$oXWN!4!qbzN`Sgi+R(zvxJ0HJNgmoz$XJZ2eML+tepp4toHE!}%Soc`amd@usTCg!uPbrFGt%Elb;Mz70$ ztws_TGjHf@gyfJ6J^eW~?yd|?fP1K)h&O_CvWBi$ZH|FT(CExTq{jUfr1SDng!7+G z9sd3#ny{}_FQ|MwwhkE3Tq zNH6Q(ml{4+M-~#li<>cib<`@sz#>3cvmGHa<)vX=45&Low%k0C%*tl|28=i@)FhJI{OZo)xch}tGHnnEFb+*s_~UuH`c_Aaa5^Q zf&&mXg-S(0$30RJ8#k{rU1`NQ!(;PR*Xx={Dbn2ohv2Z-!-pwLIwC6b-Bh{Pj(Vc| zO|?;9&Cy8ZmeIgZ-1Uk9v$>CZ8$WssA1gL8Cm;(M6A8N~UO2yZO=S_L@wnJ!zk-fi zO}{eVC@u%2W%PO4GwIma)civ)R@;Sw*xvq&YY6ePT*Wj@_bPyHP{wmxuuwEU6uYH6 ztH(PDDdf3U_~e99XFcr9+*kbIsIs zU1wb<_T$(wslms7WY*zw)aC^?3-5f+_P4NT4X~JpZk%#XD^oI}V4wLYy?II*Qv1rW z^WNI#QoH@_B|Cp&w5%h1w-M_W3a z#wnJX^|YH)1=b}a;+>|ubJfl4mHIU_)r!UC6ojxR$ac@O>%ec&Fo(;>eMHP_W*!>d zm)7W2eXXC@qHpKFI9WrHRtU87kBZ~`xx~luG^BT@R3ZomJl_VT>~K3o)Qs|IZ? z+!r$-V$U|;E-$U!CFh!e0sKa9*cDZgrSjLSDjln#vP?yIal0lCJ!yW@(sK z6*ZsXzdP-JV>A9w4^demH~*5`Ma|~0!()Z0@v=$tEZ?)?(940W;c{1%_SKm}v<>$G zu04v9pN8|=S`WtHEzRKo#caf62)e`ud&WfQ6Os$P@!na-8tJ%dO2y{`8L%cI?qp_^@{!{jCFufgZ5kpr zgFa)odT(oX(B^$EiuCoZ12~g}tm@F}v)y)nf|{YvBjX}NBvJUrGpqmhc&f(P3W=;W z`eI|yqx%u+UtO~#6NJ0y&5}FZ{=ryoNyEiC$?a39N$T~RI}|K-R;-d0l>G(0Ql&KS4^_1`V?ArMY6DHTo4mTng>PYN-)Wb${=?vDO1R z#8@8auIFJ}TowV%Zz*XW*p6~ir4D0uHDB-d5+}b8K({5A zKS?~fJn-*$jG31+{*H>I#DgX7v&j3a7W$j3hkF6jzR4gf`o-VLCp8Wc)c&xVBqJBA zW9-OqjbpaVDnxs}*lP$Hh9pSQaH>rR-fjCbTiJVJc9R=y!`bItry>+N}Jw_zm6l^jRmsvyclL)Z@D*cRuBLHU`=6q+KF+Kw;JTR}S_r!ua8cZv z+bZc6ho*B$*}GWB11Irhy^*mWdP>Dkn0&X}Sk3niz&~UKnPIYe!c)Y1`QwR>=Qw{+ zvS-zYL{ianqeJ(DraQ2+As_3{FvM?(OT2=^%lAXZXhorW4Gar)b1Cn($A$ky$y5P% zyRqA6Dnr?MZ|lb)Am^+9Bhw0O>IK)L7{-lEh8{(7V$t zJPa#+H+)@C=@`lyL)P5(s|4eXkCkXcc?q%6N4MiuS=9r}T!k~vS$}~kfsrQ3*N0_< zu*GKdX>H;Y_dfqWZ4<#4&9n+9S?m9cwzrOoYwOm$AxMQFMM4Pf3GM_7EXmsDOZ zPa~U$^_AN~f8N@04J(u2grs+$%TE9svQWA8-L+*#F>t4KR9s?#BnF0lp{}}AV>a?}3^7}|%2=wQmTjn|cRx7WDkjS2ZNtuW1 zr9>IAnGczru=4JFu7uG7Yx3R8E4{W%GRkKkm1Xru4Mc+llW~nRFQ!aw7FY#|45Ezd z&bX6p8K=)^qifKvhyv&d_?-NT9z2v+e{jZ4adUcIRbP?gH(kCqnzj|EsB!7znB?8d zPw|3u>RU|JS&9bC2}w5t2g#+~Q;`tQbFnrPN$1=r}f8>sM(hk>@ z%bfaf)IWg!r9gZAonmQ2bm>_P7?~OoJcAp3qb)-^fHw*#eJ1_)y`^3>z#-`U%x8hg ziIO1gl#3gBEZLARYNIn_JE|&r_wrL4VdgW)B}xLLeZZ^jCI3^viqBUaCOW*6UOypER%!JVMtfwn$8#4AB<# zy;wbbe~aVAw--MQRgfq0r2LUlhCgkH2I6`47>sH3ouhHSL-q%;okdJrx&(hql zBy|tIPXktqSewkBnWV8J)I9~w2(`^_DUjj1f~zv zTxPdA|J(y-;yk%$mrRX|PHut=_L_^OkdBFe!Wh^EbU?_mmx#8zYYF{>VU#V(dW$k$g4CMtGhoes z_b)j>R*jPre;rWN;=c}QCJtL$U$s@&yNn562$OCfbcb^?syo0TmWXNNT5uF;UZATQ zKM9FQ*IPh#15)yPS2EnEY3@8K<-#skDT#RWe!jOFSNbY&{k_0kqxQI+bfO%1489yJ zm3qrNJ+Dez|01HrO0>oAd`zdf45$)$+Q3PNR2(DWX4-MIj9wCm&!Ym~{~U72+Wr$L z9ug*p(}q??_@Dvw&>IoSkwY@N1f~Ma$OXzT3o;q539pZtZoV-F*lAL@IEKUri{+UJ zIMxT5gP77#mT)DZ&o!bP(#Z~Z$&i7+_3EIbW zTmYiB#3V+dM%KcWLZ&!IM~8-6X}wV3xqQUg^S#Uxb=A=Knr~o*8;yBFRh2GOiA1EY zM-E4L3Uy2T(WLUnh8zJN2f1cEgO%=?3uhS{yl&+NNjSerjuI2~M^YzW(-!lBC7H7V{MV$DsrEG5|^ z!nK*ksu6exvF=GM81ggivJJr3!_FEQehDOzI$15y){fk#<6YPgS#mt)^@;HVVLi4p z*yll6S0|j>>Xb(+}}>n{n{ zD&P-C{;kk7nhsBhfbIvEq8vv#PDjBH5^}0qYNp!DCCwfU7QwD0*1&Lif-fkU=^Cm< z=c~T(yWbDeFpNv7?|mSsD;=NK29w6yrhX$dz>T2sa>2Q_H!pYN`3UF%KPV4lN4OQerVMe8}zrD!d@)Q^zCr>NE1+-kiedq~D_Fy*;|56%Ycu$A(*G6RFVy~! zbNB^RgMrruue*P%6fYz~G@KW~NrD_}r-1tGe`g8CXmd8eBY@|1q)u3J8m;G$?0 zB-jsW!9n=|7FC=v5!C7!ifO)saMt+t(?q-LZ$-OZB2Z$mdtK&!3U4Pl(IXV3`Tb|t z&i~t=Yc%B7o66WbpB=`haE6g}U)AG|!c$aBscz_(49=n9YR`@f8+Z8xeP~$fJQE8` zi@;%w%(%bDkyUTuXt(>&*rdSiA)jNYLCXTO9souSBXb>B%2?ibw$92JArWEO+ga`JC< z@6%&Ig51n~=y?3X;hwJVxkkI5spx;$6XhALUl;~@F&~ro+*Q^3zCA(BhD``ukfxExS0TkBNl#XlJIHcsnnwdAWpIAaoX^ z{!rDjOj>8Rn>4ZKi!L8yB4HZsHaU=gAX{8aj!rfMcuCG*hl#m$2m9$%QA}-fmhTq% z#(KMl-Z_3ny}L=gIkUIBYeGdPd@!XhF|fW{v2G&fmGXhd--+lBCD2*BSEiN+Q~NbP zh1lty5HKp|*dNX&4By>;jleOEwjs_36qoIy8KAcC+tIK=MiaQ0VPm?jbiHp<-cNPr zzl)a~Vbm;O!(8Jd=CR$CFHaS4E)iBQn+fYP24tId^R-i+%3Svc?a5+I)o&4XTbUTV9^QAftBE(qb+d_&knAHvtWKC?}ye~pWIMYUXK z4AeChU$2a}+}0;ByguYNY<;AL`q;46+8!*%%N(S=PXPwAcq?(tYWsVw-f>k1R-$XB z-Dc6(g;!F*9r=AQy-mD;HaX&mvHCP z8J0U+hoKt4m}_>tgO?WR*k#NWl-&?`r-XAq z&k*}K`%o9m*51~U^?(bhwncUu5_jyB+p!7n1a_ysVe5N%uN~uipIW#bg9IimLPGHC zJ1_V9&UNIgR4$|6G@RW#-Yuu86U0XCXYj@&@A-OXQ)SMhXdD^}Dd;Yp8ySwykk88& zP)!$%+N4M>R;fr*U!L#xm}Ho;9mg6;39#%SInoQ0h^%xZF%WKw5sQZt#=F|goSxQZ>ovT%O^Vc<|956 zHxk}RFFZHsTFp}5#>eQ}u)yo4ySuwi40Qi#35w;JT12IUpMiw3k*z1)b={J%e#i!1Qy<{msMW06HEC~pWEwdGhm znVl-+aZFXyw%@N`4RlG2v6+tv8iaHPJW9`>u)G<2wpHt$cX)-R^~xJ&mPwfWW0^&% zg)$)jq=bod!4&^Rc>AwH`G0tc0?p|cO2qLn@uEH#zw@7q)B-T=M$YU@9WhVNj}~&2 zotG~z1cwT0lOo}qdJzQVkpr08AVO6T9ShRV?j^{>TiizkCiFr~jDR*=W|QwIM!G?! z!3om3gfLxBrZ-k?fq+yABpgLbC}uPsjNJ<&qpYY9SNY@&I1oxq&yh(O*oP|vZ5W>` z-9I*3C*>zlC_EapdVZH{EO{%R4t#0Pk^QF2xYv9Z$)1wmFh1LAmUlxaorft$z&3BX z-U^His;??2my7HPU^nSKwGQ|pRP<|Dt0B3yRqe`j)MWIORZygzbRLrC{3NJRTYzi2 z(lUZt%H@S`j1qOnP6C&WiPiW`i2IA3M1%2l(dpbJPpf&8z;pf=hxcJY)R^7KLS`A> z+mZ&PZ3IRMo~qhb%*08mS|WkXLK@T^<6R-N9gO3pdO+PQ$@pL{Nafe?howldXF zH;_B)SaDL>@o=N%oNqeNUSj?>%m1+I&|xtHUNbMtX5gK|Xiex7kjc&-qJdq~Gca2b zMw-SYpi`~DQKEHVDotHe{@U!Pibb~IS@P~wn{X<(u3WEEdaZP;NHT||*|D6Y47zMv zTeza}44zn;YMbgLkCIli4FR5D7zI!BWhn7BTdmL&}rH{I7cIZhm6qa6{$(I8?EY7<^v za(+b>N8X6D>MNp3arA5TtSVvHhN+s(x|d3J3YPe-_dS{^lLb z(7RIeWyyA|Hr>Fbhc-GRm7dJje0+ufK5~-Lv>Q{oey;7te1)Z}ihXl~!za5-E^o~z zD}bTT1P$g6RR>A!&wRJ?hiAH~Y18zDBp$M`sK$*MA!NfD+j10X8Js5r<+FjVGBU6Y zU%`~PFrjA#M^QQt<1AipdgZ(xLtY>Y^X_XXshQMZF>zRAaKty)7x3Qf7ck7Se9A z>Rh&rdS`)KHbONA+N`x+q7RlV_A{hMo#qFfKu7FSrt&KonOGRBqBCLaBQpK!GM22OJVwL$% z1?gaak+>H_#KUz~$nq$RIFLBnj1CXOm9*fwdPc;^{dS4XJ=q*zXXKh|Zu#ftbRVU> z-9(;@jP@F@xpq0oHy#WHbiZ7~%U#p;t+}n5jopvy?Ufs-v`&kBclJCaJdc^(T!_cG zUdJ~<8Z94Dag>sbVXj%dT5wmTG80SvQHO79VPHVOH{VuT@gCU%K(rHAhjf{7+i!=~ zb9ioRDb%$J!leJAM~A@Brmt0#fEsyyJZHcU`Dr>aU}&OJ^ZIbX{Fshco>U~rc%X(M zCD%B^OW}*d=wigl6<}NfnXODR$sAF76ct8u<6W!}XzQm2gPeC%R4MLFf>6Mvw;GrI z54HO#%y)_)2Yc~u8vI2 znA2Q9$Ebhy9m5bySvo6Z4ZqE46%Y_w$ucP31sPpladNGA{#!FB;MBfpbPah^(W;wK zFDIa=QEN&8m{PX=&1^ZTza=yT{LXUzi`8<_ zdS~!P1^H^6Z_joTw|9|EUVq5XKf-|dQVeYb)~$OTym_xydlj1uz>9*f^j#%|MyGhn7oo!Pm)eynQ*E534iVe;HNpNF!T7# zw^gjExBU(2@UK1d;f+?X`SV+NbC2ak9NL_Gu~#*CXZ)4MBnF`$%^hH)8aq>@x@Q$m zq}{~87sSRztnSzG{&BoqrRn8oF_bBm&Ha9C<^ZOF-h?UxUeTUxe8b6I7MLMzS7y@++%W$BZ2(Gpzlevfp|DQX&iHC*1> zE;g9xY=%{yI`_N$ADht1tjqpyv)=60e>iCX7ce05zj5vVyO&IUI_#u z^vrrIZ<6-xlcqaRyU!S0mcw%TliBJLXS?V_n)`7auw;rnn}gO(R8IWqEb%RoOXngR z5xB^KF33uus3LQEv5KnaFM909WyyMyK4dS&AT1MdY+(8T#9NipiHrs9-Z{aqMy~A#^Nmx?Eq;4{zKP|K+wY zyHa_FQg$^oZQWQ3ry2B8@pV?d4-a3X+|3deEs3+h_+<$m+jQ+BM^r!H@7TT?5RoxA ztRt3YOjFtI3K@LBodlud5jQOtT6^!!X6%KJQW59eurpsSTXNi?N7`=AOCGt>K%lR@&Jn=S4_8J#pVV$tqNJHaMRF! z*=8PpP|~`ys(3}&O704ala{| ze&}$j4=+P8b1Aiw>p??&(AZ zhre`k+Z8EPVdQLhzI53D(ks3{_hoD!{jf$aF&c4rdEa0B0rY3@8QJDKRlE%!;4RMA zTNc7rXn=(x+a$H}58eR~4GaCJ`i;A}3_XRwEH;~6X8U3z{htm8>FQ+hnJc8h*i8L_ zLT-(PU$T2-BS%z=(X@Mf_}f?l0ILFjLxO6c!SUdOzms+4kH>zN&_yv}E{l%U-nCa0 z6o^sN_sbrR=`;e`%vHcL1JH-biI*(x2p%|M%TaBjz8wBzHLbeVlilI&vd< zTjOC(dEm*S-2z(nN+cbcZ>P^;Qz%0%3tAGp+2SwZ7PljbzO@&QQ(S403xka(z@gMi27vw0|k^ovB%iV{L2%48dVEadUAnH9`S%z|1J-3q)9yqf8c7Z&Put3(E= zX!!B(PMXdd)T{MRC$O!!CE1yV&a3AJK(bmKuO(K%^4% zST=4W<@UOlvL70l6;3-0#woQ%E@)ZAb*bT9)uLO}!Tj=IprF`+Y55{)BhabsEeb_j zDUlL*5hBQ+*a<^Yn!u-nxsC@`q0@ez?n8V|%NiWL_(FA423c-K0}kWGE3C`y#z3m- z=81E}Gj1a-7KLe#M|GsMNMIXD3+$-fYxc!&DJ+C0M4ZphITs~i(*hx>NXms96 z9)a@2^H*;;%C+&-`a}r1`jSu3XCva&(d;huUM) zJQ#(3n@`YcN9W}jnDw2*p9&wD#PIi#?DP7Y?_IOM$3UA`9$lW0r$IDBFI`sd4e3Z& zl~QOiH=X zF>|TJu&b^D%(2a91eF2C?_O=LR=N!$D7|EnD0q>?X^38M2@HifmqrZBUBRN5tcTXjk4&xpS zdukZAc}%>k7+O#>^J%R&!AqldnOZhhhk%NuA%xK;#SgcWmZ@kDB-^RasV04(XvQ9R zG`MA%Z?tapRZvpHt?N)ftTLftYq3x0GoHAu20puq+m`9$ax96V09(9wv>%AYwA+)<4r7q6Y9r=-XhRGZ!d&=@D`=TLK>Yozf@;D9)*kZIv0EWD z$K0#0T-0{p*C&1A`m|I#2p1+v1hS+<;KhO&;2wQAJbPi-Rq}t=aKbC0z{=+M?PFB-R z^@ocsQ+rHXng;m@-P-hmR$Q6Z2Lj(k`KcEGW~<%3+-B74w!84c&+}JKodhy?AR4mb zI#Gqv5-}qDa-X=>gOsEe!)1-pIi~?`4ojGk&n%}r&=)lZA9=t8ox+18rUD;Ftsp{wCTTKDn%buQZ9U2VSg-GCW=fY@|g z%qvkBemsZ@am#K1uA7)L0Y=-oGdY~kpr9}x+^FQ)Q&FNbq1h| zyf$sq^%Ekbp@n$5LsXcx%aD*y2E#a4G}@nEAh>qi<)_mkA#;QVk5A-&U8pub@#;Pm z)0}5jcFks7M5-8i{KWY-@obp`z0|? z20+D;Yhcz75XopQSpxVNbh1}mpe-9ogl;@T)&R4TL@zUfLtX@K$NkWf&LzO%038db zM$m?9#xsM2I%6iA@bKVzWYAX2yCFh|B!(MfqC>61TOUK0`rB{LeKUbPxGfSMy=d+O zL<{cOt12Vir}xCOM&llGXY>zb@j>DM|95kiYMWII zy7>&^0Wi5t{$cEKa0%ydgxvE|f!fVyOMj~#5GiruX zSFQ74PC4#ftgVvPm%;M_GvO)h?l)y&+`uc*!-_Th+}VrjNLnPG*Vh4Lyu^_IKb(AU z*Q~yU=>PUPTY&=Mv(ArIp_+culRZRAodfZ z+uCwGpljnOUdLt1H(E{uW8rA4!{P_-qxHwrG;t|+#8WSI2j0he9J(KJR2U)L_Xmy2 zokh#h2YjNK=f?w+?`2;*|EYF;-$|}hOAMzer=L}E;nNS&%e?PSbXg;olgBvfXyfbd zMAiJ}^_h1)@Y=JNXalArl2McpVo!c?dioN?BYKmkGLT9< zWPsW~daUr0j?hXCh-xQvqAGAc?hQr(JZ%U55AA>gJImUb>q5m#f zlO_125eNnE17J_S1)cIOe|JEhv_VeKPaWpcfx)9*2p|He^xv*_WPV1X<#?0Tq03xc ziuti`mcL72X*2JP3n>iThty4IHks%F-P)Hw()ylf#oGZ^c?$w^qFMk97KAbWmn82+ z@!72mk2^AhM*!iDDrR|H4l{l?(=-V1TsQXwMmQh74~?7KRInev*xQSs_BfCKU5Ju{=;VozPD7l=E{^K9IeRD1Se;JC0*K#Po`6pu*tgyELP0T-&b$osg( zvIlUT6fvBGbzv;XXJ4f-uv1QG%3W&qL64=Mo36(N24A4~+f}JB>Cc(Ut9NO~A*fBX zc@oiCI5+(PWYgaJ(l>Q8d=2Lp13lV$vn!x$J};FTFYyy}XYdF7XJmyl$e9}p+L%RV zK56mpaeAdMd}e4xTeG#%5kDiJrb2z&<_?Jb(da&Io?tu}=u{dRm&Tr@wLBmv`^=lr zY0=E@ej=#jBeH_l30cT4MvxBSbK!mnkh?Mml=Z!oAWY zp1B90R>_x`0Sg$>p~}>TaGs*-YcInLu@5l_!<@v4A~8NF=h}Z4V|MU$na6 z-`~C+ALsg|LELzBc(>^Ju@u1_?R;McaC*UBBu1Sp+ID4kw$zcJdBXPfm$-zUZ!Ci^ z4{!3@%tO!idur~Rj?ezc@tX)hxbkg99=732-4~6@whTZ`pixdlu^=lE=lk0np2vc1 zge20ps*-(Vdq?z!ha+&e*l5VTGZAtL3@o<+4Z6#SPV@8PrFd+^T%Yl|Zo_V>fa(~Z zNO(?O{F2EXt;Vsl(3>U_^_F?lW~w?n4e5*Xh^yccyk&^QHar7Dw^8pH`113lP!Gvf z-ZcJ5e91mghG55Sp}*^E(9bD?-dASE{phYy-2!qwm}m4P4Z4s~NtmuQ0B*3WiHTQU z*N>oZMv%d})O~eN;%IS>lSIqb(Mg5-`qRrTBF_hOAv#UIH-dbcjtA4g2=2d1@y%X6 z$6oi>F7Ra)nm}c8L7dii{YQ5zKb@gCLQA_#8+(=KHmT$q=s>rMWpmzfO5%ikyh!qM zx;VGUq6a3&#Xm7VcJAT!P0k9Xq*T-Z7F!-}_<;nh)^>X3TQa%H;wO3$OC@@8?h z+^gdm0cy~dLneO%dAh?vZEA3-bb8uF&x=BZS`X$^@KAsJAwXXOI@R!gsc#c>zje?U zAqayF0e?J@5uG5)vj4@#bE5z%&@!*Xu-nx^iid9+v38^@Up@m*UJibT;bA~sx5y@*D*v0h0Y!> zf~97H6w;??9m5yCHol;~XSveA{Y%^mDmZO&!a%@@%dMX~|I5|@CdBTzOO6AbNX9?a z$bkeFcK_^a)hhO38g0iT$Kh4y(OC4A6QHYVqE$87BXa=;nmPdeg?n@)yZlXX6JHl; zD8#gl=80zDZeO4w$Fbky_50kfvEPl3rIohOUR=u80gE=}BJan?$HmG#k`4r4{t`!! z_N{&3#5B;GCanXE@`-jZ78b@MRlNLsNm8`Q!Y|Y#;P#}IO{X%EMSb)wq`SREGxj=Q-wz_s3WKX#Xw z^J$uQ-Zi;YTtM@jk>l6iAUy6M+~foUmgo;n{$Hg>1tPbn*VDy{Gm~AVa({47$1?zo znB72;XvgacQzW64_cqt#1O({=T3mD0FW$)N;Juqu4P!m>acLG zkO7l|u~so9ItagUTQ}ls3@9Y*1`bZ@rKG5kQc>?PR~pbo-KIY@S6=K_U7U%)4@k0o zfa}FtC`B#Lb$^T!7eOK~918?uCUpxt`=f}4y)9O(b0?)zyH%^ER^yw~PL%LXKs0Kj z9Y9wp_~l(?{HY1ZAFv0w`^pc#oCu`WwY4B(?4oET92f*tgw>z9C7AN7woRJ`o(T$v z<^(I(z)wG$WC35V1Ll4q*%en-h`1XB2F2C;S+W(?m3_FgX?F*Twb{Kjqf(8YWv(#? zD;M~&csM%KBFv}}z_CI#j$E-WF$lyrgZDolblaSv1p5R_wEKX;gD>c;;p(0C7rS~1 zwBNTM?zL|S~AoatT zgT)E?`3>~x!_h_#5;SW?3At!oZ}eF#_R%wLgL_|9nFWbvcV7c;HGYf}+qJ21pu z_ilFMdU}W;Yz@tGsj9_8$ghtCTCjt=C74W&bGqLn0k-^hi)4g<>JmU6>meLw?-kJ4 zBgLNuJR(__AW!)#OlW4S#X`l{Wj){X>O#ORjeM)_I0w_ zJhd<2d{W5}oEP9rUE!EQkxt)qpc+S@p8XUf(EQyiPfmn+FDT-Q?g!8liM&7phXMXG zEDGd7`A$1Iu1q)yR0QhRed&T_6*N4GZYqq7jhi756Q_4tf z%0Q(~@^uAt!yqELm8?|l?4T#{Qcrr;u^NZX3kcf?z~8xl?kM+G?At!at-&vT^{HEf zY=a-+EOAH|ue{Fp*OV76`aueJ zgt^wHj^T4b$RTe?%|G5rii-0SogXBRR%?vfTI6t2jZo_TXA28s66;e=;RhdVf$I$M zaQvgauJZ;^3<)wE0X2OM2lMmQz{{WT2&l-Mkl#41jPOxtvTfSIbhz@&E`J^xfedcR zPoLsz5^6a!=2($tHD@IG2~Xc=Wp`W{Cd>gDuVpW;`$4TaW5I8<2~&yMp5TlsN7!9` zN0@EQ9uvQ33M7Af_8=)W!tBp}EYy(5eB|ch+pw4Ed$OJy>W2P$_Zc!2sHwZ-mMfhF zCQ3eWK?S`lDoR;ncpt?yYCt2!5iiC+y1#xy%>1;01pQfpEAe?)9+0JH{|PJ@R{#PF z8peZO`dnYcfX{_>KKl>KyuIBJTR^w1UWn@@p(R{+~Y34e(rDz@0Wwy@Kk}!!xIM zT=mJ{V$o64b-#A!6vN@8)})7;kcbnId6qsJ`Pa042|zjk%<2~4iCPP*7k13~EiWRA zzF~5gEfdCDncHeMW|<{%diQZGD!OCbdsMgHYSAVC47h*Alg}_3f zS=uahU*Kx>Yd$-}qDqm>+>{SK;Y%cK^4c<<$#q`ws<0X|tIUXKcC_Hp14hXNg>M6h zQ_J%mlB&fzWG0O3Z8DuZoDZ`IB&;3*+}Q#43?@9qbmJ2Z`np}}m0Pm-4XPOO!$1rJ z9<)SlUwT!RD(F6*$J-j9g6+{c7ab~rW;){5LtK|Sko(m&6afjL>9|qEsSc=v3V^4~r1-v$!S(t>P+wWv=m#O*%!nas@YmAwrtS90oVSO#>4@XNccK zzTAK@T|9Ijj4Ycf<&S}Z%ga?)9L6TVMc`lg_SQ3%SgmlIS)DVu~(&v`85{ZIS=(FcEi zrCM2{5ig5_=f`--?0;g>E5@(exxR6<8NN^##uyb!CG$r+bQiudNG)zpyl~XsGGepb zS#|t6AjhB8&D}i02c9)(xFhaum*Uqp2z7H3xsnukXis8*%ux`O>UPy7a)AXPZ9*HNaW3wE*DqN>KX`*4rV3>%||?0hj5t zlY=CNQddFSr=M@GQTjRFAG}cfc1@(<2iiY+{BEBW};LP+FgtraUk653;g*4naLkP$=dW0x2=)g@jt&&J#(Di#)Q!t5{{n>!x-3kF=dEs z^C#~r9WTVN%H07Ng;K%oE}Vukb027DMmiC1qD9n4`UpbxhZlqoB}eQ=yg95+cq9W( zGTDB{=)Y9^j$GXVDcJ8@WE!}P?=$l>vh6kkC04&{w*Y-wdjd9Psl2Yj zx9Eh1KV3V@1VtT1=~v zRSD|dF4bI*`=~aXYj;vu5t_jnkliKmb2}$wipU^@3c;$22PF5_m(_$(>&8G|15F34 z$5N}lK6;#H$^+!O?v9U5ypm>f@fvz(KayOL#^*dOIv?cmo}3qU*+u*H6LHKp;a!y+ z019DqO@~)kd!NXU^F=zoi;02)&p;3A3g--b=v$XML4YyXe(IJ<{siy{8%HqI0oE~% z)T{n2$hB>c7#uEd0IRHK!If zN9`;3!xmcIF#tKS{bb%98aHh@FcQ~30R&ka_6x$`g5O)w+?CZ#0y44kwHE0fE<83Xk216y{_`%^d|>nWWi!%_02+k;K1e;O1wiP-EBnG~aK-T$KLRuE%8Tp!vosks()0^dEt$K3D;ei~@7VKExX<$y~b21&Qfuv%5 zhJ?8$P%*BoO*Q^pPfqWJ=8u`3t%UAd-O6VHi*;i8?l2R?RF{ zy#f$v0bq$pQNaiZJf{qha~uacg(s~eNh^UU)Hh5TCjD3?+Ryj=Psm?`b-9Rv&kKY^ zpv(Y0v&BG<4`upV%}`2?YKB+0iM#=5Ii>OVp*;8`$mRP&tyNq>t@lDFb3i-$d-DKj zk-Y||`W=)O%fl7uDfBaKGl(C{PH?r(4@~HmR>B-%uC|}C#?_R#xD&W7h>c4N<{H+k zYMcFJwKP51J_O@PfMZ3mADV>-+7&`gxzP;!-S5u|9%an9nq#sNELZ@qH2Kvmtekzl zztHexnXkfrful0cWm6)U1xF7<%EqOpN>X)WlIzDh4OrwcjI8?8ky`1^UY? z#I?Y?m%47MR#u}nXFv!B3M~->a}6?h=mox?Q>4YD%z)?hqPnut{AHbzv z?cG9mJ=&_TxQzKIB!b$#^FOs~Nj2YIt*bBr*KJdu@{K`ZH&JAe9?W>OyFAsim)&oB zd?q=vtHqy2NSM>hCED;RfahOI9lDb1OLwNHs$If+ z9|9Wu3xY}~@b?X1-7v~HI7fh_(a^;JQG58{glFpcIZp9FKwVN5vCAo0PoxFGO)TtY zjgsF8Ee3)iOqXhkf$IX-hUp^&*O5spbGRfRYpV=;%k+yvNL#gEqsRs4lurh*RdN0x zFs=wf>zm7Gnu&eIF$gCu$gPo`56nts45mOPL%e~9=su9ika+a&w=B?Yn^X5|7B>_~ zq5yvhL&Md&$<-$i|F+Lf7|+LgN&~yAf98s%&H0`Au!-6Ess3VrY#4}1WUM$Pm8%m!{J<<@i5;S;hSMfJpzms0jEQ$ z9ZyetCxFKKFWC(8TE;a^7`+Quc+u>_PCQqDG(PG9UI?l6ylWgU5fQ%-ZnoKN1;BeK zjJoR2`xkXZkOUB631l7Oy*I%ztz?S8<<6;j30pbt{*{`tPZ_^safb5uEbafD%%p!4 zmH+ElrT^D2iTZcg#Cua4#?!xIRV0Si4b?BbXx;wjoEN(@ONyF(I;BEAi&DtZro7ry}dmJd3jPQ+0^F%^jdIch>=kE;eFJt%&T0f zR`_UzQbDI}60BAu<+=I~zOCdt>$74O@notaH|f$uNHrBkrvOV%_qkoswd|+P@9Iyxr?ZS$osXZXngbuuGy%G(BHWljjaGa5zR}wA_P7gfPU|}<+ex#4C@LDp5a;86y zZfmvO-`5%FC-DC9T3LUzZ%##?HSU)7s8 za;lC-wO^&A#_}D^^vaSHo&zWM3eyQnNePKau`v9zGjKp;o$ro? zR{pON#{OSF3jbFu^uM3neTSi4cm7l7$sFVB$OG%T&-0GbQ31#(cE^Y6++P&PfqavX z!1y$hn|RKleR8TVV~c zf}X5@tg!FlD9DIho&C6WRGYJ@0@J+gc1Ov8IGMUClQ{*Ax0L+};X+qi3F5g=nPjX+ z^9~nFT_m2XO>g>P8{Hz*UZGV80Xj{@w)J#>P6i-`-5yjb?^mKlx)c=bsQ-@p$uaxh zH;WJSwu*hRjRVs2`VQ42dUYPTq?X+tuw9*oNw#XA?(FB9Ohr~x9v!452Dw@z(#JJIP(N~x?iaP>I>5`@-Yvu{Z15v zx5~&v5ZyH|=fByWhgv7<`wYHU)V}O@X4~<`V3-o0J-Q(Us*75nX3?;kw*C! z06U5v)b`9#++hR~5NHf^^$1>~5wIv6-)4|V8RQcJG{50w^~^xKKWMWzON3SLoPqUW z_@ocmA+{Q9u?#n-vWKR(kDI=jy3HA}T6Rk(Io+kP9(PN!(!1vI1`+a5j7Co>*NL-<`(@j1-i1_8%=4qf0#xY=25pdep1vWOrzQvk5a){j;fUQ_)~ z$w!@J9hIAn0(B#}Qo2jY%HeudYQt$fOsGJ|Iq{SCll2@BY_bS_a1X1sJje?>&sT4a zanvb_ce~n8DQ^Edlso`*8!5S6?a^tbj;y^~sPYOU3^N3%U@NOPZhb^7wELM#Cj@kHy*{ON6|chFyevSnN4W^6L~$4 zbFa~mhQwZy0ylu0fEqOn2WOsjxmF z-Z*Q3P(6t!*IJm?;I0w*`^HwXnq@VerHd%w7k9a#zkgYIP?f8js+nEMO0vbL?4Xe7nuabMQw52WgV5kH1l_D~* z=>r4gfe+z$Tv%!Mc<;K?{h`}`>m!7iFIPwy0k9LXyGc8y4PNj{P|1DL)61%|oYBVT zuy_l?IOJTWNNx9npmfia8;Bzme1E;UGY}Io5-oEugD*D=3_uLkoBpj#$L)0a{WT8J z`;~*S{ESp5w0fZLKMBIT8BIj-3B2I!h*mz4FWcMgXg;{}NkO5aO8QeQFeC~uVhI2o z`sPPek@(-iE_DI#X97)k$ku>ukI!D@xa95S0ZE-k6tHj)%-QdR8lxBjCG`20Wf;!E z?pVioi594*t$?EO!ftQ}NJ(YZ3~jV?N`}mSRT_>>V=>ML7Mu-SOBug!Nsm8XzPFf_ zAI{+0!ByIVUXi?419WfGVZU}PmD+S?c6J@yz|+htr~Qd6gZ#GqzrOZ3s(pm>+yu6qlI^sa%Xk8!^2{4`R#Y3!~N%g3A4QTq;;#4Ad0O)-iL z?oKMUhjLaj$+`{Vfh-~&Vm?|RP3K*%A`Vrn*m$!z6CSTaoxy4QcMY0GJNr<**=kK^ z)1z3dk;8pXn@9s@Vzv>KgT!(5cqT1+AjB>H5g{nCN3iH_-9A5$7Z=vx64{ScU5@0m zbsQVLuD>^15L0zB`ne$|S1N{5#;9kS0j73dNPGv{-#!6>foHqCdrMo3^_AUN(4~~^y0<_c7hF1LWy(xySROhA~R|H_lZwp^M4&x zV2LYrYPzgahtb1+cM?&zvdt+t&Wy9B%uzz*uP8xwlv&0yJ^ift zFox8zzYQ^RW_Ud%cT&&Bspm5Zl^3mx_+@n^?)T!x9z#-hW}!3;>W#az``Q$)PU0-V_1 z-zkum_;m`yIEDOSzcDx@?EjG|7U$cvj$^1~JDZ2d7XE6rB+KxZ)i&sndwRavoS?sE#z7!ll-0U{6X*!WB#vF9bFC+z^r)yM@7e>C@2QBk+=zds=Z(uy=gOGqQ#B_#sVNJ>b< z(A@$eEg>Kc(kV!%K}&ZdjSO7_0{fol`+ffZz4pOgzr)RuC(LpUpEYye*Y$qA-j{4H zyN{U~{DlrZzsARpa3AXa$^qvF070n(REntaA&tyNs2v#fc!3B??J(Cz7g-O04DInjo45&*d`K)*NrW3TbU#*8d1y4=+y{n=4s-X9cV<|% zcSRGs_j;%kenyc{%&vVsKhX|u`Hj;Z0hEp+XMz9FQIBZYlYlo{TN$5NS2;q42Z;<% z_FKv;oiHwlspWq_~~#%B8+$ZyH-u<;Pxhz4PEcgrRWFZen7CYS!IN81IeLx)s!DQB16QR z-YYIsP>dFt{B6A(`XtS^crMYT`^qQVA3DQ^=li(e0(f{T5Bbzby4iPLW2W(>+_4=ou37ZFL*ER% z89c};HC>zg%4^*V0}M)og@x)<`TTw;LS`CP@yyIj9U`?+vefwfaYS?md>Cb4R8xmU z!#JDMfZm*0h1bSX_zR?TI6V-|HJe(Ee35g7N5mw`p>OY*3&~VAGJ}Jb)e78Z9a`b1 zzWjQY;RQ8|)0<%l;(ac`z3W~(uAA?*fw_(&X#?r}iLtCD-Seh_;XaH)&0fgyNH*yl zzRlwJFW>p^C5VpeO+Qy?om+q8eGGGys~K#Cr8VXk0*E>w2GXP%^B|M>t-J#gAV_W} z1P<|U2V$Ykbn&d9(lHFfJHJU~2F%{QlpW7|ZNJh5EJA$HPCvp8plgc>i2FUAL9HM_ zRIkxYh*N*N64(%7*tTiCwmU)-T{5SWE-(X5I|nnVwf+iUcfgvZN5t3uZPo=`aOBkC z!tY+GY@lPhOWD=}1#7}C+T563)&x)0j~!VqiR%IcJB4kV6;4cp?S_l_%^Jo)OO$yo z*Oh6o_wp>lcjNeRm-h3<rJs!d?jf}f~b@qpark@Lp ziCgD{hz!7-IjHt%jad zTbg~y5cM<$@-;ysSFm6?U+*2>ak#+ z9%{_vW)FnqdA6gxJdG3+ZikW<%K%7Bqw3c!yPECH{VsM8iP3O@3tt`}*Bij7SAy6(RJR~WHG z5U@=KYm0u(ZF@>~B3|B_nBk%5xG11UuuXIf-h-ZPN-1BNdTyVKz5b`uqXNAho*lPC zIaehm&z)c9B5*?~=j{7>X!_$<848SVeA{0CR!PvX~5A^P)RORkW$?23lQr3oHI zbHN~G@ zmGW{rHUX%ILg0H$I!026*3CX-u4ql%qNzVYyY4Wk6`g(VAFty%wQG52NW^0kL#;ix zaHKTn7bY8>7m=y;=YkYA_x5~lJ@MBYs06sjHM&jQe6SJfX&NxDT#H1}OQ!OOmNxoq z`WS;kumrf3G}JGU7PdE_lBCE!a|5|xAd^SQiUVh3NwV#W0Ct>BNr|JW8{#t7r?zsw0!-$twto6Shv>C5_0dYC#hqnC$AMOHcknX)r~Gu9_`j zc?&tWN`{-HMvHjtTHHE~=6!Ao??X4lZO(CDZt!%fu2k0Em0_ptP|a*1yOE{|5rnMq zHI7`Z2?~Vlj?s9{X+h3sutu^*D1&@{hh0pTNQyMj`w!}iKz@W|b6);R>@0Jj|2#!$ z0E?@4W?B}G6UE+S!8Qy($|*ew{vf+!YTdQ1*Rda!lbfep#YHA@iOV?`iiz`!ANS$* z!qGi%`U8-NCu?x9oM{ZGK+rgPQTC1kE5iK4faB5NwY4yub!N%CXL1lN_6s@ev92I2 zbF@%8!(F{TY8M?FAgbw08ynyBoe2nv9{9sMfIFxi)^EUE&>y00S+}kH$g;B&>tJdK zd<1*D@y?5KAOD_>gL@QX(`uGC=S$DOzPm+xx>Dq^W2>`wSSrP(E|ByztJ$>vea24) z+`px?Bu4KrCTV)H0tM}s7Pbkl2&MdsB{zChs#|ix8E}hB3!a=QSW<8#Y|FH6D*4n? zannloR$J%VJC@p>X-^{7H}|;rZCGL|Q4Rym%rr(4*X4D&XLvQEpozr$(oI2GziLD= zj^8CK?uQ+J#|c-xXPPl=JL(uEis#iD9R-II=Yix zovE{h?}zWN8@}(iQjK%bqN_Z-AA3}?r23c|JV4sRXd_41iJEl?xqO^UPBFYgv1d^g zl4M)l(jT)p`NP9^Wbr8Owd?y|g_^9JM|Y+MIaFFl7TqRcw2C%jDhQOmFP)+hA|D}G z%&JlcFJXLQVOeqp*sVkQg)pJh2&F{`rz}-Ur~!HQ{Jh>M;d6=3fJZ3x7<=E-)cIJr z%V8WuwFY6aG;G*--=%yI>WOPyr+)DR4Fau* zTbv@Jf-#}(yE}N|VqM~*lNsK6tqw|Cwvh{Eysw8mp)~yyTp_s{4 z+;UCD^!`Ty_?#$K#1|@aQ+c0CRUJlM8u%>AL^L&kbOikrBSWF7T;KJiP2KA=DSn5C zR7?I664GIBgwcGHDsQ1__9YbWm~(`k;s5^L9S}1h`h;)6GaKtChWS*jGMV{cw1!A0E4q^Ck{ zOpuAO%hQ^4_=$bd_~qk=2hJ}FO5K95G*unOX}HY)$ix)=OK&T(casqG5+Scv|C0uX zgjY20(zPTnSx=A}_WN$HlBKQhH|cc_A3w0r3q90<6!1Iu^GU-@?g=nW67-a(<79;g zUieG$bp0&LlSGsI@{WYU;B{xMI3cJYoR$N zv1eC#N0t4o0-IbrrT_eS4v`~R?LFB>InC3w-Kw@x;C<6H5GhtP-1;0~6oL7RIRxmK z1Z7&8wrG=|CC|xH{{!M%%X~tep#oxu6!4u{!t32*X75Z{gDt)F?fVu|m2j`-M_Hkm zDZ%PP!nef1g2CM@s>ZR-gN~V_HDO-ttE-T_e#~d{W|WsLs>|07Enh@SgaK_dV(d z{(3}XGg;Y42a>R46B{9RklZ?2HaT=IpOTz-1YJR1BHdb#O%o|Ru~Atbg!VBljF0kj z{9tzVRCbg2Q7{IH2%#k*J(f||xQ^_-S~pl&3s7#kd24a)+J;GTy8)m3w33$kj*t?& z?2GzFcaFJaE}0GO3iol>GKx)p!1%%6N^lSCWqEqrZ3{wUx0|9Y-$Bx%idO9>XSQxR z`vgXg#Jl7$#nV(hen@I&;ZlTeEX}n>tZ?YmORLEc)N+H1K~wS8bt2_L7D^_U^_co< z%b0Twf7qYk%tDDaavmz4>OVL2(GT{fo^Nrpc=bKnfOwDx-H=NOFR1C&AJm-OkEqDL z^6&lUZgaLYE><&}@@W?bOIw$tcG@#&b8FHgwHRp-K==V_p4Z|M>jVLctWKJMi0I6m zY)6p*Tv;@7jb2K$sLeIo>in6~EL-$3YY?rzCak`GVCL(ylOcMiF0wU+-V!H`U)6RB zdd08Ll(-hw^71Yk-Cu6x!+jdpZ#-AQ{E0%-9}`!%QYeo;XMmA&dddp09FvjE_Z1OHfNCLA)Z+AP zEqdStXaGKmO-@EuM82S$65UX8rMPDGK7b>-;Mlk*pzwh2;$PQFA7y5~d68D4>OsH_ z^!tIPYenO>T|+6QUu=c!x;DtDC6e?*JcSp2qgcw!(4$!k%!u-Hz1 z*!XzL?qppuO5($7RZ9A70H5_v=J)iws!6T z>@9k^*3Ii>tpj6ow4TB$S^N84XC&eK<17)(S+71ma2*8a^(Gne>aUnul_u{gn0(|Hzdj&d z_zVl|5}aE-%>9rvlV@0W z++OgC!g4kR?U?`>=ru0cx(cpI`WH`kHwe+(hd4<-2;*+^qK$46k)^^dV0KdPUOGx5 zX#G`aXTH6?mBP1XW`A|qVUm4{W{K-gaIA6jtZ9U1s_+$W-y_SO*iNe+({S;wal82kc1a)+ITA#y`KplrZW4KiTN%^= zV{xI{@t5HGn+xJ3Blq6L4!|=pS#JLXQoa~z=QH=|Pe=3|Z7qYBLyMbNS&QDhuYa$< z8w$>)dgA04_%>g&F+AYC^KDzhGWXTH+l1eSY|dAtZs!%#x0aRpdo8Z6(W;1;oyKXW zeKJ5Lwu_Jsh^+{2{rm=^wQoKhHao9%IIl~efi(KJ8Jx#7RnGVulO8JqX3;t3v?3zL z#x;d`sAbfRyfw-1ws#aMX}<_5D!t&x!y~kzrgGE4>(%X`#4nd$5%?+2@|1pZo(;=h zllHx+4l{6z5*Xs)i4gZk)vY)-=sM*FkrI?e0;|4N5GS5t3|@iz9FOt^e34Cf-ZRxs zsp7-u7)?R4>SDJ3nF1T46LRnd6&%?!^4Wtu(fdJuT*usXqW9n?kQ$7(M1t3c!ZrE2 zM{10?IHe-leC74ycPvN7rqAvfb>bM*rJg2%kFCd=Znt1r6Jq)9-U50Y-tIxN8oN}3 zI>bQ2D-J#nGHaXSVxrtaIYsw})=TI4iizCHUP#?(Zv|CSecurX`pfguJVf2Bg6#@R zXB8#O3T2JlS~NevI&d3x_g#niQTb&qulqnx6zn*7Pdo7UecTwpqKj%m>geV)g0rfy zqG{sCpT<6bmWsu*?gqKVXTcqcm9^UA6AT3DT>T0+ez^O^9v~i+s>x)pzO)DTarTAk zn6NrJ0(*sTM9Zz-QSTaexz7HT+C`Qagfz39M~dmIa;Xal zsUD39bH&$lpeJi;qleboQ84{_j}xh$V^m{_8&@b^5@sig8xnWd(Sf&%QqL{zKFR;e z^v5hDN%b^!Vj+h!^_`4!t~=#M$D2W+T5jp35p!Rq4pC%PkFmXj1wrHkwvY#j|=pWLGj7%bNkR*^-}t)kP_FZ zPl`nNCdl)-8VgNqhZy4zP?IO|P*uV)EgUV8KKczmV;y_Md;I>iFTCbbq1Nj} zs#^=DdEZL$+~tcRq^a;#*g=S~%cVtHL=VI4tByXmO;?K$te4Q-P)gzG%LWkG#Y7U2 zwpxi{3oQpXhmARSrNl>&uI^&f!+WerbFxHw?|1W@c1~fm!VVW9iI`%{0{dU2)nL@! z;-hP>1#ru^tgBZN7I7zR0sagr5<8x8^$b^`@Y!Q@m*Cu$ta2Wb-Mk3`Xy}5JXa12z z@n8h*0I$nivEaoHly#iN$>FwlpFvAzJ;;N~7+WvHOffMaAE+rjDXT`KcM_tDa0X2X4ddH*RcSphoi#qjWo*aQ5`iygtv z4B~HD7sLz-X@7^aB@dFe~={|&T!(Np>VZ@ zGfb{Od*$4lfIzrz4T{6s=B>Q#5s!o%wu)Q>c)uRl_ad>-vZrf6zQ}Lwtk(3h*o`127r>|QT5Dm9JeUNm2WBO`U{0il` z=K>xO?Nef$51*>g=lGT0fR$2mdYXo9C5Cd_Fc9wg+$WXP+f4LxYZikAsHaeo5ZG_u zn7%k7pM!j9MJ8FT8r5jR%sxW1n}!>_R^18KLr+9zhQ56@k1gje%=PQ!EW@L2%e~mf zad>-Tqp{VR|9u(T7`*a{f(WE3a4LIyTTcEB*LXx-g)FMDo8k_mQL}qlPEq4@3MKw? zWRuX~#m&|9ki)#+wS~4>Ll-E6j3>Z{$!=-g!6i^lY4NB;29sV`mNvso?*fK-pjP!k z(+dx5#VQ8Hg6#H%2~62RO;PCH(7^rr1RCzfvl;@gS%;$RuYX2HTMvcZ@Ex{*;58eA zrO20hq}dN_a!xX>i_bdb%T-OA{%}d|IdFp*6ncH+O#qY_C-v~KtnXvS{emZBEreb% z{;622Va0SV=yB*a|6@UKcFUK{* z&d;!8Dr`~EV{UP$ZpL4O7mslK)$OB4o)}F1wsLR{pOcA}=sE&tRP6l^94`eRdGS)} zEi4T_GL?LVI`OtiVN2Po_qU~WaDRWqzdJ%8XZVfkjl3WKPbFx`9Va8Q-He}FtYfSF zI#7ph0iEs$GQ1nSw0hSc!bg}Tmp!bl*(v+%0Vn1#2E#{)^?;u2hF8~7Q^qTrN@glA z81*+5xrf+jQqu5vaSCiEop@^M_IftK3(8flQf$vOetXn!P`MDO59%rzp|R|ElmLgM z%vW@oEM!n;%D<+04B-{rwKdcdK!{5e(q;ZT$)*cN901(7OvQk(eY#3(#=+Ge^%4-(N4LiEuj zr)6J`V>||r86G06dy85#GI_SPr~~b1!@j9iI^NXutSHWX!>NOV$#t5#l6FPJWQ>7? zqdvnu!f$7^_F8rBXCIujV}|!#{s>LyS!yH?3$98T{i)+0SZ3zOu7|2m;u3HqDt`^;GX z6Jrjo*?J;d>>-r}gkf<8nBP}i5gX8g;^L7XV{+x?u3JNCGp}>!epJD^rDu5%W~k_7 zQj59fy$tyZYM@3c5b2j7C)JgQ|Dyb!(DUiC>>4f&%8xE#p0v?fX}@X(MZ4 z1`_X-YZ`bCRnBVALD77iQ)!OhQiq(s*cy)Krn@o{H8Pggoa_Qz8 z^SdPr)(rWRw?Tzrla<#sciYwPdaG7NS2#v5ZQi|$oeT=czciaH+VpKKa{XAjnf`^1 zOOR~1@7C}j_$&})lbJsF0*HW5QIQ);tJPFP0V?gF$NiFbuiHcU_EIg45iG?KQ1gCB zc&cdOCxa!AclV5lOQ;UX5A85>mOUeGVO#kd^3=%f+{?{*PnAfPN7(DmAX=u1$(alW z_GzYdfbGEQ_CEQbR$Q;ygp$-X1xl`p{b=nBNIVQyBs}f8))$@@v3pd*ZlOBBq~;?bqDuAm&*MbZzuukcU{WQ?rIlsw%m1ik?Rwhl_|}JfcfJ{;)y<}=EGy@5lePPT1>cX?$yVN zA}M!t^Ymr$xqvzO&dS98dB<$^88|v$g*u{f9@RR)!zUSU*8w24(++-_n|X)$Rb1HT zcD<(iuF;K?$dVWE&l-_{w9cpWoBp-p^ZeD81_@=g><`96yI49B?Sejg_j=IozR8Ku z_}>WCma0b?={D@vY=21Eh9n=pZ+mBxS@R$1@VK8lERh7)6bEimoEEfRK8+#q? zcNz!h*z|#|K*vAv9)dvjc*r-cT6QXX>Kex)*m-!A#xkY3k}w~#mA3g_ka_xoBpN7x zieZwuMYT#s=J&-m(BmRZ=A{81W|>ysGjPW!?u@el#uJk#K)Z z+$4bPLgvXYaDlCWewRV~7bdUl>6I&>@Q;56iJFd>f~=!j#`&%x9gWw$mE106nITWG?0fxBvR~ejH8vppWW_WiD8fCk%UDz1 zGM=H~M*-v7O)r=$j5htVtt~Q&dUDEDhXXORcS7_%l9KckxiJ6Mx7f7kH5!ziB~uTQ zIKTV{Zfk{#o#H9oV83>UL#9U*R?Ze{eLv39vxA*&ogm~4w2@FEq^xq6!Ivt9a$)bX zBLkcu_v$@ODvN9%rcbjALgR#du5!7vOFr&s%!NU+_ori#UT5QEyKE2k{EKa0P^OyE zJjAnh%54=bJu3nH1k1N!zCryDF8u0$chDV3-*sJnc6iGJrU&+k5I4FecY~freJ9)q zMKOap5-&QnI%xe=kck9x^6_-^fOmRw;9|4vj@SP+kjLJ;CKQVdF!yGZlHh*R-?R7N z&1g^sYyy*4-n(Wz_)gpN?;PqzbClVU!XF<^$4%k>rJQfX4FMA>$dwv)1 z0oC|tkcD*WZ3`cvQxpG%Neu)YX&(*r5cqi%ma7#0O0{X_(MA;$BdgsKlX#AVq&M&) zbVYNjI$bNzB0*yk6+VZcv7=KWDGLq$bv|_Pa_{s4X1XsIbW$oYVe%)2gM|yC!vdus zjL|3V)RRs>%#cdR)%uf}%nMP*ElAy~3oQu_w^M(w7|lt>bh6n_s3q1KuUc-3BIW&B zY*pohN4wWXzD<{Dlm%@o8H>~Saj*cgJteZ(7NJEd5^Tl|YE(EuV8v`H!W;zaR5J%c z5^M4x4ej)4@ud$zo%qVPYsFLSZn>@{zuKP`L={QyFXU%t9RuxAB-N z)D5lEnn$k;dwJ#Fi?ixJ3zW;`X;Ls-F$-x2H|yDIj~6+MZ^-?zF-c@?8IAue+yOU) zv_6AVK^VqEiK-|00}h5J)+&-NxISdX+_BYI!y;!jjDUVue#Mhkz6i|~zjjPv7 z1j*+N7#$v6rn^Hnn`pmr8?D_4ibYv9|J}ETc!6UgPCptVP5eIJ^z5B9H1Sgf1P>6!Ec26$#@U^Zb+Tr4~F9{pUU0KlOzr z=|LX?Wg;4raSog!l62s?#D1h6D+dQ28;$3Dm<+QC*%}Ijiv&&2CU@^JPnrt`g*aOV zMfYP~&~?MKh6#_qp`p5<%;~(UU+alYJ0W6Fh{4Cd9I-UglEbMlSw(%fVJtY;;d2J( zY7*YKVM|gW&NxDu+sr+EG-J&7)1P1+ll(R62E>Pa$ol?c&26+({rTP~#cO58d>p#fn;nkFiGi%-*b|$yH`7&(Qp!G*r7HObUZ56 z?PzBQT}n-m5v9|j>qbl~dsr6cN|r!uh;@3iTFi;KYnv`w#sMq_zAM+@JSy4`!NwKBY-U9nxPB3vH{4`3uV` z``hD>21e*Z;3ewLO%U=cG6bCezq_WFu`e!Q=mvrI;y-mZ9gD<=v&8LAA6-4|ZdxjS$>18- z|46doykEhc(yFSm?H1yygSw1bOw=z1uHKq&GK?<4)jREc^xBzIX&xJ$f9ZMVNi2Tg zz(VN9+l+GYZUj=)|`CRu+ zI7a+ZrLa~2D%*{Xb+294vF~M}i4oW3*#=wj1SIM#%wxYiPKj(*b)&gNA=G0vHS?I3 z7m2L9u_u~y^7VdFeC9erh?PMSd?-U3g95&2w-h2xfU@d#v`?R`?$3xcDEquOKS=-; zL{73T!UD?OzgmVgp-16D2h^FXZa1b}DLZ@@nzew-N4zCUELQmVXKGwsu&zX@<}1#B zIvlA5LrM;%ZNWRe>a^I?!JIhw$ zmG0j$JsKWVa(mZJ^{3tXo$663ukP%A?A|LQy{JkBWfKIamQ^Otbs%KFuA)ZLLzYt^ zRm@_(=Uj8|B)Q#Ab%UR9ZKJpHCS*8kRq1GZg>W+JS)*1w#bv$VDk?+UF1lg!>0Q3D z+gJZ_Y$r!yFd2kDD0FChmyt@S;d+!#o8LuE8Z@mo$R)4tbo~HhW@@bO<)3>_7GTi%gLpz{%2yOv_!mdeUeWk#$y(C5u0|L{Nb|Wq{kPxyVN}ge^#7N!wvuuF z`~yVi@}x{6WD6}288?1A!LFL}?4T&m>i_H}CtVgWD{JRdqWby-*38T%Z?$ixJxd%Bf+b3;ibM~!9gW%c!5W&LcE+mcTn z@VUMuR?Pyt>B_N2=QZ$(;4#36UL+eBA0PjmlOv^?A@tz#ZM-d`Yop<0Zsdg12Nt6% zy!a#^j4w~`QZLi)EVp*=-M-I=GN-K34>uHF^W}9{#7xzDfa;{9p`oz?1#^vbC!tkmy-_IzGwB zTSIm}m3`*5H-qteI>9*qFluQ=jLM<|BYDrFI!!>@*;Ztsgq9SFm-zYlo0S7)m(`ex z3U3WVic3-KSZZ;KOYnv(z9=dvU<5BpdjJ1Uv0;_GT;JS;+|sXq(|pycN-~(qHt_8) zFOLRiEc$UzeIK)HcA~BhJW=sQWikj20?-Ei0Qtw&`u{Pubs3E(*E((V!@q9i>Y+G> zrD&Xa3X&Pg=7>+0XR(Q6^|HQ7_AVOd_D7E-_}}88 z56{khv5aax84`8br;=?-z>!NlAA2gUUjY8dtrEHt&gJFmYW`6hqXf}0pdbaemy zhf9LA`F|fVt!n{#B+RPl5b|F-{C_Cf|NrJo$SipzCH + ## Error Message + Fill the error message using [known issues guidance](https://github.com/dotnet/arcade/blob/main/Documentation/Projects/Build%20Analysis/KnownIssues.md#how-to-fill-out-a-known-issue-error-section). + + ```json + { + "ErrorMessage": "", + "BuildRetry": false, + "ErrorPattern": "", + "ExcludeConsoleLog": false + } + ``` + ```` + It already contains most of the essential information, but *it is very important that you fill out the json blob*. + + - You can add into the `ErrorMessage` field the string that you found uniquely identifies the issue. In case you need to use a regex, use the `ErrorPattern` field instead. This is a limited to a single-line, non-backtracking regex as described [here](https://github.com/dotnet/arcade/blob/main/Documentation/Projects/Build%20Analysis/KnownIssues.md#regex-matching). This regex also needs to be appropriately escaped. Check the [arcade known issues](https://github.com/dotnet/arcade/blob/main/Documentation/Projects/Build%20Analysis/KnownIssues.md#filling-out-known-issues-json-blob) documentation for a good guide on proper regex and JSON escaping. + - The field `ExcludeConsoleLog` describes if the execution logs should be considered on top of the individual test results. **For most cases, this should be set to `true` as the failure will happen within a single test**. Setting it to `false` will mean all failures within an xUnit set of tests will also get attributed to this particular error, since there's one log describing all the problems. Due to limitations in Known Issues around rate limiting and xUnit resiliency, setting `ExcludeConsoleLog=false` is necessary in two scenarios: + + Nested tests as reported to Azure DevOps. Essentially this means theory failures, which look like this when reported in Azure DevOps: ![xUnit theory seen in azure devops](theory-azdo.png). + Adding support for this requires too many API calls, so using the console log here is necessary. + + Native crashes in libraries also require using the console log. This is needed as the crash corrupts the test results to be reported to Azure DevOps, so only the console logs are left. + - Optionally you can add specifics as needed like leg, configuration parameters, available dump links. + +Once the issue is open, feel free to rerun the `Build Analysis` check and the issue should be recognized as known if all was filed correctly and you are ready to merge once all unrelated issues are marked as known. However, there are some known limitations to the system as previously described. Additionally, the system only looks at the error message the stacktrace fields of an Azure DevOps test result, and the console log in the helix queue. If rerunning the check doesn't pick up the known issue and you feel it should, feel free to tag @dotnet/runtime-infrastructure to request infrastructure team for help. + +After you do this, if the failure is occurring frequently as per the data captured in the recently opened issue, please disable the failing test(s) with the corresponding tracking issue link in a follow-up Pull Request. + +* Update the tracking issue with the `disabled-test` label and remove the blocking tags. +* 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 intermittent failures that 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. + +### Examples of Build Analysis + +#### Good usage examples + +- Sufficiently specific strings. Ex: issue https://github.com/dotnet/runtime/issues/80619 + +```json +{ + "ErrorPattern": "The system cannot open the device or file specified. : ('|')NuGet-Migrations('|')", + "BuildRetry": false, + "ExcludeConsoleLog": false +} +``` + +This is a case where the issue is tied to the machine the workitem falls on. Everything would fail in that test group, so `ExcludeConsoleLog` isn't harmful and the string is specific to the issue. The proper usage of this provides useful insight such as an accurate count of the impact of the issue without blocking other devs: + +![issue impact with data for investigation](issue-impact.png) + +#### Bad usage examples + +- Overly generic short strings. For example "dlbigleakthd", just refering to the test name is likely to match the build log in case there's a build failure, since the log will list the file getting built. In that case a better thing is to use the name of the scripts (sh/cmd) or part of the dump that caused the crash. diff --git a/docs/workflow/ci/issue-impact.png b/docs/workflow/ci/issue-impact.png new file mode 100644 index 0000000000000000000000000000000000000000..313e0fc0b2f37a10b1efb5f7cd3d3a9d6bee386d GIT binary patch literal 26517 zcmc$`c{G&&|NpN=LZ~E_PC2RIlQY3{jS;mlk86(TcGNY)ZEXhs?*_pAG60 zu`_1IkYqP@BgXQ*yxyPBIq&!H`~H2u@9*z?&-wk~%o!KgHP?0KdOq%t`~CK~LZ3X= z;o`W!!NS7A_3*(xLl&09r7SFmW{w{NepB)0L>TaL$kR|qiv`_vaTa)U)Zvc)9Tt|7 zNX{K=R^UCm`vX%?78dTtgP%h!@LXFK760M!X*j3jzZhw82 zx&Q0RiKxU@A)TTl1EQ_BytPlO#-$`Z{1V5WjeemnsEV9P{zHlLxo9x2)N`hP3cJmMD4n$QEAYqP!NzB2%OZbm23Sc65HmtKfm}S2otG_2F@YVT5US^ z(I)aQ>cal2<{{vZo?UJ|%))Xh?l^EUSl(X^x&gdA552^Bu<6Rb*))5Yz0^hCb5KQp z^{$9bqOOU0W`O>3qXXPY#SA|$WXL1sIBKoT1U(Ft|O7V6Zt8U5T7)po6sihcaE9TmT%`oNv!yWO}C^u-y_SWzqkX|KZs3o zh|2Eg^R+#(-|)7xi8sP`LCD`sM2cpr`wQOpI`xX%dhMcocP*d#M$Ptad@~lv1jBog znA+yZ^=-5G^GbDokYY&GLSu5({MI0)IW@#u5ogUT_%_(sqA%E2HCK*H}wQNd|LjN`dM$${RYnsQ$c} zx|KgIj$e)XF>i!!$n2QKgrA;gVfg`aM-lG&8lg!wOrmemz+U~BA0rIw^WkKzp zxSdam@j|d3iZ0mh_VU`f{RU=x>aY83*57u*t!jMBe~%@fNXxRXvy_=oD&o>gj>ayE z^^HB6--v(?EfW1>aMzBDA$CJam6M6f10+6Bs~gyMTZ8wnj({Fz5SaHyi(16Y{kmFv zd>mB?2W`1?y_*O-Q5;E*?H{miftw146(>P&3SWS}mNd<%VJHm*6zcm<)^C^T-}RAC zq6=CH6cOT5pv?EB^Zi59;t5l_>pu?RZh+e^wkuK@kd^9HZi??htn2XE*EMr8YRASa zksW1oXbbC6vFxJ!P6QrS+_IKr<;yr_c{PV_KF7#*s_d^JapzJAb%vu7%}=Pgk#she zA0JgUlh}aV^hPSmrrCYa)g;@92ie6F1*4>>>Rr?uzBBR0 zLaAfhb6B5o;LA#I-uK0uwy4f+G$2%qbvD9V7I>Wyu~XAT6a8mVwRTvK57Io@DH4hn zvwRhA;D>oF&67G~BQz62IZ}!~PeQGmftzObP{kYT5?{PZK;ozgf0^FWGWnsnYHIHE@Xa} zMbws^w#55Ty8amYoziKr`w_a0kFDTCMtjK!$cpZQ=Se#05I;Qxr=Do^p>cERz8wlNUmpjFeJ)^9p+}b-q9*Elg?gnf!<|y8K zYxB`I!OnRGHsH@Z#PZ@-H*res7svH+18_~THm`tjuxB5EArM=6H{sfM&jZ(vFB9jV0NA259*y4aXGyBuK3D)K2Ca@eL9URO7R9O+n?CW z8xvl!@|&U@LJottlGXFXj=(nQdGc>Mi+RNwyly;w@->z5U&+U0lp8>m4GP$7__2>=!92^(OM)8R^JTntDZ1Ol)=~erokq~or-gu$l4SDNrC`t^SKb@L*6479B z{^}GCRQYo@&t^)0!cB>%^O!BaVm~RxzR$R94-qKvb@js9{jgPBPa~BPS9_XT1JUJt zxu`EhmfFmA3mmgZgrqNAuP0ERBrA0syVqzUmXq-Hyh(t_ybwdfj7!r{XD?j5i%0V% zjg3!}ZYkyT` zvii?_zWv97s!D&9)p^|`?_pg=3)Lyp;&10^{FtDXUbq;AIt3HA9FIS5y1BgBTgvy0 z_j9AP_j#$9M9x=VwOrQm;k#v^nYf+b@fn{NLgb#s;fp>GPm$i05c4vSw)CQuuW98l z|FL(Ah)5?TQj3Z*#ypThV8y-bEWv2TIZo6t9yHaBhySe1Sppw}9c6hh;rV!FdhVyg zwT+AFm{MY(fyif83ypI%Oj=$wJl7_!`#hFe&l>PJ@d?C}n%Ky;xm90cW3r_d-b4q4 z!twCwn$NR@NZaIaOJP$$D_EU5WeeztlX^!F-u*az=PdA2a_B)OHDH0(m+t2wdzvKPpwWEl_JYPeD(2hspfp)sLyCq+ z0PyLqNG*R@KnPN69!!T3K&lZw`O5f2Cs9}qLoq#~_FZ3x{niCTCTW5k>Hd#I2j zKl|hK%&!j>p>s}ME&O>7I+~YBozUT}(#PBNxv57)UlX5w0VKqvP~S?kmOg{8xv*-g ztygfaa7oN|4Hc|p(@W%1C?w2D8fp>`n?868}Vev=TR z=~;uvM7_5BJldkWz!l~v!-|N-+L&xNNux-Z|Atq+NfO2YlfvI=BfOu0p~6#_EcrRZedfPM z+}-~AB8A%(HSnhM(ko~Cb6>CE7_cmCsWwrSd;64=nNPy2d5L1}j|x>~cUmHF*B$In z?nrgTJ{B4tE%-&XZ9sDlJ|=K@2m~k$M9O+N4>>;%P7ItE)od>1>-1I`^=_5yAi^7< zp^Dod=2TM9CyrQoRO#zT7*|&tiqX}&myAv9%9+85OH(rhgD0e+I*@^Ok!b{bSFAmr zt~iWLIDeyCgW>^ZqsL(3dDP@=FjeP7Nw^;zIN!>Xb{B1-W&0PMK+I4Y1>3>BFt~_> zF+zu5F*nL?6Rx_EaMs*2X3(i2mQy!8$$~DCpu}GwsqUUNj85%RMjv)5 zz^E@JoFol@MUOn++-~cq4)o7Sl!cq0<{L{DlxF%CA_Vuxq16uQZG%)}N36p&+z8C) z79U$ot~*(j z#m1(7_{Kar`}6Ep(yfY3pm;7Tt{$o)F^;gj;_RK-h*CJTIs11B^hRk}RItSwb+Bc9 zNz{wg&TZGHBji={SLB<&zHeHg-G4ro&;@k6pe59Rhw_Tz9H~g)qFc| zJ?RO=2cP6U|A|qL8o%N2173kKZ2QG-AD9+>mTjD7;w>GqaQ7N=Ov^Ns&{$yn#JX|o z`#aKo7M7n{Nc=X7|+Cr0wmHrdXx&gb&C-$dJpQJ0834_Y$YqRi<_%27|{!8;S6lZ3-DDGz4 zu}LdahMs}CsJoJnlwlqev9!g;OBWFc2$jg0@@)6OZ7EerW2y-G;XZ7;CXE|!24~BW zo=}GD1m!fvol7EkhP(M#Sia&sE$eUrS`CxMReq|$^+ zE5&>*;4(YVGNv|r|Gmlw{JT~DUl-$l)CR-mKyt?(=%C*YgHAK0{eindhx%agFBX>X zj_104ul6H_+Y~chfO7J`Y(f8Bcbdg{trgwd$xM5S`V#;&r+u=qg?J zpBPdPq4fJp8e3p`TVQ3#n}`)nAI3M0f_R~m9nFb-a6m~{=kFhH=H-D7H;@UxpP*i|do8Z$bO_&!b15f$Y#>{aCh z(H8Z{UY2HBRn|CUxd-HKA-xR}vt2cFKVNN6zG7#fzi5s?rB_FWuWUm5%R&`ZsS~QM zTt2Bx@53z5B_=NUcW>vcZ)`*sAh2FEB%{iA#3wqFHQQ87L21%CWB%Y31fIx<*$K55#fqrVz?Cp>qIAyE zhw%%OlXV#)(hE`ck`GPB`*6~BbwPGw6qR1fQ&SsF_Ek)5;ikwHKf1p&bF(T%AAa=m z*wMYId*?>shbse3#H$3XeO|b9wyYtXY z``wbM`2A})p?Z6@$aj%H6cb^vHl8@U__W*yA>-(Qi;?`D?wGlFr;j^IK^w!)wxE-z zML}Z)HH|!58`L>^q7_2AjuF-BRaQ$BEi~5C8FAMHEw{VGAYbAiE5N}azTLmIH^pGg z)65Fr$koo0cF)*ecj3lYXNu`J@D`dQdS2wIN@8+Fi!kmtLbQSIQO1L0{ngGV&S;U& z-~D;$z@1U=mX6?t}LnwRk* z>Q&nhO)@;}j-Yum?)x-O-TPF6YgL_V{8^$e7(yM9tNL_y#I36f-hYbs!m9YAOT~lL zjNN**C=N5zJX2JZaM2NG_TX5q`lwe?Do{g@RL zA8LJgXfChug+>_H@Z4{USgt3MoI$C`aGD7#{j@HX@B^h#hgsysL+Yz&RUUPig}e>>0UB8r9S7#%^(U%@E6l=8o)6dZh@y;iZue8 z1{B%H}$?_XG8ck6d5F)c0`3W1_zgL-Weom&-W(KLD^J-qlzeuGW<{mmK zx|mjAi@!A7BI)n>;>ksJE$sYVM7e*x=`HU<$Sfc-S<2Mj@bpFo>?Oz35Pe|9~aLH-8ga8@d%4d(0#F1 ziZ0ADHcon_aXP3L=Kl-n&8)8`3y zFkEza*m(rSYYR6najocjT&qPkq72Yea|lxHl9{sPqVa%|@%0Brcg%7*@-ax1b;q%v zM9c%JXOwo&Cp53YwsI>J0{5QI`g#dZE;g0i^7$q-*6y%fC`xsbkN0>@`uSU=o{rvbs$%3Ze*`+9~yqrFo@UMYtW z1si+Ll+pM#UGiF%3~3NdF2)Dh9PwY8`^Fg?`tfzysr6bfTtg%5T43f92cj`W>NZ;o z2^;~F;etBgke4JG&)nQ^5*hVgbT+kF!`{F8I8XR z7Hh{i?MEKt^)Xd1>=;+Nh)%3NH%>ztAI>2J4zV<+un#KWQj`PS(}XXo+Q)YHKO2z( zyz`!yT@s0l%m-L9AdwH!gZrocx1I67YNqr1caAbUTmdm8gGyP_eE;dir&=$Mh(JY^ z54uuDE^Gd%>r0N#QEBd$tW-H54aWnAQ zeBPfmOPJ&2z+dsnKws!kM^DdS1D#bydD2P*^~afFR@5BKE^rm5NvxJpG_*}}{OtE; zJ7;HCFe&2aR+J!hcl`-ILR0vWYH_AM>tLo}%)2YYjH&yY33)b>+m~>+sx`J9`-bG!#@^Y3$_`=ceA#%Xeest3u$g!%upyKe?VM*fdh_0?0jlZ1F?Iz>*51p>;x~Deh$h@F zLMQUSTWfcl+}o{b%eP$L*zJxt;x%<>N)yZ0!8L*I@QXpI1ss&>yJDd9FU5vtPjb=C zDeXzK1?52RX&OG~TyZ3d{z0mMgwkK;4Qh9BrXHQpl~|1}8}3ZYJ+@iW-8;Fx!P@b$ zvtO8M8S1-G+6a4ZGM-80qv5OqbeWV{H(vz7JT|)QK^DOy#g3w6S|1^mbD%qpQBf=` z?nAQNrT(N*Oh}r_w<^&eU4b2HP-Z#GqPPbz(+L{22uqnryT7`Zx#6wf`ZF_xhv-0tD*1~QqbwhDlJEX}y?R{c=Xo8au&NbG!f?`nypPX*^a z#>VR4_}6O3hTi9SIwnKc`%b-M5X7cF3v)s@3Zg+z3prI{mqF+t2*>VrMGU#ha z#+UOjm8wi_^?sP$P=eVFL7FwT{@C|c1lcZ;C4RVK1~vOgrt3{x-$*=h#|O{g*jT7k zH$5~~-4<5TfgX5R7sz(u195NriLjKdSAoy{S(|J}9m4e~SSn zsnvcD+vFoB^Upr_`8XP(`3)=MO8MX*&sWRzxUyqQEb3{BVlk0bugn?)y4}ee5ey^R zx9Fv=hqLkL?cy_=B}D^R50yH!bj;~`@jH@Mgei1|1+3RGgG@ibrD!p+f^Agvzw^Qq zwCu=F)IB2--553zqF#1^>%0m~%BqskSVn!9%J(PA6b* z@MK?&^M8_q|4etLUehjjc@1?S4PDxan?gZ};aJ#0N$ACn<%Fyy^Xzv6_v>%YRqO(5 z$BzRGkJmkoTcQ;0XFe?!rfn@uo*qy@I{jrOq-%VKCK60Y6n+zHzVD8-6j)O1R?;05 zb=_KaW?Bo$=-W1qz7H&EMZ_2LJu^qr)n@J^tqw2!t}2L$^?x8Hcl;%GzKJbV>fGI* z;$PYj#~Wu_%UW)frh1N~0oLCa)l6PnSQerkWQOhGN#oRRYM*oNWkb2kV5RMszE?gZ zb}KoTGE3u&PIj4$|C-+||0JlX6WvH{MpI_ea!O)*K1w)??8;;=#8(Z?R$j3#-gqkL zi^@4;B2f#tT29rIN0CNlXQe@p9Xh@rlAOfx9pxKtXxB+Ki%W4JfJ zUwFYTsL{t{sK5#whJKpgIy5_*gOI3e_K}o{jLkgjyc_TDhVE&rK9x&IlpzO{Yh@`+ ziaPEU`H2sSRv$ZBPdeJ8LRIP;BcP>B3<3qE1eUnB%eF~kb+%`?F@wJ|u^qR6bKXN} zHlPn*#_NZ(+NXX^zB?P%oKEYDEan^j$P1m5wYb({VC?8mkEcaUv(4!_54U^Veep~0 z=~KmPc)KbYnDogj9g30G`_5>fwoxNQbK`#>!)@VFj`6$G*)V!jy=SnnT;RnZ66=Jn zE47l(RP>LJC{UPV?f_-&)l<2D_6?i@?OIP68ha#~C6BG$wMp2$Vp1{CDd`IMv?;^C zW1m`Wsz;wtE(ox^kD2cP3SRB2terz|lRpmLe-Etsx2BJmo_B|K>IS60H}3$d)bx@6 z<63AZ%>kMA-l3A5`BCTDU;8sCXQ`)6@Da`!lHf8WgYw z$jQdLVY<3I-%VRF6;y@OvT)oEg(P1l+ou@YJ(C|}muNSpSwru{&?q|0d$^lwq9Qhi z8zvC%{rS+AojE&H`?Z^}7>f{EJV{?*`wq+Z%G0SGMqRU4=jAokq&K`#i{9vpZRNCK z-~MiRY+&p;2VwpO<@Xm_tt#QF==$J9-!H=a+L?=Vs~3})x&g~4>!*=pv3=UU~GsODgG zTepo+WRY>6u)iBQ-%1!P)GLu1lW%Ri2a@=l-Z?kl-Yk`aNWq_;L%ux&@$uuksUm6i zHVi!`jlpc(*Ur`%DPPmukT!NrbxEExw!!DI~PWc|z5wBw_{)J59Z zXm1jUF4+DWvD5uD{~uwvHBdJQF)0#C%CUH>6WwNg4O&g0!9_8pzuyocj@;g=iOF&MI7iO&TLokcgsSei{RnI??YzJyUZ5qam9+t_MhwFEd}Gt{X-yo}~1u&`1i`YaXs2HXbJ-s)PX zg+N7bwgK1}^!gH?O)hMp1#pUgHKn8xx4wh!H>PQbmBW1>&_H`Nwq5Yh4^ESEN%8xA zCna+4ym&Y{zC}Fi6@-2joqblc+rO5>eFeDu$icleL|KH-!2DY}!YXo3Ad)QBw;)dJ zPA*C+zT)5EI(Y^v^hg!#TG=Pz%+6EIj*--#(rpQOb?h{y1-A-_3@kEM&8nSjnWckcOJRIw-E|8)(wtUUy%zDg(7X1%5iv(LL_YS z4)3pp)sbzOIW~`4-tnC}>`(UXfP!Bz@7~=m=5|U>9s_TNx~JjtCfw)f@uRqBo!alJ zDzD3d+sGSxhkyJp((1!@fBN~PU3-6ze!XS?@d90`op!mrDI$Nf0{->+L+O7CsrP?O zzBlsj;GM2PhVVO%vbx8^*SA}fUg0knwpP#4KcX789PWPO(yKp&vU{+53v!hx9KbwB z0X@~+i3JrGI`CS{R%$PEwY{lY*3CnHOq^yFD754p?YaA0^Mq19b+e32k||%78$o*2 z;{(DA2nZbICR5*BN@g69RGK{6dg&)$l1_46@wuc^>QYB;TEB$asvj|d9%7j>a@S!z zFmm^~xii~!9X(vGBS^S)7BMbi=2cq?Q92q8s2lcR6C-L6J|j-DbK`{;wnKP+%;x-u zUiMO~VKO*tQg3H@%Zld<8vNoL)U^b2+J2f}bUURoKh@t}Yna{BE+%2jWIQM*CnC{( z@}C0h<~RnPy2*AVmh=~VNpx1Wva zd>1x)L*OKrdCHgPLH5s9!VCR}nT`rO4+OWA@^5MG{3L%!j{#3gl;7W{4)d?o`={U6 z@oM>`ZK2C{_? zyc3%TxqndvP8yCq|q(!kA*=`g#s zrfZ&W?gp@#Rv!f3|2by&-x}pr(1Lhu;a+x-X1`S`=H(Mpvy40mtkdG$fDZZBRX6k* zZJzuab{hCXcGRzHxqq^!s$mxiUy@+rdCNykFm~G1=hs|SHxvSgBTNFDpI{)bpwT~jmYGKxp^3(UadllL4wS@SJA_I0HKl#XX z6|8R}x2r{Vb~D18emqr}TtYM0To9O;dR~#}gz#IgG>526IGkfW$Y`f@1}E4;CW5;V zc6@&|zU=B$o=STTSqK3c7Z#$=B7d^AWFrIvHOQmHaMZf;sT%1ny2>Gz<3)YHE&Nk0 zpKCe2Bq*krS8ItidfMDA(KY0N+i!O^#CZA-{TfUfKG`{T(0C?++yWjGi#~U&v8BSF zS`*`m&jkE5?syJ%ptG%^?0^T4jfZQY1cq*SLTJ$Ql>$jE5#-;U*il zwC9bufCbY!7+n|i(0Ie*?Na^kSp9Wk4{3)XUNBYvv%SqyKXLrGfV`jfhM>M=>BJSV zz7yC^o$b-#%aP?p+MUp~-oTRb|D zUqK^Oh_@zAWXBpG1tUy9)}=f{REEuX1k)ccwpj5!G0zIe!ZY-l&IS_IaKvbgVg+?G z#VQ3sX!7)W(L}jto^5f6Cp~;2m_v%?rz_bLaA$DhVh&Nd;AGEvFJ^zLKeix84$7Oe zeLg&OqOBpBvuLU2;`LXOPanHwD(|!1Radn%A+78BaO+9G-0%{T-;Z;7-bGb8pQ4Go zbrt&KY4aV#5{0?3Y!o6-dNaHQPn>p18;aySTWuvlB;}C0IDrf!u#-er>h{41cz!tR zQhH%4vLJ!VnX#;`&*>vh5Rd}H5hJVXtWRD}|R;^^n@cmkx zFw3j)dGZUqs#q2N$GCwH|8OcBeQO|1fLJB{0)_sQt?LPWjE{B<%2OT_6C7}YMwQJ2 z=Pz(0$4q6hYZkG+aIaU7PjvnM(p0lCps*E~-BAFWF3 zIVDOJ?2>k(I)a>REZnosyenWwSNpE4o9|Y_#1m6%%mCQoBj%SInAB@E#+C$KA}nY* z=L2TM?k7rLwW?RG=L2PX^V64ay{&alo)`^7ApgMy{KOP4tWpMSh9<Scs-iw>&#@CQlJB5n>#Y;j+ed?lw7r&O$@ z^Mzci=;qP!FFO&MEsAFf1|$RV5rcGjWwBdnT`5kb%?V5IZdLvRpX;~Q9sd zUkryA|D5>fRWkq1>PYU==bs+0m6vkPJaZ)-V#;0n^cHg5BE7>~Il)S{+eYPAcNQCJ zIHT}!^y?kh7YZtOhD@AuEVAr4cbBVVI;C%s+g*CbJfi2JNjnIXxH+h1n6@aCG~NX# z1+LPR#lsl8kCt)k5T(QZS!eTlsyP-6`KI2%{ml8|M8OAGg2vG(SesdmvGOj#i8^3E zt#?8`QuKmxVE(!5(%AGW(My)%aGn ztQ0`n$~E$*TCp)*ju(Fq-8=aOvj63tX74Ai_WII=_*y?ifF&`7Ga5G3{r2`gK)3}< zzaXRPO&1mG>MDz=Jy77TO{QAPp^M~doQno#n-MtCmZO2B=2@!pg5qIdd35C<9Qpj` zd?{_7a(cSC?*q1cwwAneX$*A9cTaa-tGMz>%e;`M>E*4f^q+WT{szIWe{%4v^~8A2 zc6U8~+GghrLv`~2?t7T}gfeCr+5OkuF7dSZ-uZ1=KjZ=N_Uh^X!dCxxn*jXbWc{A3 z`GM#F@CTkNKyv(l4}X~9xl#!5516MdygvCf4XA>?WHMF)J}4rd`paRZT0p4pfPR0_ zjzL1~vQW2S&SZ;4q8KG288q-8GlADD24ft+Yi8Na^D>um#4Ix${FJ^vfp?ZZ|&@Jg#u_ zNNVvTou8A$i9bfX^a*)v$(9&qs%c{?VdteMEzO zXshM<4vyg;hyr<&Z;SJt$=^2)TJNKGhE)eETP#pFdjC?g9WCEt8+bnY%y%#R*559Q zfAK~0qS}4${pHt`Rt)ma)xrAmWv+|G@Mm%u|Fw5P9QG?QRpK8z;lVzY3qNFCC(Ha& zsyxajaQWZ-(FY=RV%H=r~;-(b40zmEvDy%t2&B%_;p$ zkBY~i5e}P|-t(oybGM!)ueJyOjE9{z)5-KLqg(<@3a)^4>p{lnxH&;z_U~gPa(5^{ zHm@FSK0v$1FXI7vBrgVr@7(@h=R(@u~QZsw3#5-_rkG9 zoLU)NHN2gCzo5(>x5G}cWH%g_;ytR{>3WU7(AWAIlHUIP@*{aPZ#E01a9ZdhzhxTi zjHQz()p2tQ90TEFZv$3_LpgKKBg$O|RtZ7xHuJ1MiZM-DRr);b@4x6dJ?5Xq{~2tk|!i6;23l_*vrx zhcmaEZ5W~Qc-^%%`vTFz)=^n=<)(PH{^oBF9+X|auC8VpCH`|+0?81UcxgnQb2)G^ zE{raNA1KP;@~B6jgA-xH7kz`@fuEWrn<3oXyS4t?)2LRk!pl{1EL0!V%(QDY?o!s)unL9MW=9nFhw?_4dNZ`@NC&1LGk_oUj_Zh_Y+xJMgf z_ZhnV*eIS>#;?#d@9kUf|L?icRA5B zFyU^)($7jy&s}+2EbcMniZRV2P)Mmmv*vrZFg%l_Gjw!>>u<#Y zUFU7iaD2dt@#+&V!0I|?3p=egDz0lYt3-!CqfS1`1SS^T|4ugCDr`DeE55%mFAK|7 zl0E*C!D$bZ`imP>4t-RPS$bb4IKVr9GxBvlz~YAq0HY?#(n3xgiwW;EX}*1DgJNp> zlPQun&zwmNT0Dw98MmPIlfyQPbkxV3x1OYiAYc|4o8IjxvP6SaplhI#gX6yt2n{lI zGIq?|Z-Lh(VyiOpG_!y41;$pgra9NnPn*RVCgH$FKG&$A6ZEyO-FXw@#RsNDKr}@u z^KVn)oqzxRZPMd>!c*TxA}Lm+JNbLm84J|b36@un5?RE}zjFloE$$?$iBVKP-C+qg0|1D( zge6yD$Z@~POVQeKP`JnaIYCHAs^{ePKr{7!vMJ1RD_*a7Ln@xXW=9~s*l!7NLHib~ z<=Uvf4;pt~+$wDB3^>W)5zlr3W3T9VT+#QlqJR4eidPGJE=+OEz2|B{`7SD5IbldF z9|H!ZZ2UI7OYSH?i>qa|#%(;n)1NHjyoZrCfO3HPj4RhMl#q^_>7%p^8E`T-(D|ia zquPk%r*b5xTjub`x7Z&ZYZT~16pQ}yQbYh*BE4I2Zubx?i+Nz)k_Re0HN>bZF;zKdLugFLvUp9q3w)K2cju^x zEbMnzjB^i@CG23DvHcQD9C225T;Hr0KJTrhSQJDlln_)qqq%YJAo=3-tpLd-S zZ<|5VqpgLUu9-a4?UCDy^T=YTA>MEHht&FLPM@{e8nT;~yL(r_iV zif_#L;WGu#*zat#*r&ffUMXV^vjq0^>5n@rISgPJ@7eYS=L7#^g zRD~A&x+A`R9b|~Vs2b=#=|UA939%K>CN0IouyT~W#e}out-i=er?GpiD%D^1DAz1> ze(PRj0qBwGcmKc{3W)n_{d5C=Au>R-2k3v9bCAzyN-1m-Ehem$`t20=zr?YB!_B|U z5f-}l_s~MiThPh2Tdj)_|2iSm+^4CeldAiYYXS8B?HBc0{H|GB+v^nH13?hERlPg4 zwdieQsh#C9s$e~&M$D_y%V!$9Yp(@-e-zO&N!+s6p{h^%dpxT>1Qb?pe`GI{bws#W&bOtzB3+53m}fzg3omDI7k!uE8N zXqX)$CBjG0V_x6bF=uS<$R}F!cnul$Djy&icxo|!5eLUrLr(JzU-Sg|u72lEF?s9Z znjj%=Vv<24Ij=q)BM77!8EE&o9pZgg(Hm9=X^CJy#UjPc2W?xlgK@jBmTrCHSt#+K zyT;e5+|oeTer}Pkvgki63$sGEjjR;&ZAXTzomPg(h7sL0G{DX!N~B{_I9Ls(rgQlNp5H;AkkbHX(C0= znkD8`1o?F>r4~cfh-ya8ISa(r!=PmQgH)JM| z+Kegf>RY5Yl2Bz=&PMxr?v$|XS|8}+H_?SveATy3oxtVU`nhM>9f3qtUC|@F4sy2Z z!Qhne7Zu!Y!dHI|-R_QvADqNC9T*#blN2Xb@(ZD%Xx0v|z8bPW*qJ$A&2e<_F0KxH zI>~%d%&*1lFJJ@#XAC%3)ewlzB;^O)X8Mktkr^`ytL&yx*(NbCBQN5U*X|}|LY-jUNgNMu)c8ZJrM6FqFOZBN?0( zgT-Gt=7cmVPlOa4dxuft@llv`V|9(mCnl3ZNa!N_YNspAV+Nz58g&*wQ_tt!=N8S{ z&-MKlIOE!bp!>m-qrX9UqwIRp7SEP@<|a!4LHdwQH0bz zJw0T}W%{oVW@CY}DRth3t^8jX;(b%cu4jQ{X~|?su?7DsV`Yuwj1C5mzQt=Ym7T7F z?BwB&DiTN3_A@zTB>FHF2gV2|p|hg(1Y7V!#+=;3-3!K6VqlY8F$;9j%PA>PdO;86 z)E#dME#GHBWndrcLvW>ZUMx%AuSr8ha6~{n$Rdpl^HSUv9RwdvX)y8j^z&YOFa|)i ztie^QQeTAr3;mFJS19{>aFosoNFud4JoWq{8m&wc#=S+~d-_}1o1D=r^Fam+b#-s) zPYv#NT(t;Xbg%dQbmP>KOyj7c{(b|x2`c;`y^+w79N3nw1z5XiZ;>aEGNcgXJYnQ0 z5g0A{#c+RiUExrP)yz%OMDR3tJxts~i zui!VhVj=dGMW+zTp_A{JGN%^^+SIR+-jOoY`*ISyuV@(0;>SQHMX&(!9GLT{R}n(< zMG-@xJTFt~B?0G_oF?R6zrN@4O;qzrlcG0{UmV{G%v~ob6+CHAi#w61-5*2SBRt-! zzd8Fug5toSE$%OhEgIv6k&opugQK3cz|P(4J8u1NpN7zqVdSkKHRAne+>6e}a}A?b z7-O04TALBaU~OLmQFd0V=5AGvs`F@-U;;$N^Y5@?f9UIBwvP?=4TzTr`uv0D2;HK~ zTCR0)7bN#iCaqwT=JV4Ksf7HFr;G}WSbjDF58#wQpr7x2uLbWbk@he#6)I5J-=%~p zJ?M{<7xwOn4+rC-QWS>|CfQa1DiH5Lg!uhz+f9ONEd(hM*AxVdp)YGWv3-XJH4t_H zOc_x3#0Q0X?GL%3P?H`}eAwJKyp#tH*1^Yst%Jv8?SSVn=me)Q!hozaIyXQF7%#93 zeWmhW0~&zW*8UbJFj%Wxt6O8aq_$G1V!@}7pgDG|p8xDIzCmDs9VmK@lSv!1+>i`w! z$6A>O#@}&A4{2II_y>8x@(mD9|JlTUQy1Sm2faWDmr4k)fO>(!nye>ew>qOuNu#@Nnd=9P z<^wsvV%7gnJ85DI*N8daI%>OICR7_qr^9x`7nEfyW=WubkH0Rx5 zYyHKZC^3ywM|&O539?#4fBn1}^OXzuLN5NxnETt$PVE|}jPHkBp#U5THZ8xlNTZ&s ziesTrAeOZEZojY3&s&}^zfwH6#|$l9ga-+?LcMCwSB>#xxfpe1hYZ}DkBUKMBdNg1 z#iTfzP|p+j>9etKuEB@*014*3CZ5$I4=EELV&3Z!H(}S2W>w#yPtnir?j6Wt#%Po8~ z%XaYJefP$gffFA_<=XGH#-|?^1t34Nv^sff&x{sozPG!}QF7=Wv$fhT31N<^t)|2F zrYf9QkRaIp5CE|g!eX&-w_UF8{HyyBR)k5}`q84cl6p58q zY*z{6)W-df_P#VM$^7rvrm3c}vdM92OsPzrH20-6l{T|9C39bp%FMzPm()_hnXH_& zq|GHuDIG;oA$J9Z%!*vemBa@U$>FY z*6$l<)IBJ>AEia~oud0$9lhE6u)Wn!nmZ|NGIQjKCg#5(y$@$rbhckTJ7H#NSz8+F z_*wcseE~yO>F6E4lvis{(AMC2d7JFYKt~&9=5%rsj9VI8|4}eJ;;>I)YlC2z_U2}X z$=ZG0eRJREZerAJeyhLakV`Bdx4s7IvZFaaFHZIi>x-^LkBL-O#P^4)CSsv9>!esC zr+s>0z!cpD3HclTc~u?K?T(C8yW(0T`C7UW(dTLX!&Z@S_wu_Ly~!Mr;z7i~NvL{% z^s7BDx2Gv*^pp)BwHfs(Zk4-aTQY5}$w%#Ccb-|g7q}PPd!NqwA%lCopSh3z7CY>x zGT9O74Ih_wmsU+~*x4|A7W&8=ne2He8X4&1<+2c)GPHFtIU6 zu+2i^Y#5};Z=voUHFsETS^WxF?{NTfV|l5(t=0GUp8n}XyAgRcr)pttwuAYm1arKA za}C+OFXDtAI#RF6XQ21`2WT3S*}9fgA9D05H1OXs*TeT&jFzuGxMemOBpY6e+?36d z6$nqx{gOJ&s>@)tsao=8IGrEJE#C%!#W8+mt+|_RVjEqo&6CICB8eRu9gS|i`cxO) zdGhIn$-uPgP6Xtnri~R z;CD9@{g7SJi$;;cUiRii7Lw5|PYmtC--)K$0S(cgktIgH9#!o~Q04AG7;3_X4P8}> zbZOCGVtjqvnS|IxDo!*3MoRytv;JdFL7A&EG2k?^ZxV@UZfx)goBh?`R@3Voki)DM zvzF60MuN0Rn_(;oXWQgrS57q>s@M54ojAw{s^JQifF3(V7vgBqkt(~R4O8KNP|peO zL&&ffl>uAp+BY8w#%^RnZgT6!DZTduAocuO>5Z=PC?i`bb#rfXO52}O?adj%UmIcm zN2uLIRrm|2ZAYns+IIfkrUGO#GJ+a57m(9fHA}WLJjMMok412U%caj)mZsGpvTa#hQ>&gi ze{n4JLa%|OW9MOzPNUh)NF&YvXZ0G4VCwHhAJ}k#eV}Ku0fSk+7-~9hGWdiQ^D4G( zIV`3p(9?kossB&W`ZTT43Gu>mSYu#>pmbsI{_tQAtdMzgjy%*~=ATlnR0})R^&1 z6|W$!ksDs$r2HDbr1WSb&hCNnj+Ob3#gELT3)hEo&pyZGHGTZPY$I|!i@Zs#?bL2X z{p#b~0%R@PUKS?m*?tfC(*;d||6L-= z?}WhwaW!#CdXUW&6>v6?bK5H6%JbE4Z`mwH-Dfz+Ep_6%fTBYAG`8-q$~2zIJnr>h z%JepW?^_Lqk_Jepu0WFOVoHbkO?Z)+8S${jn%21$enLMr1GY- zeoN)JvHG;)NpOrWnG=)ufv=y^{yyeu4-}Bhz|Z`Fc?QAV{(lYg{M`nD|DH4d+vkyg zc8dA`p8{{T|6|C|rI^^T&@rAYk&b=n)W>mfASOO*+h%d};ukU%bUYY85jq23ZIct- z444uyEkCjTuinVQZmwU%prx2!>7dWx4vc15&Am-pnuu)ntG@JLnt>zjbuSW{f{X4u z5c%n*U~!~0_h6jZR3@Bp@k37}2FLB_>k0#Kqt_T%9(~=%nz1vTJ|3kBU}SJ=9mFiO z-s6_LY)`<;aGESu)<%+kze^RQA>QZV7Ou1MNE<-;G%M$-@WqWNc-)X30dCQId0a{KgSzpRIB+9wRcf(ACC#)bUhP$*J?9!NYrnhyK(VqaWJdeK z$H+U2pl|ez<8jV{68f0=MF}V9{rh!;b=WyPFpUcesL*`BM&Xd{g{!0TI^5jMkX)p0 z7Ij$Ag=&2A5+SE7&){HI__vVwgWai_I!(qRZ+{FJ4G4TQ=7m zX>ibxPkUV2WykFx!lL*rKjDJ`CW)u9|~OY^vmhB;?g{xN9^+dl{I$vZ1Bq z_!X4ZrS`4@-NAeCg4GQm-cX1*Oi=)Keyw&g5&x@uvhXhDE5J}_armS0>2AXRBb)6{ zM&eD%#?03Ty-P1Pd%!0@eKuVXlYlz;>JR(D{uG6oV6Y`C__3V?OzIkn`7LDN_8r!W znnv{sB4_R6C+i9O`ZwS8K>E6*ZBK$gXTrYHC5ANfVRleFPo~E(@ueOn z-7xiI=LXJ&37aH*n$k3KoHtBxmM^X;M_-`0K1Prb22aO0KV6}o&BI}U%jkvG#h$e^ zz)&-Xe4?NB)7|~1{wxXJk1`$EBu<92qN50HB-4qzpmWx6fn6@{4c`i0foX;)t0|pU zjHikn;{`QA`hMgyp+H38^rl@M)Ya)U8=^a_|C-0#M-m)}a-tm=C@xA5aKX)nn61Y# z%C2;6E5AO&;LniReK(wSkv)4>&rB2x5_x)5%F!lFBf!b=3M@?XD7;?f8pcn|hCef1nWy{^x4 z;(NHPLcdcqg^>vjzm}>hR9JpP!-PJJa>CDT%N;Owb*57=;YX(T!83H=d^hDC%hD^_ zVP6W#lYB-$M*7%@eE$AQV-p-0w)UshCf>#@O&i@iwR#?0=@|?JV?F*_1LQwqTDZPs zMEwysMefG{4$ZLy@CEUp?a0y__xK3Wk1@HQjnyxsn5ER3W4IcwX#OnMx{SGcl~6oW zEx*puf^Gp9jLa1A9^89$CyPsF%hvW!4saP-qRi3N0`R&)&3cl={^?iZx}ayWn1Cd) zCwi{Mapemj3_SuK7GAA8pXl+``eveg`m3(}s^0N`U-S0Q2C>DTQiuEh)nhy1tP6yE zqwtN@(eyr`AVlSYh#`I5ytHHJfPK&gIw&A_osdJF{(ecEo%1?K(@F2n?3omkfe5g@ ztv&*MX<#@tWe5vq%8zCt4tO5Lz+E%!B?+scQ>fAWV4NSpz*tl=`f(^9A#NRTfKVKj z&?{bO;h|i4;RyCr^avU@n}?7UQdg6cF&!XXD98>sMD~=TWPMnTlly1$P{Sm`VmSf& z$+0uAWCKLzf}VV}+7TN_$8g&f3$tQNTCuQk7P1COl-|dDW?|4{ zjw!fOHhHQ*JjRn;U)cKN$Y&K3qM!;E_i4NiiTN}|o~uo$nXB_IE_&A( z67EA#f+U;4ehqefqX()NG+Vw$40#LN1GD@|; zA7zl#ikczsfOh&m&+%8C*#`X)0_}!M?+oIB+ICxpdvl7hX=E{KowNLrmhiQw_(LA2 zdK@c10h7K>i|26)D(Gub^!FbN43$O;Hw=7>jRDSXd)I0gzpw!l1<8?jbtT}mWTd3> zBzsGLoS1=~sj8B_aWfCZVyizx6Av>3GfUIfOK#%q%Ml&LJw3CSkL0Kqs*@s4$gUx& zqvh;wsL2H#@?sotC@vuSfk57go7)(@FHgSccCYQl2M-mMQ#)3I)+ngkaf)^iEg7?_ z0KE9EaUnv>!0qk5skzI-JVDI2kMJX368!8dd;z~}cU+~oWBH3emui+B(W@z_b{|0{`ID@R8dwuXBX@+aSnSCV~nX6{d z8jn?}l0I-s({4mIzrGjcDHGdXM*P0pKca>x=`XPntfiDak6JltS#ovCj$oz-G>Y15 z=2I{Ae4l0pd?nG?XYMYMsKnRH-DCFJhqIdE$umGrwUH zU%F%^$s^G<@%ad^)9Ylv-w3Pl>^i8H$(>`!GwoNOOp$dtcCzP7E#l#zwPB8c8O_E_ zA{e3-nI8m>ut(y0u+G6)f49<+MZ`>UI_?siyCD8df|r&my3S2OG`kyBlF9%n1jWQ- zf*Mp2*1jo-1n0pzX@!>j3%yU&qr}hieOK)d_$UpydQX(12nIf7rm9%jX-#`J9bY2X zX%h54@#B|f6_?Nmgs{?7S4|r$ckjvD89jFh;$gLzhCu+4C_H+HDPXRr@o~8A5SnjX z;%MR`A(h`1O38>GnjnXqBl^;94JotWjSuN~`-U`7yl=m^cM_|*HKfJrWRrP;0g&u9 zYT`@TZ(nAJl6yeS>7RUhm8uz@Vm&0Qhuv!zigCu3_!418;$mGb0`o-|f?y%@sheBWM*Y^X#)3WPf=Yb854yp=Wu2TKVjmnmsXhly}1%iV9 zTtAbVL0R#rWV7& z7l~)rW}7*{{TF-JA`-|9Wz4MMxVU42s$clyqg*@ImzvFl{msLkTDZh+>}s28@zp52 zfLh_-gevl$tz|cybV#8V)`Tv0lY!o{cKaH?I{2)f($0{!jWSvCMFfDv>KalHE9z~j z)GQdwzol5SGZYsarqP9F$2T#Nfs*m_(R+8x_!1a5lonFEx=JfN>aJEI_AVUY^>bx+ z%q@69vGVqqmBtd}NEMtn)ND~$cV$v|Vg7L}O{6@Pc;!Wh&aZ1Z zsBEi^?^2wgHqMV+vjK?YsTT>dx=0F!`HT zpN0W}`02zix*2m0VfCw&>E+Q9u^z9dfIT|F`BvdgtM#Tz9rB#B5|uR8#qOI7+m|SrYMgxqHZhqOW4L4((lCWYFeG(&DC3Pkbgo@OGkK4kiD8m zKAAMfGilGhtZlMH8wcR7OZyj3I7Iwre?hyk+dJ#SprQr+b}@6VbF$Y){>6YLS$4Jv zTb#n&md7lVGpSltA0e6pFqiwlZ-YQ|D1j(>W1B1IzzICV}A6IS#;*5&Z9|S z8e3MR8er!3NcYKQIEBw}Gioej&)9l-GJ`O(n#+Qx+}FVMf`AO3AD$!(_dTN$t}Kc zW5amJ3LnOw6QFG@MNyp<-ba(K@mwUpjX}XX+|04S7j3%2jbOF>LC3?j$Cx7$l@U{# zyFY+~4h+0xeW@_;j6X>vEDk;=k?QJ19m^7{xjdceeL*N+vHnmpZvQ!5J__m`%7sY_ zT<~WWosY-N^$lXOe(qBtGHh+kPFz7jJWHc2IRszKn?tVH;aF_#GwurSqBI~SmMQt+ zcoN+Z`Dt@b&^M>NdoeL8Xjd9~Xv(I3R%vBS25UeDk7Wm0y`;Fn+bYxS>Y zou-UV2{*Nko?rFkt{}Q&FlEu=1l9@zZ^@gWm4vEIBH5wFTcS)&;=?}hM@{#lGKr~z z!3EfAi9N{<#JTi_jg^2rTI_KhA1F7*a{GfGJg<-~y-~ZZ<+BX8%&n*sd4;wJ%=h-* zjvYeb(yN`a;Ii#1ryd)LXVg~iRQB5Ni)8r>(_G#KmSynI{#Sc`OO`D%QWC7|p{KB4USlD{5qHs6Sv4dexPci zNaQ3{<%w(A8z1n7o-c$CS zU136|@Q(KM%UaB`^+Ik`@_>BS-7k)rF*ho&&J+D=x0e~ph0eRndq~I;*G z&=I{KTQYMyWo0D+^?Bl9j(nQIpD*py7q0Y^fl@@j42y=dDg9tC`saJqsRDuQOq`RO}(Q4--w-!D+J{=?+b?ye!qk*7@ErZ(*duF9-gs z>p3Bpy#DLsBh0RAzAG}lZd*n0kfa#I#I#3?S%^eb0Q>m#vQ=!vK83OQyOTfx=W~1D zE0d4ZT3Ghhp(_8R<=iFB^B_IJ{;pE}X(D2%CaKbmf|W#qu;Yh+6U^uKBLv_4vh*8m zex1S-jaJ(HTU_z2mVbWg|1)jHnOEBV7$c7ysWM^O@mMv7v6uvGLVCqHA?=w^cVzh< zqxk9#FbYor-2iHZg9a;OXwSAt?Sr1cq<8gH*#2LtOr#T4hib5+1%yP2ZTyaoNPkrN zQ#A4xy|aFiiuW)dvh(a^j}&emO6Ht+3poZxw3KPk-(F4{kn!hfR$tp9%S6O5+UcbQZQ+Spu1Y3p!(LJlJ{>v(ZKf$@(XKjrX zP|Q$NN|IKM%+PX5h0vk&X_&l7y+?KjN_ksD9nyzlAWzGS_P2-v`||2SLYucizf*Xn z9iXw-VnZ>uZ=iV8KT+ed$PE=!bU`<#w?QZQDB(!pNlGs_~&9J?a0 z*z$J+9b1z2=S(H7W8MXi?sa=?-W^Y8e6^Bb315a4XuDAgU}M`aRpt)?Y+jXprTWl; zydVvF$o!a(!mGjUt$-r~{RgN$`|Z|$uVDSESJGCnm`+;`vTGN@_W(POy!)eWN8LzX ysRnMvcXt0M@&4aG8s@JaslPl>=7bnnqfxqW$gC?CtPWOCIO*VejCkbijsF1f`Kvqt literal 0 HcmV?d00001 diff --git a/docs/workflow/ci/known-issue-example.png b/docs/workflow/ci/known-issue-example.png new file mode 100644 index 0000000000000000000000000000000000000000..ec4b140e8730d80caa68efa24e655307e8de2e18 GIT binary patch literal 18393 zcmbrlWmFsC+wKbmihC&%EJ$%J?p7#Jq-a|t1Szh;-HN*xr?|Vj6fIiZ-GW1K=nnt= zp7(q@YoB-R4`C)`X4WM0%slsX{jNJyRap)jgA4-!0Rdb7ql_8?!YdGbJs<5g{I4NX ziXwc02vL)hLZ}!cKY+hMHkDM8L_nyH#(V^$z~7_Wef$bRK)~sJc_9wi78xTT$l1ut zNNTw1A7`L@63s01gK8>c0+ByTp?M%6{zf6vR@J~G`jD;G$Q<^zw1FK|K2uU&uX%`3 zueHp~?%PC@?aPP}<~vBEh^B}J3`CZ?7QNdQbQv36PHQ!3eeL=D7__`FmcAppCvutj z{yl|zA$B>j6nsm(P2yL7Is@_G>wUPYp7<~SyTuRV_|IqJQs*E3vyB{M$IDXc5$!ke z%QA#2=a%MWr*qmjp#SXb9k?0(pMymI_d&A6ICyUR;u)Zd*hPHRp0LfMY~x ztWMz?yXve@oFU{v1qhn#k{p!iBG2R%cu^F|vGy{=y-SH0}__#NAt}s6{ zt)Xb69OZd`{!jyX;B!ikQc*RiY7@V){#xsvzlh@vS)$r7l ztp2jBXq7LqEZvzQ2E~M3U^G8fc+hb(4-5PQEHr^LB0BH2<0kUMr{`uAXFJ-tPc!&; zV(hJ5sGo$eO!0O-`tJ}9{FBehAmhnV8A9OjH^jt4hm~4`VLMr+Kpmw{M5LX~>STEb z1zdCt46TO?9EvzM+xCjxIp7Mg8@M}(?fLjDa_9cr0W!*~M?h%us2NXRuR=xi`odX7 zHi-4n)sK8|m^)f(VZ|sx&qvcat4$olp2aydm|StOQc`J>h;N#)d)lc-FNj*B=_!o- zdT^<-gH^|8@dzUL%964LlY@!=Lw^K-qy6D3K4wCd{vsR$bEo%a)hWg2tEv1ZWg~)zBzai z4SOT7YI4#AZJ(NVX6DcxkA`0<%?2$ce5U&0<~Tm?7Y#aR)WJe)^5SdGf9M&aArVnY zd3nY#K;HEsTQ{)Vf#+Wp0g+YhQS=2v0GoxVs zwOB(-qsS@5zvhCQiH)h+R=TC4(=9ck*{Y2|f2ZI1NLrVJ(&dM);5iw+7DA96KCUi+ zI^BX6*KkXiWkXX>lg*^Rq2!Rco~oy;tWJhPTk~sqL$lGudd|g?@Tuk|&N{g-EY0>I zBQLL@#EB&*XrlQ()iPgk&ZcDf)hqH*dM3fI{kmfMJw3hF4*{>zG@{0uFmTVM9$#aT zSq0+fP3e67Y`$$0(bw<9H%6Q56@vy4Cd5*-pp3 z6sOqqu~-T-?F;&T{|0Qb=;BZgCVd?jVaoD;^h-!ilwb2U9}e(~avSN#KD@%* zqxIXjukiPZl!X{MKVINc#OaY9C@e>ic~$q3_F!cuC;?^_H8kqdo%_+y(b2iQ<%Z@! z?8(XB#aKXW54tV%@0hyr@$rGE5Qm5z->}^GCi(d_?mHNX#3{(pFygEXV3v1X*I;t_ zVG2Z6kCApv5Tu|Gww(ySiE#JYX<3rkKc62jRdxam2~B)v^_f^jEYLEbbnIfQU&a#( z|DC6>>Rc3;ac)8c#8oh&-wsz~2q(B;-eGjR?yFX`ac)sv-2GCaTM`(cz;mBlwu|rU z>mOP??a(yw6DZTGUBu&MAo1sw6e2a;9e_b2a-oqm0I+UuErBH7d}RlZy4!h!&BAt! zEn_^JxJ}HzwzE3cyKP#*1dl5DoiA2_$82pQ8^zECMT{u&*qel>#f+tIeRoJrYI8^bapm>r`WD=yQgl5k24RF5-?YC>{k!zV<>j%Wt*eB>pA8eo6Ub<)C*@ z>8|q%-%W2Ycg}iV)*r33k1QK)2LSyqaQB$-F@VJ=v|ZE9ixx|&bZzG16(GxPr`~2I zlpetxMSkfn@}&GAys6%F#$G4O4)spL_*NEs3lz%IeA$kpC1^`}G|BnD?cSRs{kq+R zT%x@*3A-ZekowhIZPTCXO-9hS^m*_(A;u{3U1(+MqQ%`wT4D)Oq{==Gp^sMv+4l<> zd;97)QXq{jj*1#S?{AKh zF2WqpF>&MbPF4~_pevPG@bN!9%Ld4wiZF6?WZ-=a0S`(^TOBR_tQc$b2Y-a}hGT~3 zH5AA`$&!rH^YQ7Ui*vdk3Ai2pNIn|r_3=?_A@N7+5)Sbkns1g4mBp%mI-eZai5ux} zO;?%Kz@tQ_?wbjS7Tv&$R;+ANpa=j4hHlop%ik6DhC6nDFxu{x`v=t475zFYZOL9;@WrpIcOt)3 zK;l+YYjL;OoOA6{xT>}W$>y8_WOyW}T7fr75(tp;~oYu;M?nu2ABiPmd z_K|K%7=)s?_vC|p5n%fD=Y*A9(Jw_&6h$h12Q|U&n49!jD!QxjSqFzm@tiK_8%=$S zw7mcZYOc9qj36Q-qpbvAe^mK^JDsyC1G7q%PM!z8Dh^2F{St?D_C*Ldgg`pcIyC14 z_T=PxP7f!;yB`5!UJrLiz`pcC`YcbzaglTFME#KE4q2geKeTR3mNxrA&zAQE>JhQY z*ebpae4}h~Am7mqaDdPAF~@bVNL=fUDy0;>*xCN_Yhmk0O4{XJVOG%w^(V5<$3u|3 znnPG~qd9e17N50R2Di-cj<#~$IDM~hCVck(s)w{n0QJbYK3Qd>|NWZ)ADIV8d#vs!ETAbRU7(q?f{nJ;Id z0*NkyDyKWNr;BasLKH8}Z3Nvne{m%jLwF?-{RrL|kHjw?lELzr{%h20E3MDqxuPKW zrc^uCJ<*GZ=n66PjU-_M@){~;pG(kP?Pn|Rv`R|I`U1QY{hZcT^+@BUN(=iK9C?vH zsE|5M(sNr}k??N6_VWez=^7wq_N(6)lAGnMdyTIsi`yf- zh=&CCK-ursvz+hI5`6}d0=cfkN~a&X#wgu#(!~#Hc+t=;S07dwp%Y=%rBFA`!?X>^f-S3G{N0UY7O6T9h8^ahqLGI188xd~i^9umpUQDr zoN&K%X*F~WW^|*i>%7;~0I~3E<&QMnJJj2t7(!v|&)l3{?yK4U8bc{Qh0VW3y%@we}190^i>EctXSzC%Cs6;=bPT$<&{k7`6|TyctageK8( zh~01uiMnv_-XUntkjQ+B7&b0+>p{~?OXigRQL!=Dj zu>Go)%e9j!W6Nt9ig^qcp6~0e*?lKMvS}xeK+hbVy4qXmsEl$6g<}B?C(F8tR26Ql z7#tI@X(lyiyVmx{3%)kfaYa_^6;2>kY}TN*uY1V7s|b4K_1I6-EEXTnTU&?o`4M_L z*6C$;Pdwr*>I@<0xGFoH&Pm$(!sUlTx$R;3xguD@Yp)?+z}`ny)^Y34q-^6Wt{2KYKL`CVOJF3K8%aT{^dX$w(9LMN&`WSrA%-=&USa{vnWEQ)J*As#EYNuiQjV z6To@e&N`0Q}s2-C%jwi-zmupwsB3Fz(+(;khX)p;wQyfL?U1H`d2 zfBm7aWUDS*@YfPTaE_Gdrx1)VAbPgm-!qBzdor)`^qI;c%k{CoL=S)fuDw8E;{%Eh z=k<-o!?GUk-FJ$qk>?APP=Ltn$=f;h^NFZXoI7Z`Gc=}xmt!kfw<5~kxt#U{y|+TE zGb1=4ES57Fi=4I%1MFnY$w_>3KER5$jI)su8nGM#k5;hU;mFI6+S zO7kg`%45_6X3j&Usk=^fD1!ZT@8fKXc|E!T8v{l3#j<0lFgRlIyHY9St3Yz~`=+;t zOg2qYMsbPONfgVwcrGfvl10h0LKP#u#2$Z%)PFpv*Uyn=RZ~EG zOdN$B71mg|KzRIYF8Als;o29>o>JLU$}55BawIB+;Zn)nIA6p*tVu}>&A+kSPX1NqYUegU$!Yf{+8?4-=T$S62z{w~wpfCY*jhuyQ(5Z!bBwhH_-b zTOt41uD>t?<51HTL#inm-BQI14Nq_kr-3%Rz1{+*GpqI2BD!sEZdCWG$SnxlXBROLZQ?+n?u3GA=zh}r&fIe-K!O%K<362DN1v=R z=+lOv5~)|#VsKj{&gX6Ko1n!L^pID}2OA^>n77mSAF*=w=aqHM0tb_5l=!DnzD;LtA|bR;FXV% zOH^|7S{B3j_-(5(*{0FHJi`d-Ub-bEkN}^Q=?OKH8uITZ)oP*cv-|Y{%U)EQ>T#>< zGLgf52*h|iGvi`7oa3V((1svBZl)v2A6jsINP9Zwrgwe3LK_gA$;!X%(E3>A9O-#} zXBZk05)+$??eQMjSiz#?)7_{BI{(<6S+~f~hgqnawl;^h@?&B;+zEXz^Vxps`tMt} z{nb_z(5`;-bAe7i#FNrmgh_O}L|#4Nqr(R~)v9#o-Gv&fA;Yir4nO)x zXbyY0l7D&tzC5g0xcRIuslk0MxWZ={f4a0E5>F@$B<@@DF%>P{T==$LfP74}yVvro zgj(kbJJgyH;CRw|@}$K^QW2;m$=da77hecvv-*U|vDeVjP}8@H^YsB(SFYvp*B|+z z+!}ci&lWaS$k#8OwjOqNyNYw1!r@w~-Z3jU(L_ONl?Q2C+)E!fqcWT#iwrSg3qZ$2kPNz$<+Rd6&rY`-rr68uwyQgr*h$_q`IrL!lIdGCxo6N+ zI~9V|ra-ogvi@y$Ol+R>T2g&)fu(fjtbOCeT}ZE}?j8rl%}A|zSO_;N8g4>PZWawBft_ty)Eas!}>6QPsc=ZH`?Hd*`pQSzl zBgyhW!I3=4-))_XZ0}Eq=PrLo*>{WyZxarWSzr#nPv9C}B)VS=VX^wMRUTy-79PG0 zO9myt;7-hHS|W%&-a?w(@nF%;%1JZP^Z7uo239y)V|8Arrmw}k;*qCdtdWq1O-6?z zcVT>z&Tl->P|p1?gCFj!iCz9l@`JMfJ5uMBxjW`($zL@qbU9r%x6+{l`84a|P>sdg zN&8AlWIFdR5a3e+!^ONoT0T$t3giARYZ@C^!Z1e|F}aAHL}C~_b2PSsr zgnJzLQ|T*Humi4wlT&@Oc3%H&B#-2mXI%;EY{-CNd-I6iO#^{SF|lZNAj#37x=#5L zP_HwQ?L@!4z}n0pn&cU|W$fD$n#%1|zpLe5I@9=?bzh@7f57TtLZuUqtA$*Qex2~F zr|iAgP6{4~TBpR=$1AbTI8yG1%@W{g_mSG$GP8{$^-)D0WEY6R4(8< zc7u@_8UM47^Y4`n;SvD zh(|4V-0O%(glAjs2Wv@8BvRASW*{PJVEC)3sF0VJw;{_TmJ?1OD7e6fi`&(VMq6T3 z*ZjMvH*rUS#IJArg!w52@82{gN3qESx^$j&FpiBV=;Kms@7d z8CK7X!IrmpQl zd`XuB#K^&tTyvoo8Wz?N9suVPJAN1ZcW%LSJUr8Q8rZ!ST-96zDt359+}<+4tf#Gxc%XqM2lHW{q|xY z>wA}#w6cmTt&T$^R11D6-`@!buQw&wt)h@ea`e_oOzPn zh|M7H@nGEfJsUTRQgB+;XXw7)`xF4_$_U?MDU_$e&#rx=JklKd+f-2FJE1JDo9Wc? zL2(e=H+Z>@Gk+}^dCVTyzkL87f4!}$&Ns(({^dK_?Q!`!o7x~dWnf1k4-7!o zT|*x)x;2k4@U$_M>c_v$>fH(DCx7K-(_0SmzLh82CVjVkXy>SZ2sT%dhE_bO|pXQ3D8&>j=>Nl5*Z>A^W?I!=7++ARXB z0|t$Id-ZBC@%DYXexCh#IrCU`t8(-;b!#*Yfol-xFtGYZRK_62K~XGxn3@8s#(*`deA zRmVGH6Nv9q7a>N_O6#H_fMH~Iu7IZo2o3aL#Zz&;C zA7s&(S&2w+0&^m$(3j>C%dWj&A?pIHmyXPUx_*ZWpMWkDIe((^bqBU;E!%%3)^^ET zJu@+Ta+UKK${<#e<_X06C8^^FmILjLHb9fhI`F4dUOR`xFqGVQcxE7r7;ps6?{aJa zV#;^!UOakl^oh$E9_ofNjs)vN7yhLuz{yK~Kq`tMDpXtP#pVhm=lJg=!~ei{^Q%7B zqvG;u1e_(EB!r(N*DO=0IXQMV&s=}Mtb^*uhxvQqEVcVJ`r)>n`@}h3TOUeyd^x*z z_iQZbD3}r{F&3UaWbo>KEg ziD10lFkLab@I|ecUq;L|hKPE5zj%&F&DbwS$T>(ySEYATZDzm*9qxEeu#0o#bzSa!Sqd0S@8=AjVEDoC|J3UafK{UDH`q0xP#v!tL z?KQahr=I!Ko-O~uam57q&B?v2A!MA2kaoY~FO(8~r|?*X zUIRICq?fR^&on2Wo7)heu+8YC7J~7>_-%VVt{?040htPV%3}h1wi{!WbY+U-9%2H? z@#X1RT-W0pw8-!7yHug} zlb%|4kUdrqGI;MKFbM~g+)R}4bF|`=vq#jz#+sbLdhIr*$%g-``RtqAI~*-op#VfL z_o8pWp*_FXx&3EQ`AOZ08-%!3pN=P4yKR8)?%7(A#QI1C#TbriP9pb3hZ%@LkV z4kqoHkYvnz?Y>=;lqPvYS|}u`vj4h;&N9I3Bf(zI=YH7xw~zYFn7D(p3-L!87VZyx9f?xB?i@vR{uN<8}GxZ+b z1#Z>(+VxleVMx2PBGj+2LhcgVsGodLsO4|2qX1q0AurFhJAmX<9d*^E zyv`)shVKLAtZx-?Es@Ub`MX|#uvu78Gq^k@v@W!Ii0CWO8;QReQ zt1>x9KvCf5)qA%?5}u-_R%c$veU>Ig*>s@c1eYWp@K5SR|1U{GxEW;OxKaNqMDAMq zeg5oz0?%zm>xngF)cMoy=D<+~LPdDpEqAg~p|IrvmeJ_$V_!W!YTt)|C`<~1F7M^h z+*)M6ZhQiQv@&nvW4)~lV?i8s!T@*-?NmJYwcaXTN~(i4%=ajxF0d*LG`AkTT9P( zOKeI3+id;P78_l~J&Hb-;V?W0 BquKm+{0uEkHQ+k5YtJKmxAAB7Tm-9su2)pTaTy?cr3K(p*gq*RKS(4uzhPrQY0u zz9tyimxt)NE*8a3eD3jyrS;;|@kwD)e(`8^G&iImQdH=iba?D)e&2ANafu+!{OC;Qw zP62Lq{H31dU^V>4z>lU_}Ry9Ep? zQixs5TfE3FTD130e|oR0MA5ZDmu2+uXWTpnGD=`p1^;ch({dS4aMCQW4_(^&ED0=@ znmEmcyRdbDo2r)Ckv$@fsrbpMOIJ{8kR#1V$`jEQ3&&R9tYX2pNot@ZSeWyU{F1+H z9p~-k*VjrJmQ)1Y=V!9OPdtwvVxAI80<#a*`^p3Z259(u>%}6VNeYb3z3@5Ax$Zz0 zM~SBAb#tl`1_n{L8tOypB**j(^IA&WQvjK}Xy+)#W^iG>KaEi&M7#8|TqVgJX*CM& z1D9L|DT96qIf_yZV)RI*%s#S-HqC&?lCQ03$d{h2%kLGUL@}w}Nxqlqk#|iKi~k2992v z)x#K$jg3Y3%}(Bk#S(5*k7<}R$30p3kHQNpiw=bJfVP?Q{;N=UT$8~89XNn{e4$C$ z_gd(!t5rIcIRhI~#=D?6>L?wZ$CnChRp7e_sFUYP6|arJz#0tyzbNdT;z!&A3cPnlueOXe^a*-_Anek;yLCz|PlrAH|kg2_O1VU1!R1&c`eS zv(3qGj_+odnF(IFYT8B33xyTvgcq^&H1;vQ)g4n${vLTF#dA%cqIs#HmdvB&*1=;w zmVzJXv*yd%Y^)s@<}?$V>mslF*9lePTAxoPL&L+9%XRpE>QKll$j1U~GuRojgmh=i z&0CHi$z9<*BZZ_H7PY2$D(1CQI64oqU78GPD)A{QMY8o&j~nY4wHX;ZR`6(W@ofMe zv>kZE(>zK#g{aOk4wFx^q^EXfSs4!upz~laGhytg2$uz){SL&6i@4R1?Y>38jV4aQLQ0n(-dJ@Y73$2N@M!;kXUpo-R<+(PxBH20B*unPtOV z_0!r2=s-~?S>Jm`Ze`{Rmo%M491Z{7yh5hz2vsdcT2{u+EF>O<0GqGbWXcFSexuvA zj}qlnBYnS}k^r{Ndfqp||Kcf&ML!5Ra^8?X$b67hEKKC#276xTH2yKt{Z$;oI@lxg(aO~od8hgHX88s405?U#a~vTs?5S7ZmT zeey~e2P6}KnTXvRYU#~m%Tghx1o5qkQgb#n7CXsmT8r1Pp{y4@-1&6p{qt$_QcYct zEhh&|kTs#{FXcZ559+TsK24CIr(+L}bArxEM z@dLmRQzGH1!Xo*ROCUe?>^}RXs(BZUtWAtCE4Iw!eV*&M%djh$M|e-U5x|U9yte%{ z4i0*CPJf8u5-|!euS%{Mfj<3SrPp!p4d-xKo8x?YUMwRwHyi<_WMO4Q554TzOSdMjO+)+wdbe&nqO*3tdE0u zsw~rYUia6@p`9Jdn?ejE56s3;6#?56t1l1jZ8u|Sha{#g&WdqMr!8_gFR^^L3ScMC zealjVRZ`R>MZRg4n3|dz4d$wsqWjG;gK4HyCi3gogS+q~QyV`h86LDgh)ZGIs!U~V zzrRk*&Ng6TVM%;}yc}X68W_yU0meHwRP{G#Bq#{r+21e_CU1crRQmi6hzPB&NW&0}j@)(Q&xO-`?FmxxF+3{5&g#ZU+LT zHOa%nFm{gTzK>KyI9?VNAU;U7BBVh~d&xjiuc)mAQd&|NRoKZs4KBesk zmPA%hpW?=z$`@^gZCmcKmu4w(^f;u2-wE}p%;E2CIX?X;6lbj{yf25QLG-5gt0rdq z^CEdRQ`k^DJv8ISe%jbB`PO?~Y85(?;lB&|?OU(>?GmtlKYKkSC_3wm@_w(oPHby>_SS4`p2>B@wUXak(}tkRh@L*}VON z!0I6j;Rq}u%B~_iFA6F+xP6bD@L7YB5bQ%Y3+U(7ZFc<(Ht3qY+V5vFof)}? zb_*9>VrPQ`=DR!20>!vp7g6J$W>}p(&98T5+1>kW_pj(*w9t%yQ?A-h*?lElmP>FL zLy*tNCAWsj#amRK5QK*+@^3d$)w_4z$mSzo&OC})MY4M!Gj>4zA=*=o0ibRI{fXA+ z*JPj(GDpQDb~yXszWnJkEQh%(@A@SrqJ5J&lusu5J3RYeV|&W}^WQajadB~MY%WLA z*ts5Ej-s}-@iHA4j9;_Ag}dF0a;i|d`a~`xr}z=T`O(>GjX8_dpOJ@7qhQ&!magzB z#%0ZOCgc)PusdWfJBOjv6Rk9C3Yu^Esp-dJe--&N8_)S_ds0>o{EB zaY>(dKO~|o*Um?LlZ9^BRWSi^+*Zcu1>7h zAus>Q#u1#OitKRv%QLg;B+3Ry_%?s>@T$z`DciQ(NeB%`Eo__K3ekE|Zic2Y_YpZ! zIsu$Kw`ysRDSq}ZitS%=l`TU4^p>>$rS`0gpO3z-x{R^MIre+Mq4!XFpR<@g%nd2^ zXq#cmt8OUK(4%sC&+S$v{je8N?v+{)CFhZMx!kPR4YSkJT?3ejtLitn@>+isXROO5 z8!BQQ=4xyz=*HnIx;?l?HHYOtITSD&<==+`Y_J!1;r23gQ5kZy3l<|r@*;~tJR+*hDoNg%;$o>WNxvHkVdElSn zV#^4L6cKH6%V~#a9EwL2tu3X#R(@@t!h2u&5>mOC@1lJ}M8t+4`*|0iruF?4He%fb z9$u;O!|W&lB`H(rki0^kj7vnUZO1ou5c|U?cm#J$;Dolg-1-qg5i;K@EbUg&ac@{m z&eQicaLrJ9+Zx^%_VuA0>>(-H4-+1a$?3%crW9>fTMf~?WbE9akqc_NYBUTu!kYg6 z*3v#sPOuAD7?H#FAUHH4EKWTri#-^JGT~;go&KkX^U$8++Y&dkv*l(a!^7O0-D1zB z`u8iD#9Hg2!f`%d4kMw!v1U}wfj*!2iLdDcvDB>NsJw1RODA!>aG#Ts5Ag> z|BkYaqP~&~zXW#b zPE4*i=#k_1ZYmYJdLsAuasCEXgKz$Wl1VRNc{$<*!QIYdOaMCvhz#F!IzG5@nH^X3 zIZx#I3e$pQk`(KM;Xcmv?BcV3MX0@=HJ1-tExGtq1bMJ3~z{o zfczF;>;BGdEBhnR@JXt-hfd_rE^ilCetrXYcb_Y3O7Qi(cvfPezN>t}%DD&n`zTyA zyEV_9y`6>2U%z_b(V$wx1A>L?zwZR0%a=Qo4A1m)t2~-g(f|*1E}5{~{hjn!;uMc% zq_i`QwX#eL71tUU?M&WzT|1d{gIl>dq&m4A*`*v|GSd=_8qKFO6m2JTdkI~U&@>|= zm%AetMvi6Vp7^(KD6MT^I2XisRzziZ_;|Z#-_6g1pWwh#gA{rpyU&63`cBlK_rISWWg*AQ3=C~`o*=gJcc>4;q*Oltos0I(A{Z~2WbD-IH{s!8 zX4@~em&ifIyE&vi`P&nTEdqn0g<0eu$Xih7UEAeV#IBEA`W;U&sOF9@OYI`3|Lm(@ z7(s7+;;cQ%pb{<@B!+>+pGdR96-v)%L)O_52f8w#@_B**3c(PVUaNlUrl=)`UBH&| zTXqWy6%~84P?C$l!eJb)WsPc6Kt<~Z^cWP|P9_!c^OU2pdGiz47@X7-kiTKI&)9-n zXDJj$bc_??@qc)mgZ6uPTS;j?5mMpLBU+Qk(!pZ2ya%v3qD z*d7N(N}QN@H_z{V{;@^F%l@5qfXJ1xbO`S?i9yA(S7+LHP=|i?@=MQCCm1q@dxYTV zYo>Uml)%5d&{~S~mQVX@iZ#{ix$x2)KxFyKRr%jbjpWq7ca)d{d+!&uKp$QWeidE1 z?bL6<>0G^qE}g+eL@DYp1tYG=qX{h4(Edh)T4s9J2XyGT{25Y-%|=2P6r~-7TG}{F zICh-fnr4fQjBDlox2&3(UF-8f zJ-@IY!U#|i3YIfYa2z$(l;->xGr7%pl52+n@?trb;|Ce?y1`d?;QejdcohwMW`6}19VeGUNDs7jqUBd$2R?Z3n;cUC`0)l@#>oDYz!Hmsg5e34;c=Eo~F_ix}_hpT4yg4r2sPoJ3$r zSJ9WC-vD#Erw0m zLbM^0!iXwFCuQ~42=k=7csXqL3_)e^JIb|*6aQPh>zMT+hn33sR|k|M9b6p?52v{X z!L1VZoUt4nBGU@~#yTw5O=_E~GyDr&r=vZDSETyVmfi<$@*V!p2$wp!9@sAX#MA^L z^`dyzc;0-c3D6oDH;F*ARx`F38?3}%;;`?9E#uXrkcNB|lea%bWS*SmQsT9%}+6Ay&{1hj65_8Yl$7qsdu&vz7D!BKPYP6xV)aYA!BXt~YxOK-J`k)J)_a#sl4m-4Y9W^)1xwE@{>{+;LwH)chUy^ydK%Y@7UuOtyQ*dy?9IZSW)%;sB^te zdNW{cr{ay!4zJzMY)IzPlm|KLA-%c6Wa8V~xT^m?cRJ}#yxZ)44HD%c3)~Vx9iF{5 zo?kNGYe03w9@ogN;aMaTMUFJO_Pq72!EC1rKQV2q2c2}eoi%)W0H}0%mzkgE{~^1_ zU#g;Q>znno?x1k*4E5dnbVJlKdR^~h#e96NNq7>N?Bvj1I;Z-nXmQreh6K)$Z;FJy zw{}&&u)8?I$R>J66+Q2zoo7{BWIO-gnNni zzN|?_+k`uVv%e1mYT;nppM!yan6T}(av(*#^i+3tP9s%^;z0OZkaoGV=FpA&N2MxzDK z&m8h!BWi;TgSB&Sh*UmGsHS}57+*8_Czi?^@t@w82R><%BlUB5&xts}8~noSjWmPX ziK0?Fc!lLSpILu3BumMj0TS|RviYK0vIs9PQ}3Y%tws%(ret?3+U3G~{8a@g`)AAf zRMNhyo9oOzQikynXU{f)rVm9eyyCn~--mzP3{~8@v=V(Ab2I$?*X77SN2mkgj^gc_ zPCm+Yj&-@?KUovus>rf@6+zFvQFXU(m4#bq!V&TS^E`T;Yc@Ascl~Sr;5OTkQ;Pm? z?aZY;dZl#UgFA<*kNRZr(1cE%@Obh`%$bv`Xu=yj0$_J6U(P1W2D%shL+Q_#-VIsQ z=GFPlA}-*OMX7@3Eh(mVWk+3nS88xrCRpS4{%~?w;xlU-MjQ(q46KJPcX~l zo)I$H?kJNu?tA^M2%JOP?kJ9F=Od2M)opI_7^M>b7F+(^uBQL3` z;k`n84!4S!mGCB#nd&d;mjLrnrB(?&&;Sy2ki+EwHFI;F-6!m(jH{=q8;zs&vui56 zGeS*UkDWL1!*0?n(km9*UQhZGzCR>j41T#KbRHQmJB_w5{wNiAko=+tyrS+VR47dd z=eJgF=55C*VFZv;Q|h*th`|5ay2x33BX4q^ngrZl_j~!>PW_6i2OEJ^!udN)z+yWn zw(3aCXWkNzc{Yq6T%N3%x3=!Fg$zGGyOlu)Q-x1SdM95*_5PZJp%Rs^pL++StobyD zVRrb6=3DU_YFFNR#&?AK!0F&E<-Nb&@*WAVuHm}0KOj!DLo7Y#r|iN<%QrsT?&p1O z)%3S%?ojM@ux0JX50Pf+G-;per4u@ z3w>F0L9ShPw{!irFIhjBtPDz0rn*`_o3^ak066`klKSN@c+3Md(disf5`H*K^7DJ6 zzE$Si)=vXAQwv{jbZGBcsKp`L(x|xc+Og=m-KYDz{@iVg=qi>j_pdlDpRb_z)-&hD z!>lETgDZuA*=+$ZV8UgyJ#sd&u({93&gE~Lx+YGkWSM}}J|@M*?Pm>imWZ3OWK}&@ zIIw~D@M?*)uPO%&WLlFQv$+lOfA(&1n6vZKEYtF!UHU&CcLF;hA#)Z5`i1|9(;*-=Lsrz2ojv8<{oB`zmkjla*5`PvFo4E$Ex2dv|TG?*79)f97T6 z6`sjo!rG+taZU6a=O*C9;F;%HeDgjX7ca1Dd-cHb@Et?#6Z-Xhv1UtcY8|`p`t3a* z^m^N#d8_J#oj{8g>gVY@|4C3XR4aL{xDvQvP4-#M%biiq%k>L)?qB*QGDFzLs^(1Y zCzI#gg?hL4M*Z@uIA-^zW%;iMl9v(_8n3U~w#TDsvDNME&PU$-{J^NHG3W3^zOO={ zm1lM=%lo3U6HmXt-SbB-b$?%Ros#a1$E^z;-yDxWV|nTG&X}e5rQdyG|NH>Bw&waZ z;s0NMMr5r%b>*kj>kDdPe*;{z8;cGby&%>+W: Launch xUnit test wrapper hosted in LKG runtime + W->>+T: Launch each test in process isolation + T->>-W: Test report success with 100 exit code. + W->>-E: - + E->>+R: Report test results to Azure DevOps + R->>-E: - + deactivate E +``` + +### SourceGen Orchestrated tests + +Consolidated runtime tests generate an entry point assembly during build. The source generation globs the tests that will run and generates a `Main` method that runs each test in a `try`/`catch` block, while capturing all the necessary output. There are a few tests that require isolation, and instead of calling into them in-proc, the call starts another process as appropriate. The main advantage of this method is that it relies less heavily on process isolation, making testing more cost-efficient. However, this also means the first native or managed unhandled exception will pause all testing - much like what happens with library tests. The merged runner that invokes the tests sequentially is hosted under a watchdog to handle hangs, and there's a log fixer that runs afterwards to try to fixup the corrupted logs in case of a crash, so that Helix can report the workitem progress as much as possible. The usual flow for a Helix workitem of this type is as follows: + +```mermaid +sequenceDiagram + title Merged Tests in Helix + participant E as Helix Entrypoint + participant W as Watchdog + participant M as Merged Runner + participant L as Log Fixer + participant R as Helix Reporter + activate E + E->>+W: Launch watchdog + W->>+M: Launch tests with filters + M->>-W: Tests finish or crash + W->>-E: . + E->>+L: Fix log and symbolize crashes + L->>-E: - + E->>+R: Report test results to Azure DevOps + R->>-E: - + deactivate E +``` diff --git a/docs/pr-guide.md b/docs/workflow/ci/pr-guide.md similarity index 72% rename from docs/pr-guide.md rename to docs/workflow/ci/pr-guide.md index 6328c1bd1a9e31..4c391c66438d64 100644 --- a/docs/pr-guide.md +++ b/docs/workflow/ci/pr-guide.md @@ -19,19 +19,23 @@ Every pull request will have automatically a single `area-*` label assigned. The If during the code review process a merge conflict occurs the area owner is responsible for its resolution. Pull requests should not be on hold due to the author's unwillingness to resolve code conflicts. GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github). +## Pull Request Builds + +When submitting a PR to the `dotnet/runtime` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. For a high level overview of the build process and the different pipelines that might run against your PR, please check [pipelines overview](pipelines-overview.md). + ## Merging Pull Requests -Anyone with write access can merge a pull request manually or by setting the [auto-merge](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/automatically-merging-a-pull-request) label when it satisfies all of the following conditions: +Anyone with write access can merge a pull request manually when the following conditions have been met: * 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. In case of failures, refer to the [analyzing build failures](failure-analysis.md) doc. -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. +Typically, PRs are merged as one commit (squash merges). 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 disect them. ## 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. +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 turn the PR into a draft PR by selecting the option under the reviewers section. Alternatively, you can do that by adding [WIP] prefix to the pull request title. ## Old Pull Request Policy diff --git a/docs/workflow/ci/theory-azdo.png b/docs/workflow/ci/theory-azdo.png new file mode 100644 index 0000000000000000000000000000000000000000..3599b824950cf4d0f7d6bd24d32a5a95dfbf62fb GIT binary patch literal 34690 zcmeF(byOSeqv(5DS}4Uzp-{ZV-8EP#?heJFxCAXupe-#@3KZ910fIZh3Y6jmmmon} z+%-6XOW*hXoxRWA$JSZr-uuVBvlj5oS_z9xm{~KQeCLVKR9C=%Oz{{40|Q@4QC1rR z1Jmeky!r_1?z=J~6ms|Do~O3LYmD+Cs?EEV2X@kG(ij+3F}T;35AW7-+!PHxF)#=^ z{(Rl*aV@mQzz8E#l9kr=HQQ|ob~c^zT5nDf*j2$UGk%p^f%*hnAys-g+pk+|9S$V2 z_?R};CMz$GObz>9Wd1U(`UAALKj5=sKmV~s>;!F8=|)acIV)<05N&l7Ms8-9q_phy zK3fMT_O%UN`hBXrq^GuY$p){2E#uV35?ssB%NZ?a5^Z}eVI+(osUNX>E$dT~P8BVu zW=<8L>AH)XD}9{1zxmJd$|11xn(*&2MmEDQ`+I+nU-kVMz5n;{ecT7gpO^S&VZ>Cx z{dhH&4`~dza^Q^tOF}?H& zzF6EaN847{Z;v=Bt^$tf|9R*f*4&t&k?^f;Y>-s@%olJeKdP&ZSBlg& zT;1%F%e2|0-gTr;!gdPF?)t0oo)^niCWWbq@P+C~`qZ4An8LEHMhS~3Sk$@I#yw>S zFl;xxy*0L|VmWBdVsp!7T8f{#A6n%}z44hl=25^Pw7K`$pf4I=+N`@wI!QsdUO1;L z>C&>jyOXleQc$?=v5#yWns-bChV+h9R3Jk}B*ly=n-G#pt8XH`zu&N!Iw&NSb2>SS z9m2SPQ{PI@Y?(1I=CEpa?e&6uK6VG!zisW(4LWmM+IRRgq;IE=ctFUYp}D_eun>fdp}bRB6R5FkBOu#u{Kr7NMo@XM|66n{}Vl{z1sPFt{UJ9t+2QS6|?{E7;6 zdpoU4IPG7=spFa+l2$Yyc(X^pX6(M>S5mSTCiF&%oF<3aNkx~O%4;hNJ1pSRzDWNF zT|f&>Wq($D)BZq?{!9XDZ;#YVo8eXVI@Y=382wu2Gea<>bH+lL_E;4DQDn0W|KlVE zFyZOUd!mr0iSki=1HM zyAL#z9AO;QWg(oZ42&3K1f^mf5-J>1LB%kCiK(P2wMq}s%8?gMe8iw&4#@tNprak^>`)IHNy+W&U z4>h#-sF`^qik=>|e~QlHlpB9*w|%y0f>bB1fhIRKMvCrJyxkMeY?cdc)Y*b~UJJ|v z#TY0hK&UkF)bvXQ|vG| znLtwEvXgeRUZL$q2P(A9VJ>IoR2U-wAi&6r;>!G1Vi2AETBdtuOdavWYq4-V`23nS z@ySEikQp1JoYu}lud#uIFaGJ$rOCP3V_feX`+9}EUtnt-?5lTWfH>5X z$Id1kEH2N7wAZff4(M})mewTUU9**6Q2nkw*fXpPLb*Xxn`D0L+ttO3knIb;cW3#M z$Se57^n^x8VAhJg?YHh_d3-s92`#f)YTg_ygR~8AvxxEZdpVak1DDy^(BTm7nC%Wf zS!~Xeq@MUxzfAYD=Xy*vQWjfvevT|*D?CwnPX}v4DC)`zoKig+R()(z`-lK7m9LF$ zn4FvwicN6^>V_S<9Fw|C;)M;m7mhvr{0H}EsB(@C*e0axZI)p~Ah0FT(+Fe{_r* z8(yri{oZ;cH80a<*;+DF9y2Ec9k3H*FF3`-a1ow0hj=Zsqki5V?H2_>(!pi7s<&BQ z)i=9$2V8tlRq3U7?G+=-CCxrw{1d&@j zTRTCzntN*FTOBf0<h>QGbznOCqXq39sQyf@M4|P9_j&TC;NwZ>$3ASts5n1;sYErb z`#tsC-5$mp(YEH|z9UzPyA=)xDpSkqLazaJ#1p|Y1!0w6{pGKtOSSXObPCoyj(_F$ zaLR;SHV_Xbxq&km`%acK=sl{YXckuyuGa%{)`ix54NG~YgCmc(U!9A0=oerw79`p; zvEECX&r^O$owN5jInArRF-cv}W`5CY!2}6#SevHWx{4mT-g?m@KC6bSaHb{EU$p|D zC>c{uuoaY9-_3l54I4Ps_DY{g?HG%~((|VoGw;R<&)9COFH#O5tg@19j-i=3Vr!{) z)E;p5H*~vx3b&N)JAb)VCSZR7y2uDcG;T$SP%GCh^QZ~ub9zyOUc(Uuvhoh4bEg4c zcP3p8o5;5$>g(axHF?gAX6Y5>&PqHyBo}VTY9ae@aJwX87!2tiv~HxTzkG4l(7p%} zVhd3lEos0j#>WmBlcf2s(I1qArWLCDpl6hL@4A%>z$v5=?Nl9cBREEFVMQ@@#Su)m3k?Noe%JFeym0-5Z^0m=2+xpoNh2ODn&ve za&Ag-WVD98l#shd@|q2(!`z&`Culh7W*YA$2 zB*=tsOfAW@t7*}hbtPxH{MENV0zaRciLaih&G@?#unlO~|LzG^3BDQ)*a-HKHw_3X zf1P#h5E677CY62rx=r><@|5^;O(R0`Vl)f7_)9HRdft>4!by8!c!|uq`PN#bfr&9E zU%PLQv*S#CUe8@!bK;5eq!u#-nDXpCB>$`>500{mx(+{h7q!+$(EXgI@I+7*%Ao6C zG#pr}L90ZK_jP~Es;7k1r)jInMN-^{$@^O|K+Jt&=g=#yZ3mBw*iG!2V6P{Z(dS>$ zFSZ^;w<;gArx%{ZuLTfg9CwK(o(Ouvj?*NE7oFLxjt4#{d*ML}Nog{a!~8AW#i*OT zC1_H5e`PPtg;bo*?L0l%^#I(;>o-x+wjo(VWIe!512)5~67M}%#Osjcx_-kMVX;bs zYKCI3`T2ejWZI2MauX(O8|W7W@Wbgx$G<2|P_7$o&B)y{_`YC4muR}eok%V+9)PuM zbg6P!^=JnH+2hoM>-q;{m(e4i#Zw>jWUU8uufp3mGK|-Ysnb6=$ijhru`P5m!ZwI+ zoCDuf03;4ccYb>#NKzo~Zk!C087hU26U@l>06Fd@9qS+S!ZQP$YU!9qreApPsk8OG zeB{=E>F-&JzqEPto6$cAQJz(Dyv{gVi{@Q$O%$Do|3(L^yP#Me){WrGip-S0q_FXs z6Y4wyS=#d%LAN$#h#pUGPpePPs827)MIamMSO*0*TP`HF#>GYg*uyR*lPda}DoMs> z^v~DZAfK~tIM9gUX~VLZ(Y6G;Tl>#{&M(GX5AAo7C69QUPKTvzQv+2&x7<<}`zV#2 z3^W#Pef1?VhyvpmESFzFMRSOh&|lfDnuA)*_@iuSi#=rgkZ0_re5h`8U9_R?R_BwG z)AON`x^3n{BPGfKghQ%LwMR=sV>BR%*;ADBp-DraNN6|61qYL?~;_KS)%9Sd-j5&8opE1e_hY9)A z?3y4>p;iq+1?xotnzq!KrUY7mTqQ1dQsA0;nhZ`BvCnZ2H3{1SqADyTFZQeUb^s*|FZWKg%Z-_Pm1VVT*R zuv?2NsSuL&G8HJvcL5nu+nry9L*iwgh!EaeH9h}G$Ts6k>Xu`=Pf=lby%dL(9l2$_ z>CH^bU@)^I2gXQ5tI_AM{zy39Aa8~aLKT3rk4LCI?H39VJImnffoEkTsup? ziXyY;c}m_eX5)(Yp`V|lHbI!9tXKUK%1`k7Q5ci4n0zwFMZ6@amabAiP0E0j)4 z%W&UEMHx}rkISWDnS+D1@AaMnr}g<&h-bC@((P{{IIC46mzv@CPmNmU6NAOv8ndF; z0mgt9ei&<+`!=f8G)S>V>Z0nxnTlHw;w9xO0Vq4j3eE+;_HJl(lsdkhS_!_pDpU}S z))%`*`)o+v_?;pjCf1y+-=^N^j7q)vzD@!@K}cWsYV?(k`+>X*@Mr|n}@rz7Ew2A!=Jvi z7E71q)gM~e=KgA``^E!cb)9G9g9yIciZkl@-EtuP$WF`}!%A|^3hN>>h^n9l0;+xY zl3lMi*UrJ&C?5p3NT3k8j8jf@FwmzF=ZPSTcM2L#wb@5l}*eZhPzOCLPmZMOk2*@aXQJDT=eJ~d3UA`)YStBZZrSTSo zpJJH<7<7ag8S9p&R((0`DpNjg96ch`%bF{*vlK`F3h0dfxZS{yV>1F+&(kG)<-CL# zt+yXA4w%8xrs-Mmn{Ltxr++KS#Pe>86Jc!SY7)TZpKR%B^=2{VWPGVM589u$_>0Qb zcBa-fo;n9{pRjdffG$9*UBbnEnl zyX$;^twBxnH?!IrL#gl5w`Wq@i#IK)^G0=7w}<4$%z0>{Du)M;RyK5ixj@P=H z$#C(*eZUeYKjYp5SzCzuX2H4(UjW>{Ic@(LJnQxeEVO)+Om=iYqkDtZA^S9L7HvpDh_#W-` z?aJq_CakgN&hrU;m;O>?RvFa^PFJk(+=`Bg zF8?EsI(DN9`gZb0+ghw@UJZEjj_BpX7gZ9@Tp`8Cj2Y`T{Eg(0?=QHC-Db4|gks^I zBdr6yF5P=y@FRkzyyv%KIAcKDzf$+B`y_35qg;n&u2JHmS=g(|@=M82+)Y)BPj^I& z4M-b7vz{oGXLP1X1L3n@f(~P5gFn*TtljgsUNq@m-1kJy^p;fupIM&*jXSo-={k!l zxs!;XuQz2(gv@Ebe6y+8uHBhcchHID>KZOI4@c2}+UzQd`9%?RtS<-sho4rTR>`!) z>@5bT670<>cy1<=Y_wbuVPJS{%m&_qfGYBycB-;@%k$n*P`Nm00+NL-We4uDDQss#gQFyGQ}z6B ze`*YJ%RSGHPi|G2Do5^8zVnEgscR>%F!$+iA+TB0fkbXIWp%tm1i(B6Tuy8I&&efk z2P}^{aU1Qf1G|QuJ_yF=Bu#bAe!FmaE=IN~mwZtq(kf1u;nc+9XIktY>4-nN99d_H zmh0<5_K;6xVcUBuL;YLp=Uu0dc(Rh_$w8{`*tUXo zX3e2!d+lIP+%4O})2OvpV_s=jGh)%hWApEw!vR;w^w)V`d5vUZBKkMazTV`2#onh- zP!ThfDiCIFRam^jKDOf0CSor1ISrbvo^i$|i;%SOuK)1-as{hKNPx8U6`}L!f6+co ziZ`J!ALg|phO!Y}kQyoWutz-(}yYNQiW2R+If z7{L|-QAgLfPme382!h)5j-7f`rPTQi*mObNqxj`Dzkwd0Hd`jK27}%CC0;BdC+gJuYjh)58|7vXDN9!CN`BUsFBT~_?;0+VPH9Z)SFF$S z!Ep4su-6RiPx@6SxFtmAqd(0CciXnKJ@ZP)wF^)mJ+}x^-@n_-OG=7^?c0Ez?-1QC z4;4196D27m1xe1L9@;ww=c6Ff!5!XmTecEK+y@Qg+s*q=X1C6)=f>1j48kw5ji0M{ zA}^an^4Cfzh}}U+ zBV#ZkV$Qc6BKnL*g`)|x#(a*in9u&Uz>tKNGp-R_b zVr|WkzC(5()NhgVA@#gL;wCGqvMj%I$;;~%&^z;A&UL%iI5qIv*M0q90sj24r@l|v ziJo%J{sPz?Z&{b#^d^+nWZXvS%S7nvp*7Rg+B&&UjC+>wD?ml4 zha$mv?~74!u|lm0bM58te`(=x18kTm&Cp(xmNGr3N^5mQEgEo)%NA!--j~j9<+s2h z7Xu$RX31kE8u>!}+XETi8a)fy6Z=`#^m@{2Xy2jdxNUOxSrec+W-C=|Kok4v);F8v ziKK+U7`;Z>od4{_Q`8N zn`(Bw+A!I^&Pg&Nl;2sIi*0t$1~j`>-RhdOa0U34TtnTmzXYpsLaG@BhV3$>Q;bq> z(x%PI$Eo6VdCg8l@xva$ulwbEHt+36&iWlUHsQH6&N<<*+PG8;6V$BRyL*Z0Nv%Wc zrp|V=74o=a4ae@2GZyax0Fxe9Dv+W!)rJ@!P6#%PCd%yDt}B#_Lu;|T(m5VAk<{bh zSf@U`J10FnNSX>(b8>Bpek;M>Q-m%U@|$}yW%b52XXxOjP{PpfU|MB9{R}O2ong6{ zkWYw3eJ!fsH5wy7b}r6>4fjp4xoofMDQt%CVuxHlF_}^5Ay3<4pQimeRQ31&a&X!$ z`(;f9nnPk$#F$#t@C!XEPfg`9UKk6==4#nQFR4SIvP}B8LZcXqh3Ej&w)g@=%-P$~ zeeH{yDbM(@=)^nV=VIp{e}Sd4FzZzVM_xwlJwQeDqQ-HleMfZ8;M;3FA9aH@ zqx1{QWpTImBsJ|}Gu^0HV`~HluhPl~3PDA&AkWskqk%vt_9&BPbz;-_p_8TXPXe9G zNHVKN&UXqm+%$Y4FFlU1`bizcnG0{L)d(%gPo`6!$>b}ykiGNQ@|=B4$mKuB_uQ_1 zN3C1U{LAWF8@^U}+2VO>A|6;EEsunPF~0p7vzKM4{u}I{>*NK=s31fv7JLr5|Fb$> zmo<-mqUAulhO5wtT5DC5r>)rL`}TLw-K84&lhNeqmg2F)QJ2M>_`k7ojrR^KX&{)` zz%L7wS=sGCTRQ?3VG7+%KgD2j$`>BxZJon{bbM7c=AA%2Z4IEm;p`#m$%#Hi?KSXk zq{N>mohU%@KX=ZnWfZh{GBZn(Xn*hn*w)i)hA!|ren?L_3N90WMWv0It-0UWV!D>4 zQ!!{@0PB4B9ML)hvvD5L1f~GH@pfy~`QWP!lh}rxWT z+S3v)BuZG#+*-y__to7Y<=d9WL{QhxlBs9xo-X6WF3rUb_^P!|CYiCB7e6wY$Dx;x zYm~5uKc-S#-v3J>2W99Oh<}OnhR}n)j78!ggQ8l#VC5>4&IRQPY+AJa9F1SRQN7#a zNNSU>xD|G{egraBmgSW5GI^BpVUJ-6=19){+BXb|VY1dlt?CAFg7ix@t{nCNw<*)1 z<3MG__=U)$p*@I#W3XCCScAkNZ=?Ud1Qbtl-U9|bD`5+<{hVaDFh;D357Yh;S#lH%0)4_rmNb~jaAAA(+pDUDZW^|aj@`!6P_Q(Y6GQ`!cW z`G+qiR(;RYv2#5JII55RP&od-ej#hC)7&fQV2Gj${X70Pf}Hrc1~PlVg3xCGuWG#h z!WvDd6@^bwC&wp6*j9Li6PFZ`wJ+qgORe*h)1d{DAOy`_oV0?3ou&CsLr} z3c%8rpJEnw6Qt=H)lJvliis%<=`>SA_9Q%MVr7CY$dI~Q)N4T zrkpCZ*8h9tsA&C=moW}j0cSm&(cF1r9{Nth8G+eG36zssB!EK+}m&lEV zC`QeZI}DZm8c%<6Dvo^N{zc<253Mwl#q^id-$}$@axiS@xw;a}$^3*jYQe*9yht{S zSabR+r8608b;9YO+41Qz+jc<5+54$@_I`!QVC_^DxVQ$~TYh4jKBgMKpa5IbOEahD zC^*~mEN*S{Y%!QKS-W|O=~g@q33x9Sv@$NN@41rS;KVqA;j*x<8Gsf@6l~ zaW|u(jcuxRnUcQ0iy)`^Pgz_27EVMV~o1Pif7`%pzNRpNAG^z*NVH7)?>0{d<;$<03uc zhka>S)VT{Z?xAy!kT}KqV^|hmMy=Ad9uoR!@!Vv~i3Z*o#jdg?Bz(d?&x?W2^NDPp zuD>EoC)eYx-lu_qqu$H17x%q@31N!Gn5^NlLOYF)j?FA#n>$rOM(?6xe_%lu=ZJkLqu%jvTMgd;06r_@W8}+7-O1`x>9s|ENZi{i zU^XXn8RIjY=hqhBiY0E|ixVkD>C@J7r0ujQgI!*p%Mf}rZ@oqO&nr;}3iZI0Lqp98 z0qD~3LHiFH9>}Uqac|F^x`FP2Z|Z(dLuPJDHLPVn2o6V$^Uu0i)S$S(xPmoV_twsA zt9uwzZH8>(xJ-VxU*`ObH|levOfu|6%q{|SvfK2yyACpbkh1bf#+^*E&tW~~Hxqx? z!oJcZoV;0lQCu{Brm}}=ld-!QrzBBZ19dkZ@F@-KudeHxbB|7XF@(sv){0Qq|3q69 z(c-X~fKuVl-CB*-lY5o$TV*?=F89*4f7F=DlpBXvU?}p55X~5`QYS-#T&ys*DF2f& z9t!s~jas?UGOEtL*&3>>iUL?<&bZ0_Wd?Obm04P3KOHN#T;E11l0tVIMS<3SOihie zQ>`o``YsRRX&Y+&Q>EwIhuD9y>cY#*2b4cd&V!EhWvGkBH;ML;uNiHG!KKSy>5EP5 z^dQEL=k-rX`noo36ZDI;U!uyRGxi@?3t6oyZ@gg69s>((+SqsbaSbySADN79YA@K@ zG3laogVJA8aQ<@ct4ci;$5cA}e#TZ0V#cMz7kvJdFXLq5&Qtf@n~f}yjtkw-frhbG z61YTv(W zL%TN2(NTlR?8KLku}`{iAo0}))#0Owb#m3w5LP47A@5#{?!bYbfi(ZiyI3dsbad=9 z9XKH~zse!;lru!D_@klBWO=E0Ls@6!n=%MMBj@zX&)$;yv$RF0@ z6c=C4*0jVjza@<5IrK!82|O*EvRN^GnAJLKM4OUN$aWq-QlNXq@6dFVdX??IK79Xc z7Mtx^f7RXY+!(D-Uio`GQhZmS#7y@2`f*zS?`{a$y2IAgMXi}zcb35 zGb3uR-Pm@boEWvJy+t{B7Hy_)u_xx1lQ=^vYJPOxAxu{nlXtIJu3Mj=no*8%(Oig| zr7GRbzJz|^>EuMwr^B12RnIIXSVU&xH94mc0dbsu2e{1Gd-Ye!Ovc8UsrVxvC=LL7 z9<-eu)7v>kcxGt)3eWyLNjf%h{nP$n`9HCy`@AGGrJqtI4k+`G)GCWk2#^*LmAx^0#tlIb%d$uh6!0iJgG zE_9t7ROkN|fwLhHM|?=p+bzzyU%j588JR_ENsVAVIKnD5XyGet8cbDlsix1L=~P;` zk@x2Jo~n5{TW*ZTfzzLgBk&h9!_JF_JtPU2xS~cv_J>A~Yd9FnaRuMIQ`fRba-5xC z9%+A8OtxVfY&}=lb=?a|J3KM|h6vvi9x&nVr8xg-OlIj@90%WTu#!qYG zeFBD?sl4ga`FehSd?XfKEzKQ!(B9OwSw7 zu1ZJW2ApZ3AB%-JoH@b~q!6cL^jQ(t(^?!#d%+PnZ!rdjn=z)b0bq+WUBa`hEzh3b zt$w4!UlRJ=_D1FInIC?+p3d)vn{+qXJK9x|QIf2B1A~wHFF)X>Zx-cA!9W|FO}#_% zv_zYP0TpN0JYUf}uvo-Y4C0qtw$p0#^^mqC|c1u4hYe>Jifb9&JT35{C{ z&<%eH>gID+n)w$VS!Qlfa=B?eQg~y9rp76R->hvfA%MES6)I0Qr6w7+S$gKYZa=r< zka)-+c$3<(W=!fae17pIYwErelMH7?WZlc-c^+@Bu}H3C9rr*#S&^xCT1QQP#ihAD zWKJEIk#R9)$G&1>1wIw5VGFs0->+a5p7j)ZWD7N=@pvlCwZlV*(DFJBZP5mN@%c&l z=Giy3NEZp?0_WE(v@Kw2V<{ZQZFF}rBu6KC12gH&ZECk%6#N2&i=28u9v;}rg-+Sf zowzNiZR5Kdm4I$+PnEX*X=Anf4X#4>>{^cIH}OW<$^5?e4I?9Fzw9X2AdB17tJ>eD zKb})aRG4{m91>aOu!*)cIrE8v*S4Jh)n*c@|XWUV14cNtD`n>q$qio?*!(c3-vy}XpTv7?Q%F1Cz~v4>UJ2k z_WhJu%Bf}JHc=G3mvM?3)mB?{oxGmq9gi6wNPMi9<^C>Y+u0ZSba3Z+e$zz}=o|oB zun`l{n1{?&k?u|WA2;pJ%lY;c1^Qi>U4*fTl%8>2MLDNcy2Yx8MbKyciUC>lSp4{| zV&RF9vjgJFSWAJ`zdPjOupJA$&=|9(Z=iQO5`+xjERC9f96fTu4iX4-EX@B9pmW7u zMN54f!sex5lbVNX0E3ydB0s>o3&S$=x55k@9FQ1MbrxPf111${U63xq?kJo+>{jKh z^JNv(mu2T73wRZq-oV+rJ5#lg+thVjoVM2#M)oo|;48UJv-E(M?SYri=Z|sMJYNO; zTMqj;RV-%RW%PaCf5>6;s}zsRiNI_Atn;Fc9hwB1v{5MpKK~VbSB_Hij?#EY8vmu5Ci|&d&QaWP4ikfVjn;;va)k{Xv+C`=tDL+)!@j`w_ex zwHBy8renPHKKX&Ff_*4#A_=u;a>rPAr(N=ltdAJgji@&MdngWy(As9GF!$>h4}ZpZ zJa#%klAk$CGt+&-=le4YaXQ8}#{!O+jZ%^|+MoK5Ebh;>e{(svyt7M8Sg`6Nkv$}4 zu2EOQV(KOl3Fz5T0m06ai((7sl3qmph+3&CW#nAWV~x+d_i0q}E}qrtIP_C;z#Z~4 zLu2ukdh3wE4>057p7d)zf-m=}mJbf|@6jwvy1svBhQIpFUWR9wz>!2EuE=}esDR4l zg1>y%^OG$p#RN0;#B`y@29p9cjWj!DebmNw zp~O}z{ai7-uEg4PrnmU5@w{11NzGN^9>7rT6X2U>7)Ns+EN`WR&iQ{G#7Ut4r$9Un zy6EyaElnb(d>NtgpIg~w5>U8}Rrz*pi1qyzpnt1xR&iUcP==+Bhn9n-2?AQiwS8r~ z*;0WSBx*br0FH+J4@JCGyL}F%CFUw=klfCh9KiW9e?aZD+wzo(v)l!`wSJvCbJHn3Fxa^$f}Z3I}uyKX=-1nK?f z=#G>f_nn3bf=G#{Lthy~RlgNGP+)^lJ=iEu-hUo^C3f?^bL_wL|%Ic zwnvX&n~!FJcI`GTSsyPM7?f0|@(u4a>`K`}(*+p$Z zxT^y6@|Pj=tuoABozzpx3ID;xrG>iX-ZYJ7D-X+D;!*Ws-HNAwXS|+Ubr)OxNz(-V36n5Rs}KfsPRxl8KGlOH zxO)kqM+`0A82kihysEG1vz=kZ5?`SZRqg0q#>*biU47fZAQtCDjCShue@3Ui7;aF( zuD>={z&z)zH%^gaKh+>kFLC@qLZd+A@S=a$?ebRPL;nhO$yUMh3NaHmX;_5r0ZUdMCkp}Uc)B+8U$S8qTS(OyQszjDg%nY85+7jy3Wef4j1NT%L_)*GNy&ofoAEU)69s_uGw6?dKX6b=x=b~UJ10Y^<62zat;Q(&h9v1z*IswK6L z4mzKsG?}}`?50?$qwe&Ljx6`Q_pR#Db3sCPwgrg_JIk0%XucX+pw}iw_UWuABH1R% z^rmHY+dvqfroiBop%m`;3@Tw;#gO`Tp`mwT{2>e?Z@yP3XcT< z+NAs9g6Q{V8inju`*Zq!#GAa&h4)a}Sqm~JoAgB?_fkE84Xk=wO?%Gx|AfI>ssVxE zHEyvG_ye{ObNw2|x4sE{u&u!w_h`JDgfgw11${(e>aiTd(w&2!iPR4(TBT9iB=i^B z5hT4?(AQ_1@^dHn9uegfT-AX4-K6l}uuAm`E zHf($UpeFLB#WquJ(>(H|LQ#^LYndob8?d(Ves?rlQX1NpXrhx^8PtjSICZx_R;i?? z`8n8g+oV3x!eZ9L*u%Plr^&$@vSp{k4NT<5sR`AARM9a1uF!M$nwW+e)o?`yQMq|t zo%k8~^{%YazNPdX=MHh~Xy2(pcE|VDM_f#4D*82icXuqUrS`Cu0DJce0bHzbNNU#? zD2SF<6k8;Qg%mTE;``kn-KQ!g8-1S{^DMw7#Mg*)@9-u_t&sVpjKK4Oe#F`5f6IdT zhl{T$hW8%jNEVVGlca+m5N=$t8}RRXIYYOcnX8>zW(owx^Uh++{1Vp;up>8Ht}=@E z_f7Vn2`4uO_x_kGAps`=V(wcQ?M;lsXMX}yy;fO+XgDd{Stx3Y)}_7jx!<7bY9>aU=5(T7Y)$eZkauGuf$maW2Y%dmYVtNU zrwt8eYcm9`Ok!J`%ksOrCM`S;Si05TK;jdrej5Y2s-c|mHa9StQP8+cTT^v}zm!93 zJ-%2`kH5pvE}0HawS%fT$BBd9T66$;s25D~%9v5akjv3xUta7wS^>~`XX23u>Sc~S z94T8U@_$gAGT$Ml*il)h^ zZ_ZFz&P-jR7k3%?cKtaAXFyHV(Gw-F7Y}0}eU+#m$yJIJ7`kI|h|PV(_iq!Y%H`-N zL*Rw_mmwW3?aEk6)3writ9o*~W@OTvBU}_SD)Ii+9Y68_P~_96t?)g+c;-E1ToK_;Fx3ueCSwW&d6Jc$ z8^>c!hdmJml_z%F8aIWq%XCqC06$Dyx!@uUQ``F=1ci%BIt#zG0A+tbVljF!ehW7V|Y?Td_EmLj3e$y zI{^lM(SH=%EX(y2U#`eKuSm$jb=K&vSwuSED zA~?ZZy9pI)N2~Ok(d@Mhu9m3Fkp~E6Zk=z*tGW$4`WmPL9kn`74j5Fe$ED?RQXpa6 zi03LCIZrh;{A!RotaC0lI%$b^@D}_d>bMj-4X9)Nl1BNPz?@?3o_EF;-(8No7p}%W z5OJVH&j~D08tlw7hX)f=5!za-MaF;pZ)^EELsX7~rg;X><2<~Gi;T~uoN-=MYNORW zY*t@=cn3<0ptN@%T^07-4$2LWP1h=4B}p60H-{FR8v3~zN012`hYbP1{-K|8zXt|k z**#(KFC4{G5$vsMN%<}$6a;nQ%cV41;msf)zl>EsJ!G3-$|1V^^|o?kdMn4UZRsJe z?_xMkYl2*9x_>V}ie&!{u1%sT;Lp>T{An!<+$TyuQC$B%W zlTda}i4kvCQiv49z10zKPKYYCLL$AIzAXd{r;eP?jt2NxBpa!CR6KnLNS{AcE#?yh zoYbbQF?`coqdTGBJT%cvy6sqT{i27#^bX>h~}12XLIKm_yio4Y?-1PY{wZV4^4Ai7qP_a@CxEP zG{i&{nRDV!y5ch-+r*|u*)W9y{bTK@M!(55yGvGV`uZ|(x!P7wR2)0>?9?_3#EEzm zLZ7dubvL+K>En_>0uGYM>$V@D>k}^JPg)?!&r+@kOzdr7azpF)SSTNf3ePCkhMJyl zs^>5Z9h@Z(;wtYHki~6<*UJieu~~j^^Szj}iv#A`F$T*=;`e;Yo2=CGgqKrM@uw4` zTO+aWtqDl4`!>5$qli+^FMmrq;Z}YC(6riUS~Fg3bo-J~g{<-gtv!%(|MjjoTeeGN zO#IPCgiWd0`?tA1YI9K|ulv`;YJHh z33kLyRw1Q8{$cU&{{JM*k-?s0F(#@b@)8Dbp`_adrkcjBQlq zhY>LN^T;YZZ8PzOq4uxW@m#dXeDoh1cJiVMeku9TDfu)Aa>?$#zOSoymN zW1)bx$51UG%N{A{&G34{)Ijj2WU%rD$>R4Pch>qCt&49d90^+72kgPEbC^Pu~)%$-k!^8ha)jRrX)FOju68@mY zk2628&UGUQ!M+F{y8ApgwkQ4iJGii{w_KpP>~fogk^@%s1ElNMut0nzZ#6!4HQ2EC zpEK^UUiJStUjr{nEo5FWuj=5TzeOb1)rW_u}fEYyrm$)pys9eQ0?Xzl`tsaTV)$MUAKR9XygSG|uh+Rj6}2C%U@{$xmxt zEWW6-`e()l$>j~KshI;91M!r_ zv=L=ihEDamt2BCBSq5Koe3uXf-c7Ec=AHM?d<_+20VVipw@bGEul~&008X$g@@{Lb zpKUO0sWLKaW>YO)r2gtBFy<1F)X;UJQ>S;e^;gP0OfXO}vXz)xXzuUPM2%Co5Xw2| zAI!eRA~$@Rk^4VG@8;UJ1{akLg&wT%T&KM|6u@>cNp!d?OJ-(0E?lr@DIhfdNyW5g z`T0Oh0mR2ioP9l7Py?`ezH^j$nlw03@~|g)<5|y)cKh8Kb8*W4CRIUf`f zQJz1!k1*rCpyf4T@x*`TZxH)Br39rp^fMfPcH%huQt0Foi)9hZGSGn5wB_J|SP$jk zMMfSJ)_IQ`Cnb6W4_L&xIp6r_X7gj-C}r&@${DpHBVIisMpDNIAk;)^|pE%i?}+G zSoH}AywW;Yvpax%5_(*a32$zbJQE4H>I`wXFeNNJ9-7kGWm6_I8O|Nzz0%IwMcX(s zu+=jv(!0_7{iiD2EznGR_M>N}LE8tslKF`)zUyCUTq-OwFF9hE`5T3#h8qIDUVXne z<|mjSlZ)T}rwKBF# z$0vkFGYvplbA?^4GwR>^ra4=@>u0sg7mIfjN0{ExmDg0CBi+P@f2NLLG=FAk#r)=! zm7G$dkbH)+v4mXHv(-6hR!0-dFSOIiE_-D;$rLV^IJuG5RNzS{)#dOr88Q{>buolc zoj-02PP12denw;FmsVk!m-5lP!UcJVOyshwHXUzM=viABS2%gd;ls`ZG6zYOkeM0& z1RPlt?Gd6@xLemY>(f83ZATk(_cbw9m%A_pk5|LHI|PP#NnV| zn-@!<;+wHqw@|gdyF0-zF9o@_$N#VH?m8;!MF0P|t_mt3B8Y^5(&5nEUDDm4i#ta zfqWKD)>od~UINoyKU1ePO*73_-tw+0wmc-At!tl|;+UgP>1wYlU9V1h%X_u)>E>|l zaMi$DLjQKu$Vy~&v^OzOg|qYB1JvXtv~lthK6v06=7;(#_gCEmYtvJGaGz71pmPf14M_H-6v_usF_%~bU_<0lgEiW$#VJc z7GX#WUb9`d2CgTaDQ|p?h&2=i#8=05Pk}9?az7X1M#q4`vkE85db57|LTff=nZ%lg zE5gxvEL^sxwiXL%Z0p=y3)6};6J<#0i5wR=f4nl;;O=%<Mpz53o!Z>@k~CE+Rq@Y?wSR)W3(SjV#!^pJY15Iqx>#;J&L5 zJz0CaWum?Q#Rj%BqCgR$4Wv`-P0HGLj~ew4;FZ~lP#wYaF4T|aY}9gBAD(wUK2FM_ z^DQHY34xqbI~2!)ZIMKX$o$s@Fhu6EWB)35&5*X^T3se@Zbq9KO)jADmcE6ZCN(tj z#f)!M4E)4C7|V+li6hIKEoA8Vf3nKtxA6d=%+qMcC7l-7Tyu?Wg!O# zf9n~--;m9ebA68>U)j}OGXAyOtTH-LvcjZg0DN3bk2f)Gu1o-TojK>~HAe||6h1#{ zP7f3Trzh~Dkq;6@?kLy{>zgL%yB{CfmYdFTKTk55(tOwW_%}s>F7xlUkjmt zVe5q#L{J~g5|#TyZ`5_w3Dg4({4Nspx-M#fG+t)n$pK~2cO|3eja|EPp~i%pwOu_| zWq{V$RLIlmrA=|8#TeIYkX68 zgO4m3a+VRQB`e}m(Xm%orBN99glLTVihNn(mBiC^elf%Q50}~`0(S@o)1L*T8)vr| ztE?`3%fg|&x8HW}xc5DXG0JCksf0jiRtx7M)sNBz@M+>wTv{MZH`5tX08ftxD|a{M z@24WT@1TRqc{Kge^_lSzzIY@zXx@3fNa*?!BsMJcpSNP*A48;m=IBvp$xClZlN6@Q;FyTr@d;` z=^RrxpRpZme01XUc5HiM6}bE`F3~U8{=IVRH^8NO*nwP?dVzk$RO;dKhrO=CN`!k) zGTQamRd`K!9CRbXKAOLiA%5xhRen9T?8_olEQftqyETtym(I^q)Kn!WCGf2*H%}#J zroAI}t&5}+hm)k0ElG*#RCK>z4K(>ING3h{U3ZBQiMiorVU< z6D{JCEn{ox_16n)*{*#aw~>(`fojh3!KN>+))E^U@3R3XuunRb1S?SB<2${Dnxi~q z_jBW7H-=T@W>q=7=W(Rs^3tDr85yzdgI;_3!T`^0@)tL*arMjn=|#L~dFcPZBL3wc zEaFn7m*Z^StWhrTv9fts2^}IA-JwV77W~JaVThk4jv)QyO`<>$BGNB0q4QxM=dA6Z zS;0hODY5%_=wi$9=Sg#v{mD_*;G8rct%@F&kr;9xCBn#cRe&M_L7?nR8h&8(J$KYu?nY`@V)QEplr|* z{n@?q#i(`SmtqGGV8yI;r4tZTo3#t5*uv%uIukh@IvGykfdKP zWNT3_juPGE*ZBwAcu;)IWIFHZ0eVX}H5ycBNp_2K3Q;jsaliPbx%vx5mu>-rm;8o) zdvbJw`UJi?^h1V;DhjRK?cfSTWf5aAr#BE%twZ)zSpdABO>FrfsLPY!U6&NDc)LPO zrD4pvoi&zZxCM>Men=f-V|)O=zE{H1zV@^>hil5?+WIdF~;I-u3)SBiK!F|f8i}92|&i|LtYG6l^ETi_;^(d97qqxEp@F~o|4v1 zXHl6BncFgx!OGi!k!FwnFqCjV_1kxjXxOXVdB&sa0Ya^f`k}d63|WQZqKJbo3&?PA zh6D;|uS>CcZX>sBpS`=K@I$01k>s_7s_j~cy4vp)VstVN)Z2_Uc)1_dwzEf=aMP=-FE!%ui-RTNcK6Xxa>C8 zyPpUO+3xwdj8=2=mLgg#M-oQMvTQL>$E?nx%;0!dwMu^a!z@O&Uw{q`JZF$YP&4ni z%1q9~MyG)Y$=6)w24aX_(H7AYZ3D2)E75wAN8EK_o1cV^r!Uzo2{!X6_i#n}8i8Rn zOoew_S-Yp!V4Bs6iJk=~9~~&J9UcVi5a4SCt;I_X86vcNTl|{G8{Xq(3B0i)%oUD= z?|%jb^M6?}|3RwOrP6$P+GVs!l3@5p>}MIOT2akt=NsVCtWS+>X>g3uVXg`u-(ymm zxk;Tjl~hY>?k-{~s-Uhf5#OzBi2FSpmximEv3FwaqK7&JORypfb0&#~SuJTcClB2r ztT{*XF7!2U_k($g$=vbS+2X5^AuA8zxFV$p6%jz5zzvJ|2KjS&Azz#N05?8*q=f;Z z-O$c&$$Hkj7QR`x8S^O5J9+p)9W_8cnvQC;_HmVOSpU!xEU(tS#KQ|Z)iOz$SeUrZ z*3MpdF=Rj+p~5pZMMK$shLVmF)EB)ykJF=yBm_%GH{2wRc|EG8G$VA-^=LUwyD<%=lm5uyKNKcZZ%T5BICY1hw=F#iFIY2pyM zAKqdh!r^&(CoRTK*6soMeob?Ky30$-)6d)@?*vOGt_P=?p!+g6c&&LGdLuDET?~*! z(y75oXbqo~P!Jw9(Q%0)P?6lC}cJ0+vYmrwUa#QG%{8>6{12___(s(PHG z%GtsuXp9q*xlb3VYFiudZRy9YPsb%ZHB)m~!6&KN)=!6nU_8yDfOoj_e>f56aeQOG zcQEfav{EhVfLm$<4BWqp*Xw6~w za#PQ8suGI8=};EvDc5`JWywUmmh*mhsl=2#e4Xx^(`}f@w@Lhho9o-8{m)I}b&}CP z5+)<`u`9r@7o-*Pq3c$Zc2liSYDa%w#MvY^YD{7TuYdbf!_=%S)ux8cmY8);G zsn301R^JuUw_XeLGxvQoa2wKmVBF|F=dh3&=QU7Z>2iw_lPX5viO?dlqBQUHnWZg4S2Lq3Y6Yc^-%vwMA_mAScq?C9jlkA4O-j9 zfUg(XAI&#~F|^70oLyfQZ0*WU%l77Msq9$b(W6b;cEpYC>gw7oyX`owNcWksuIxGY z%_&YxLdoN`?XAfZ1xEcHJ{<}?NTW1WMf2+>2amz^tLui7E%ZI&ANSqXyQTB9FZgoL z-Dab(CL%U422^u`M$0sxtJr4zj*4}#Nkh+)vhTbKO2 zAe90_L&n%Ipe_iPjWq15CC52kvi`8$3#>MW0IO&K>iMhglh)7U=MC*g&hGIcuk68< zjW=_IAJ?9u;bUFf^#ktONqVh9B>OfwbBB+d!Z!15ix0a7PK zU4`!0!to4K&=)!=_0aTf0hy%$JVCe%)nI8^(M8sI9RX6Gyy@;YH}}Nm3rg+r6%U}F z(_F$xRAdBrsWth>){qrRYg}JdySz7dtA0=kQ|I2MosN;Cm?b2STn%%KuoAU!2%GP!qEdG|fT%Vp2vG{Q^c0a9z#^DxO>H(Wfif0SpEnm@K3HTua=V1Z=vOX2sI-rGt&tA-{mc<;WHi8g{i+;ETN zOW7AtP_+-aVseL_B8zld!w}Kr0vy>pT`?z%&w22MALx|18R=T1Xzre@Q^3Yy3;Bp< zQBB6K%(gI@PEW~3X^zm$)SF;^LzuaTFbFf$mEM+*o&X3pUC{J}b;GExIr?IWDcV5I zHX52wH(jEtVXDGO2@B{Kf;-+KV`bT{ZRkfE_p8~^Q}d>Ivf0jtFV}tfV!NvnFt7Xb zlwx`B$ex~Y=BVOzuUl6CxW(7jXT$28#lG11X}YchQHo&C?6S{^3n2ul+a63 z$QMW@7;6}6>}eD5y1%r{h^-tANQr^RG%=9RpVj1N;_l&wObm(lb_1Fc!kCLkdEAs& zDSbncuh`_u@izA$rOAz}E?>DvBiTQRH1Bbnw##!|Yc-jxTY|9|4_P$j`9(zz!tm#}%RhNXJri+x zfiizh>Jhn%aXtkt;hH^izw=b04m?1ho&)Z_TnephYL;TDKd%jj#MHO?}UwqGv3e~c$Lz`(@Vys?#XWnuOL z0qeeSI|p;1Nor3g-lPYaqttu{?_0s)imOq3Ulz~q*gsv3GX_)-zptbC_Rl%*C^u!D zy>dq9)w+ixcMbi@d=f0N(y!mo3*z-i3;b9u?-I*IjFr`eRj|`{-*3b`NC+_+ioDh; z8D-u4fF|Q7Ql%ReNLK{%n^h0~*;Kh)Ed3TgX?^9&R>c%iVloS_Tbq(y*wYA&w42(7 zSnH${-dp%$loYw4LB}2Ay zW1|&>l+u$GakuJJE7aJz1~EaU)x8S{qlDph>9c#qIboWC2EF9)9p_CxUn}5&!@qkm z-~YCl!a(%NwiH&3`_!DUP z@?!Lcwj_M@&^_5t1zL~ZRX(BOqs306~b+@MC%-D z(F%|{!C3!E3!BJTLL&jh?5eZ3b0KZ{Zhf2uN3nmn}I(&oOcUG@HuFjoQl^loJO z*`c-Yx$lc*bIp-icQ><^JCoyT6GHA*A#Ku=-4DL14R6{sm?@o7K+UwI{fB1F+vmNYp-nky(ppcj?c{_-n}{f za%sGywKudW$DQIf*v{)hPb>fF#eB2ym0O~U*T7Q+&dz41n8JJA@(QRT=pOY3LJ;+CKL zZR@0Qqcpm7;GVogF;5bzc$iT$ePlc?Ey2=hNbOIQtB0gOB^PM81}PobAd4;m79am3 zD@`iy48LDLtJ-}$wRoKr|0h3%{NN{7x=R=$N>=NCNz@mni52ou&@DM^d+WXc=3R#H z#{Gfgptn6aD`}3_p)XfMtitqsT|mu^d<kOqZCi#TtC2g zEA??&eYl*B;(C&=iR0ng8lmfnVJ}bojZHb>%;?`oR6+$s#5(>!J3gb3nad4uyUKTz)MOuPc$K?whfPoZn{9uhA8WGCE2^Y0N@%djoYiv5Q zY)10ZvBzS_R%e@?6m*jH>Gkbmvzj4W~A-k zTg%lwOGH@95$W$%a^#U9k3a#1|}@j%wQn- z?0MCc9s72b4GetYa@wi&5=4f)*Yue46QdlZ57m+(){A4(gwxcA26Pi%gaMrV!Lh{5!Jp7@ZgbLt+I_CdD9i&^O6i`T!%X@cb;TSXu>1 z=ZooCnB`bzV`(U|4eou{v;!Qi}6qxW45FWx5amy|@k*TNOnc2v_m;sC|%$pV< zogrxDbKUc0O)a)iNtl7$BA%CdNs{ zReubn8ift48clv)mq~Y5)Mew1+V@oMZl`hb_GBX zgG`dS0N6l*F~eGGE{d;chXP*mcGly)Bug~_V~L1QiT5=0%4YLyy;JqLDN^a*+6ppJ zd&&oo){<+cD=O5yv2@y*yUpQ5^^P9^BNsI(iG~3mHxu|;nhHzgVPR*h%w7{7y$v*-rBait5$G!OiQ~^?=4~n0Vvxlqq*`+; z1N3}TF$mCN&ORqi6KT`t)NT8T(u-Hi1YVSzK^PsoIq^xsKhDeJtW3|KhkQp8gB>TJ z1wlqf+c=brs-Nb8(iSG^44TN7Noq6v=z8_!LE*b8OPoUFz7TTD4U%9y!(`8l$gTMP zB&HRdDvx#iG_m;GQGgsldexotRgi-hrUm0C_;5ljDtm%m9_3~_VhI~}6HMhQGMyyL z4S>rZ`H&c*;8#RM+d&4SG*l{11)1Z;dbJBTxA8O zlTRS3AIa(OKFn>*_^|W_FmkHpS9*XL*91lJY_D4)NqF$|!?bR2HsIQxS2#tccCl|A z#NM#AS}1n5VU*&VxWHL-HKgJXHsK!W-%=SaW03C8Fy{cd#YjHWld18R|nHpx(p z?+YyR?3*@5ZQx(^tKM;t`}l5X5H-{+Ry|6VTPw!8Aj7&~ksTRa&8OHer09Oz0$!FA zn=0mj*C)H7%*OPLV#mFHXfhF zmE1)4FY}VD(8)u_Sv0VJ5<@aA*#GrYdjEyH`~N%;o{wH!XWifwyW5>8_X=+HxhZxc zmkd@gep{qPk9^$pjW-C=jfoH8UdjRo#6IumU_Owhv4Y0W>6Q=+J;5v=_c~tJQlHqq zQHOtCSGjYl?qzD6gL(JXK=IgiVdT6-w?zno`A>>EitpG{NZl~T80c<@o?znD18Mr7 z7VI&SKkWK5J=%IO4L*CTw_tc~L1D|+r zOD%9u8cUJkm}X+vtyNL!Jt(4NaeP+rW`u|K*IanPEpLo9B#729%$w(p*g!dm`W+GM zm-26?uVxEsPwbA;@%5gCY^7;nqsU;+2WWWZyKaGOdD>a45Nv zb^A<$ja4_}*r4im`$Q$0b*9a8gK{~t_E~cO7O+8os%2Se3%4pttz&P&Wyq{!J?eU%43?1Bj&bI_I$;S-;V&U( ze})%t+J7d2jj28)I|8e zZ6AX@Sn&*e7rd3Au|%)#FaU13&T&MJ4-0!!`S|XMHnKgdn|7~y^_OFXu@mLl^M3?d zK@kx9{5mtIzBGT1Zs?wxVW3p%-vNt5JX+Fib=4c+gNfZDrxH&J0!1GJo>k zxOI!NsNW3bbh!Zj)oVbm7+ifhtvBJ8U)p$#6V!qv^(a-Xob7$TT`N5DyppqzIaMf4 z{?gN34Z0Q+qwEdPyahWWoj4Sb(sCoRtMmqUdVwQ_SF zuMFJ+i@MVmkddo?*f8C-jV;llCKVmRtXs6GhyARD0H))j>*PXhRjR#{YZ8M!^F4EM zc#i+R%Dj8~-qruv#C-d=^7udFtl0Ts`fZ-gUMi`5vHx9Vg=O&fl$B>R)j$RR4@r#` z((&6-LN_1wxyP-TW@uf}33)-qt~rT4`K0RU909JsyHu#+$*+!~VzGfFBrlJEw50bRyo`xh8`7bCaI4US4&~+Gn0UO3A*06P z0hJVQn2PNUyRZ~aq^LIY$@s57N?g*R`bddcYZ5mJ^UUMiaE7Z)I=`)mHc%ho=emdC zmS0~hxYJJ1pG*X!nWfW2DI&&~W9rN;hU~%b>~(oc{X^U%`neEXRFnG_C-vpmu|+hc zOfzAAmTYiO`BxS{+{dPhvi8ttqX(Vx95RyyGwVM)4MF4toZpmF^*!ZE_Z54)SIK1K z&?LxidIMxvU^kH7U6_G=huK9O3qCu+eT_oO2XoAk3)}J`XXaPuB6xx*%Xt1dw+F;e z3DmyMOP8atBjag(G)hz3n%5>ZoBk!q2!52ViB;ktFf)3pZJnd5hEE1)@!?#@(aDH$YnqC+Tv^0uUUs2kqdCLp>oP1*;u2+28 zR0}41q1j{%v8_C}M1YTD6%wQP?X&F&i-b#-=*LV??C&0#!@ZNyd%DVGWwqTY)Zq2H zQ|s970?%O0-A|q(I9>gvC&oI({M#I1 zbiG9TT{3y;tQ8bIQjJ2k5#tN+T}aQ=33_1@)yv5UWxXr!EB(AN4=V=D-W6OmXY}s@ zR(6k7DaMd>zcE%AN0FHOvCX9=T1Dn0GPOOIVmFuHF8c}&4HL`tJb$M4!ArWDVK&n` zvA{7AdCa%6elS{qclGmb6NFQqcA~J~2xPt5<7o>sM?tKI_^y5@$AvVBgjKl>JN8n| zm&V`%tx$OsdCNG_MAX`|a|&Pg(bkE9YQ}TB%8R?bs~wiYlA4O$2m9b^Ik}8X`v!nOl`iJt;)mnPH00W1sbFBSw?Yz68d(II z|At>_Xfd>_ZY;%3|6u7w@l5$JvQLVh?Q8U;`0uslinb-P)3*ew(^bfLej&&IP+Xp3 z{V%8G>!+T6`QY;UhJkY_tQC{owHlNs(IupFe!9sxu|t0ei|X#a&1kUHXr{6Vei04N zP=n`EYzb$zQq?#ui%9KZ?xlIMQpW4%u9!_%XU3GWG=VK9P4KQUv`t-*sqkXUwd0(q zeHG5m4cuU=>+VEz4!eKmnNnA!;RjZP8Igy_LB-CJ9C6}qf_x5Pm@AJ)sJHVG?q4XP`qXPF zk{`Vjsx6|ZHY-9}2ZOyjNS$dwTWz|(*y9fTp3-dXW~!}@+`(5%_!dm^WNAuiVv++M zP`eo;q^c&~6n4fj|6pPDt22+(g|~7Z{G*W^F}+{^Uow)v20l>S46&381j*uf$Ihte zHo_Am=5g2Gz*e@dC32@CZf@PCf@_0K!x65Hmp<)bpHl~O{|JxEw7Nchul71lb~eb; zs-X5z_f@_3b}S23*+g%kLs8I>-<{3U#6HqkCqs~-tms^)`;z{Wcjz`##Sl}-pNYwV z3d;os_&S0*ceT}n*f1v^6_;9><*|;4e{A`kw&x0@9@H26`vvB%s4~PfHfI5Jp zqr@^WXN;$%l~s$XHsOZWn%ACgXUMOb|`%(b2{HQTj_xOakT_ zq}5YI`Eu)xNNldEyv}55UAy{$RkU2%WVnCpDd=o!N8I&5n@3c^+=dKwk0JaACaI^Q z)(`E%EGXnOYaWI7{WV9Pa<*V}@F+sLxWhlS@`zty z*D?k8@wI?_r*u)_?QAKYi<7|D&WzF5b6}oIFj5r2QErL&-14gm7|X* z!s$a-IWeQ`(R%=w?Zk}}M<#T{hL;>03;Pj8{YW1uEN%FT8t-jqhpHGGyr$1ch@>j$ z{SI5|y*HD}Y_wwpjv=-iTJN6w?d~-U)6Pf_D_(>XlSkfAD1HK6NiY`Rx8h|u@wtcp z!vIi{J2+}yaE%6Y8M57HoY?G&o3M9(W{=|D=+yIKm6Gjrl=a!b4d2DL>sk^ap-wrT zw?_#3_28E}rFXQ7q93int)_?HUK5<-CjWLDlCh%TF8J~9;QW4r4ZbLJ3mW4d5faSIjhKxQ1{rS$({#`g~C_-Q7>$HjS9fS!pW zt5-!1KLEk6-1N!`ZVSNwn5Tky@=7oR+e}yu{CQ3Q?3)nS;r0+HPE!`(ZW*&oX=+Mb zF4y>o3wYQmX6xrdg;FXRJ}eFRjWoU{3h4L~8ToIdapRrNkn0n$&m0J`=RPH;FIk&v z%aBuP>gVsq87a188h6?!5j85Z$v7Me`S)~yr_d%YVYP_X1Mzh2e+pHR5fVwy==^6` z6`6m5RY5n#Dmq-$^DvSZ^1*X5dAgfO2W;G=$$uKFA6B2**k(z3v8CUiquJ66N?@n`YAx?`m2I`UF>f4?w>5k cnWevqg)aIwsV1qhf2*GrWK^WfB+Xv_KiwsLWB>pF literal 0 HcmV?d00001 diff --git a/docs/workflow/debugging/coreclr/debugging-runtime.md b/docs/workflow/debugging/coreclr/debugging-runtime.md index e390a547965c67..74a742fb51e4c5 100644 --- a/docs/workflow/debugging/coreclr/debugging-runtime.md +++ b/docs/workflow/debugging/coreclr/debugging-runtime.md @@ -233,4 +233,4 @@ If the target process is using a .NET Runtime that is either from a daily build, There are three ways to configure Visual Studio to disable signature validation: 1. The [`DOTNET_ROOT` environment variable](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#dotnet_root-dotnet_rootx86): if Visual Studio is started from a command prompt where `DOTNET_ROOT` is set, it will ignore unsigned .NET runtime debugger libraries which are under the `DOTNET_ROOT` directory. 2. The `VSDebugger_ValidateDotnetDebugLibSignatures` environment variable: If you want to temporarily disable signature validation, run `set VSDebugger_ValidateDotnetDebugLibSignatures=0` in a command prompt, and start Visual Studio (devenv.exe) from this command prompt. -3. Set the `ValidateDotnetDebugLibSignatures` registry key: To disable signature validation on a more permanent bases, you can set the VS registry key to turn it off. To do so, open a Developer Command Prompt, and run `Common7\IDE\VsRegEdit.exe set local HKCU Debugger\EngineSwitches ValidateDotnetDebugLibSignatures dword 0` +3. Set the `ValidateDotnetDebugLibSignatures` registry key: To disable signature validation on a more permanent basis, you can set the VS registry key to turn it off. To do so, open a Developer Command Prompt, and run `Common7\IDE\VsRegEdit.exe set local HKCU Debugger\EngineSwitches ValidateDotnetDebugLibSignatures dword 0` diff --git a/docs/workflow/testing/libraries/filtering-tests.md b/docs/workflow/testing/libraries/filtering-tests.md index 28ba3e114977fc..35bf2cb2717920 100644 --- a/docs/workflow/testing/libraries/filtering-tests.md +++ b/docs/workflow/testing/libraries/filtering-tests.md @@ -337,3 +337,15 @@ A common usage in the libraries tests is the following: ``` This is put on test classes to indicate that none of the tests in that class (which as usual run serially with respect to each other) may run concurrently with tests in another class. This is used for tests that use a lot of disk space or memory, or dominate all the cores, such that they are likely to disrupt any tests that run concurrently. + +## FactAttribute and `Skip` + +Another way to disable the test entirely is to use the `Skip` named argument that is used on the `FactAttribute`. + +Example: +```cs +[Fact(Skip = "")] +``` + +If the reason for skipping is a link to an issue, it is recommended to use the `ActiveIssueAttribute` instead. +Otherwise, `Skip` allows for a more descriptive reason. diff --git a/eng/SourceBuild.props b/eng/SourceBuild.props index 5a8e7a4b4f05d4..5e12f4af83cc37 100644 --- a/eng/SourceBuild.props +++ b/eng/SourceBuild.props @@ -31,14 +31,15 @@ $(InnerBuildArgs) --nodereuse false $(InnerBuildArgs) --warnAsError false $(InnerBuildArgs) --outputrid $(TargetRid) - - $(InnerBuildArgs) /p:RuntimeOS=$(RuntimeOS) + + $(InnerBuildArgs) /p:PackageOS=$(RuntimeOS) /p:ToolsOS=$(RuntimeOS) + It's used to add TargetRid in the graph if the parent can't be detected. --> $(InnerBuildArgs) /p:AdditionalRuntimeIdentifierParent=$(BaseOS) $(InnerBuildArgs) /p:OfficialBuildId=$(OfficialBuildId) $(InnerBuildArgs) /p:ContinuousIntegrationBuild=$(ContinuousIntegrationBuild) - $(InnerBuildArgs) /p:PrimaryRuntimeFlavor=Mono /p:RuntimeFlavor=Mono + $(InnerBuildArgs) --usemonoruntime diff --git a/eng/Subsets.props b/eng/Subsets.props index 4af6e90f9172be..f1af6a47bfddcd 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -26,8 +26,12 @@ platforms (like s390x) where only Mono is supported. The primary runtime flavor is used to decide when to build the hosts and installers. --> - CoreCLR - Mono + CoreCLR + Mono + Mono + Mono + Mono + $(DefaultPrimaryRuntimeFlavor) @@ -481,12 +485,14 @@ - + + + @@ -494,11 +500,13 @@ + + - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index eafe55366b8c95..19abb875fe144c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -12,29 +12,29 @@ https://github.com/dotnet/wcf 7f504aabb1988e9a093c1e74d8040bd52feb2f01 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 https://github.com/dotnet/llvm-project @@ -44,29 +44,29 @@ https://github.com/dotnet/llvm-project 76f334f354eb653a7b409a5319b591ea09df5a43 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 https://github.com/dotnet/llvm-project @@ -80,273 +80,273 @@ https://github.com/dotnet/command-line-api 5618b2d243ccdeb5c7e50a298b33b13036b4351b - + https://github.com/dotnet/cecil - 9a7551fa7ba8218affbc1148eabc4b5c9f4e1151 + c32f0be86d4e72dfc0967ef08913889cfdbc8dc4 - + https://github.com/dotnet/emsdk - 2327f6b63d887979222f5bcf15f3322f800b9695 + ab09b0b8d6768d58e09c033beea1570d4ca74c1f - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/llvm-project - e08f119fe5b5cace97abf56f69ac25717437c9d9 + d6e31f5b29c46b9ac99ff747be0628fc55840cf7 - + https://github.com/dotnet/runtime - beb708f6fe999cbbe5542846c9985ce596569097 + 25f09dea3cebc63ef4d780daa90943fcaaacdd35 - + https://github.com/dotnet/runtime - beb708f6fe999cbbe5542846c9985ce596569097 + 25f09dea3cebc63ef4d780daa90943fcaaacdd35 - + https://github.com/dotnet/runtime - beb708f6fe999cbbe5542846c9985ce596569097 + 25f09dea3cebc63ef4d780daa90943fcaaacdd35 - + https://github.com/dotnet/runtime - beb708f6fe999cbbe5542846c9985ce596569097 + 25f09dea3cebc63ef4d780daa90943fcaaacdd35 - + https://github.com/dotnet/runtime - beb708f6fe999cbbe5542846c9985ce596569097 + 25f09dea3cebc63ef4d780daa90943fcaaacdd35 - + https://github.com/dotnet/runtime - beb708f6fe999cbbe5542846c9985ce596569097 + 25f09dea3cebc63ef4d780daa90943fcaaacdd35 - + https://github.com/dotnet/xharness - cc6611a8c5eee02e5095d9d14a8b0c509ac46e86 + aa434d0c7e6eb46df1ec11b3c63add37d835c4d0 - + https://github.com/dotnet/xharness - cc6611a8c5eee02e5095d9d14a8b0c509ac46e86 + aa434d0c7e6eb46df1ec11b3c63add37d835c4d0 - + https://github.com/dotnet/xharness - cc6611a8c5eee02e5095d9d14a8b0c509ac46e86 + aa434d0c7e6eb46df1ec11b3c63add37d835c4d0 - + https://github.com/dotnet/arcade - cb54ca21431ee8d96f91abfbc42237bcb001f9d1 + 5c98e75aa0078eebd3b8f9d6a6fbed1a1a5eb075 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 103c1eaca9ad80cdd1746abfb97c7f3c9d0b0f3b + d463925800632f9ba23995cc756590f92bea1f27 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 103c1eaca9ad80cdd1746abfb97c7f3c9d0b0f3b + d463925800632f9ba23995cc756590f92bea1f27 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 103c1eaca9ad80cdd1746abfb97c7f3c9d0b0f3b + d463925800632f9ba23995cc756590f92bea1f27 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 103c1eaca9ad80cdd1746abfb97c7f3c9d0b0f3b + d463925800632f9ba23995cc756590f92bea1f27 - + https://github.com/dotnet/hotreload-utils - 9a231fca1b904f869577e7abac71aff263fd0559 + 1400fe3bdc4f115168c2a9eefe2fd904885bb441 - + https://github.com/dotnet/runtime-assets - a18b8d48387a7980ba9e484ec7169c58731175e1 + a913d737add5a62c90968cabdb34323cd888393d - + https://github.com/dotnet/roslyn - d7a4cad21c39e18f3d5e1f7fa7dd3f93668066b4 + 56393223b78d294bccec3101e79dc03e1b3cb683 - + https://github.com/dotnet/roslyn - d7a4cad21c39e18f3d5e1f7fa7dd3f93668066b4 + 56393223b78d294bccec3101e79dc03e1b3cb683 - + https://github.com/dotnet/roslyn - d7a4cad21c39e18f3d5e1f7fa7dd3f93668066b4 + 56393223b78d294bccec3101e79dc03e1b3cb683 - + https://github.com/dotnet/roslyn-analyzers - 801122692fc2953759f41330f5d42e9144a034ea + 31e5d2773251838851d273edba1babcf60321f24 - + https://github.com/dotnet/roslyn-analyzers - 801122692fc2953759f41330f5d42e9144a034ea + 31e5d2773251838851d273edba1babcf60321f24 https://github.com/dotnet/sdk 2fd62c3936f5336b836f6b12df170aa0e90da767 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 103c1eaca9ad80cdd1746abfb97c7f3c9d0b0f3b + d463925800632f9ba23995cc756590f92bea1f27 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 103c1eaca9ad80cdd1746abfb97c7f3c9d0b0f3b + d463925800632f9ba23995cc756590f92bea1f27 diff --git a/eng/Versions.props b/eng/Versions.props index f8940b01835a10..00a9da19b8e113 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,7 +10,7 @@ 7.0.5 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) preview - 4 + 5 -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) $(SdkBandVersion)$(WorkloadVersionSuffix) - 3.3.5-beta1.23218.1 - 8.0.0-preview.23218.1 + 3.3.5-beta1.23251.1 + 8.0.0-preview.23251.1 - 4.7.0-1.23205.4 - 4.7.0-1.23205.4 - 4.7.0-1.23205.4 + 4.7.0-1.23226.15 + 4.7.0-1.23226.15 + 4.7.0-1.23226.15 8.0.100-preview.2.23107.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 2.5.1-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 - 8.0.0-beta.23217.1 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 2.5.1-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 + 8.0.0-beta.23253.3 6.0.0-preview.1.102 - 8.0.0-preview.4.23177.1 + 8.0.0-preview.5.23251.1 6.0.0 - 8.0.0-preview.4.23177.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 + 8.0.0-preview.5.23251.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 1.0.0-alpha.1.23106.1 1.0.0-alpha.1.23106.1 @@ -126,44 +126,41 @@ 7.0.0 5.0.0 4.5.5 - 4.5.0 6.0.1 - 4.3.0 6.0.0 - 4.3.1 5.0.0 5.0.0 5.0.0 7.0.0 4.9.0 - 8.0.0-preview.4.23177.1 + 8.0.0-preview.5.23251.1 6.0.0 7.0.0 4.5.4 4.5.0 - 8.0.0-preview.4.23177.1 + 8.0.0-preview.5.23251.1 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 - 8.0.0-beta.23179.4 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 + 8.0.0-beta.23252.1 - 1.0.0-prerelease.23175.4 - 1.0.0-prerelease.23175.4 - 1.0.0-prerelease.23175.4 - 1.0.0-prerelease.23175.4 - 1.0.0-prerelease.23175.4 - 1.0.0-prerelease.23175.4 + 1.0.0-prerelease.23229.3 + 1.0.0-prerelease.23229.3 + 1.0.0-prerelease.23229.3 + 1.0.0-prerelease.23229.3 + 1.0.0-prerelease.23229.3 + 1.0.0-prerelease.23229.3 16.11.23-beta1.23063.1 2.0.0-beta4.22564.1 @@ -183,10 +180,10 @@ 1.1.0 17.4.0-preview-20220707-01 - 1.0.0-prerelease.23212.1 - 1.0.0-prerelease.23212.1 - 1.0.0-prerelease.23212.1 - 1.1.0-alpha.0.23179.3 + 8.0.0-prerelease.23253.1 + 8.0.0-prerelease.23253.1 + 8.0.0-prerelease.23253.1 + 8.0.0-alpha.0.23252.1 2.4.2 1.0.0 2.4.5 @@ -213,41 +210,41 @@ 7.0.0-preview-20221010.1 - 8.0.0-preview.4.23177.1 + 8.0.0-preview.5.23251.1 - 0.11.4-alpha.23178.1 + 0.11.4-alpha.23252.1 8.0.0-preview.4.23177.3 2.1.7 8.0.0-alpha.1.23180.2 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 - 8.0.0-preview.4.23218.1 + 8.0.0-preview.5.23252.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 - 14.0.0-alpha.1.23179.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 + 14.0.0-alpha.1.23228.1 1.0.0-alpha.1.23106.1 1.0.0-alpha.1.23106.1 diff --git a/eng/build.ps1 b/eng/build.ps1 index 6bf2dc78f7c067..fc2712fcafe512 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -17,6 +17,7 @@ Param( [ValidateSet("Debug","Release")][string][Alias('lc')]$librariesConfiguration, [ValidateSet("CoreCLR","Mono")][string][Alias('rf')]$runtimeFlavor, [ValidateSet("Debug","Release","Checked")][string][Alias('hc')]$hostConfiguration, + [switch]$usemonoruntime = $false, [switch]$ninja, [switch]$msbuild, [string]$cmakeargs, @@ -51,6 +52,7 @@ function Get-Help() { Write-Host " -subset (-s) Build a subset, print available subsets with -subset help." Write-Host " '-subset' can be omitted if the subset is given as the first argument." Write-Host " [Default: Builds the entire repo.]" + Write-Host " -usemonoruntime Product a .NET runtime with Mono as the underlying runtime." Write-Host " -verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]." Write-Host " [Default: Minimal]" Write-Host " -vs Open the solution with Visual Studio using the locally acquired SDK." @@ -251,6 +253,7 @@ foreach ($argument in $PSBoundParameters.Keys) { "runtimeConfiguration" { $arguments += " /p:RuntimeConfiguration=$((Get-Culture).TextInfo.ToTitleCase($($PSBoundParameters[$argument])))" } "runtimeFlavor" { $arguments += " /p:RuntimeFlavor=$($PSBoundParameters[$argument].ToLowerInvariant())" } + "usemonoruntime" { $arguments += " /p:PrimaryRuntimeFlavor=Mono" } "librariesConfiguration" { $arguments += " /p:LibrariesConfiguration=$((Get-Culture).TextInfo.ToTitleCase($($PSBoundParameters[$argument])))" } "hostConfiguration" { $arguments += " /p:HostConfiguration=$((Get-Culture).TextInfo.ToTitleCase($($PSBoundParameters[$argument])))" } "framework" { $arguments += " /p:BuildTargetFramework=$($PSBoundParameters[$argument].ToLowerInvariant())" } @@ -304,13 +307,6 @@ foreach ($config in $configuration) { $argumentsWithConfig = $arguments + " -configuration $((Get-Culture).TextInfo.ToTitleCase($config))"; foreach ($singleArch in $arch) { $argumentsWithArch = "/p:TargetArchitecture=$singleArch " + $argumentsWithConfig - if ($os -eq "browser") { - $env:__DistroRid="browser-$singleArch" - } elseif ($os -eq "wasi") { - $env:__DistroRid="wasi-$singleArch" - } else { - $env:__DistroRid="win-$singleArch" - } Invoke-Expression "& `"$PSScriptRoot/common/build.ps1`" $argumentsWithArch" if ($lastExitCode -ne 0) { $failedBuilds += "Configuration: $config, Architecture: $singleArch" diff --git a/eng/build.sh b/eng/build.sh index 1147ec248a7842..469fd9d06714b2 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -31,7 +31,8 @@ usage() echo " --librariesConfiguration (-lc) Libraries build configuration: Debug or Release." echo " [Default: Debug]" echo " --os Target operating system: windows, linux, freebsd, osx, maccatalyst, tvos," - echo " tvossimulator, ios, iossimulator, android, browser, wasi, netbsd, illumos or solaris." + echo " tvossimulator, ios, iossimulator, android, browser, wasi, netbsd, illumos, solaris" + echo " linux-musl or linux-bionic." echo " [Default: Your machine's OS.]" echo " --outputrid Optional argument that overrides the target rid name." echo " --projects Project or solution file(s) to build." @@ -44,6 +45,7 @@ usage() echo " --subset (-s) Build a subset, print available subsets with -subset help." echo " '--subset' can be omitted if the subset is given as the first argument." echo " [Default: Builds the entire repo.]" + echo " --usemonoruntime Product a .NET runtime with Mono as the underlying runtime." echo " --verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]." echo " [Default: Minimal]" echo "" @@ -134,7 +136,7 @@ initDistroRid() local passedRootfsDir="" local targetOs="$1" - local buildArch="$2" + local targetArch="$2" local isCrossBuild="$3" local isPortableBuild="$4" @@ -142,7 +144,7 @@ initDistroRid() if [[ $isCrossBuild == 1 && "$targetOs" != "osx" ]]; then passedRootfsDir=${ROOTFS_DIR} fi - initDistroRidGlobal ${targetOs} ${buildArch} ${isPortableBuild} ${passedRootfsDir} + initDistroRidGlobal "${targetOs}" "${targetArch}" "${isPortableBuild}" "${passedRootfsDir}" } showSubsetHelp() @@ -286,6 +288,14 @@ while [[ $# > 0 ]]; do os="illumos" ;; solaris) os="solaris" ;; + linux-bionic) + os="linux" + __PortableTargetOS=linux-bionic + ;; + linux-musl) + os="linux" + __PortableTargetOS=linux-musl + ;; *) echo "Unsupported target OS '$2'." echo "The allowed values are windows, linux, freebsd, osx, maccatalyst, tvos, tvossimulator, ios, iossimulator, android, browser, wasi, illumos and solaris." @@ -360,6 +370,11 @@ while [[ $# > 0 ]]; do shift 2 ;; + -usemonoruntime) + arguments="$arguments /p:PrimaryRuntimeFlavor=Mono" + shift 1 + ;; + -librariesconfiguration|-lc) if [ -z ${2+x} ]; then echo "No libraries configuration supplied. See help (--help) for supported libraries configurations." 1>&2 @@ -438,7 +453,7 @@ while [[ $# > 0 ]]; do echo "No value for outputrid is supplied. See help (--help) for supported values." 1>&2 exit 1 fi - arguments="$arguments /p:OutputRid=$(echo "$2" | tr "[:upper:]" "[:lower:]")" + arguments="$arguments /p:OutputRID=$(echo "$2" | tr "[:upper:]" "[:lower:]")" shift 2 ;; @@ -516,7 +531,7 @@ if [[ "${TreatWarningsAsErrors:-}" == "false" ]]; then arguments="$arguments -warnAsError 0" fi -initDistroRid $os $arch $crossBuild $portableBuild +initDistroRid "$os" "$arch" "$crossBuild" "$portableBuild" # Disable targeting pack caching as we reference a partially constructed targeting pack and update it later. # The later changes are ignored when using the cache. diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 1deadcc676e309..6a59f753b5d329 100755 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -70,7 +70,7 @@ __AlpinePackages+=" krb5-dev" __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" -__FreeBSDBase="12.3-RELEASE" +__FreeBSDBase="12.4-RELEASE" __FreeBSDPkg="1.17.0" __FreeBSDABI="12" __FreeBSDPackages="libunwind" @@ -330,7 +330,7 @@ while :; do ;; freebsd13) __CodeName=freebsd - __FreeBSDBase="13.0-RELEASE" + __FreeBSDBase="13.2-RELEASE" __FreeBSDABI="13" __SkipUnmount=1 ;; diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 1c9d212d135926..ce01673c7a6b48 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -67,13 +67,25 @@ elseif(TARGET_ARCH_NAME STREQUAL "armv6") endif() elseif(TARGET_ARCH_NAME STREQUAL "ppc64le") set(CMAKE_SYSTEM_PROCESSOR ppc64le) - set(TOOLCHAIN "powerpc64le-linux-gnu") + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/powerpc64le-alpine-linux-musl) + set(TOOLCHAIN "powerpc64le-alpine-linux-musl") + else() + set(TOOLCHAIN "powerpc64le-linux-gnu") + endif() elseif(TARGET_ARCH_NAME STREQUAL "riscv64") set(CMAKE_SYSTEM_PROCESSOR riscv64) - set(TOOLCHAIN "riscv64-linux-gnu") + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/riscv64-alpine-linux-musl) + set(TOOLCHAIN "riscv64-alpine-linux-musl") + else() + set(TOOLCHAIN "riscv64-linux-gnu") + endif() elseif(TARGET_ARCH_NAME STREQUAL "s390x") set(CMAKE_SYSTEM_PROCESSOR s390x) - set(TOOLCHAIN "s390x-linux-gnu") + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/s390x-alpine-linux-musl) + set(TOOLCHAIN "s390x-alpine-linux-musl") + else() + set(TOOLCHAIN "s390x-linux-gnu") + endif() elseif(TARGET_ARCH_NAME STREQUAL "x64") set(CMAKE_SYSTEM_PROCESSOR x86_64) if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/x86_64-alpine-linux-musl) @@ -92,7 +104,11 @@ elseif(TARGET_ARCH_NAME STREQUAL "x64") endif() elseif(TARGET_ARCH_NAME STREQUAL "x86") set(CMAKE_SYSTEM_PROCESSOR i686) - set(TOOLCHAIN "i686-linux-gnu") + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl) + set(TOOLCHAIN "i586-alpine-linux-musl") + else() + set(TOOLCHAIN "i686-linux-gnu") + endif() if(TIZEN) set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu/9.2.0") endif() @@ -266,8 +282,11 @@ elseif(TARGET_ARCH_NAME MATCHES "^(arm64|x64)$") add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") endif() elseif(TARGET_ARCH_NAME STREQUAL "x86") + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl) + add_toolchain_linker_flag("--target=${TOOLCHAIN}") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib/gcc/${TOOLCHAIN}") + endif() add_toolchain_linker_flag(-m32) - if(TIZEN) add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") @@ -307,6 +326,9 @@ if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$") add_compile_options(-mfloat-abi=softfp) endif() elseif(TARGET_ARCH_NAME STREQUAL "x86") + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl) + add_compile_options(--target=${TOOLCHAIN}) + endif() add_compile_options(-m32) add_compile_options(-Wno-error=unused-command-line-argument) endif() diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh index 7aee4213e1b069..517401b688bf76 100644 --- a/eng/common/native/init-compiler.sh +++ b/eng/common/native/init-compiler.sh @@ -64,7 +64,7 @@ if [ -z "$CLR_CC" ]; then if [ -z "$majorVersion" ]; then # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. if [ "$compiler" = "clang" ]; then versions="16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" - elif [ "$compiler" = "gcc" ]; then versions="12 11 10 9 8 7 6 5 4.9"; fi + elif [ "$compiler" = "gcc" ]; then versions="13 12 11 10 9 8 7 6 5 4.9"; fi for version in $versions; do _major="${version%%.*}" diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index b214a31db23611..44ad26abf54ba2 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -25,7 +25,7 @@ parameters: enablePublishTestResults: false enablePublishUsingPipelines: false enableBuildRetry: false - disableComponentGovernance: false + disableComponentGovernance: '' componentGovernanceIgnoreDirectories: '' mergeTestResults: false testRunTitle: '' @@ -155,11 +155,16 @@ jobs: uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} continueOnError: true - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), ne(parameters.disableComponentGovernance, 'true')) }}: - - task: ComponentGovernanceComponentDetection@0 - continueOnError: true - inputs: - ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + - template: /eng/common/templates/steps/component-governance.yml + parameters: + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false + ${{ else }}: + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml new file mode 100644 index 00000000000000..0ecec47b0c9177 --- /dev/null +++ b/eng/common/templates/steps/component-governance.yml @@ -0,0 +1,13 @@ +parameters: + disableComponentGovernance: false + componentGovernanceIgnoreDirectories: '' + +steps: +- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: + - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + displayName: Set skipComponentGovernanceDetection variable +- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: + - task: ComponentGovernanceComponentDetection@0 + continueOnError: true + inputs: + ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file diff --git a/eng/docker/build-docker-sdk.ps1 b/eng/docker/build-docker-sdk.ps1 index bc73312efcb6c5..1a09343defbf6e 100755 --- a/eng/docker/build-docker-sdk.ps1 +++ b/eng/docker/build-docker-sdk.ps1 @@ -36,6 +36,7 @@ if ($buildWindowsContainers) # 2. Runtime pack (microsoft.netcore.app.runtime.win-x64) # 3. targetingpacks.targets, so stress test builds can target the live-built runtime instead of the one in the pre-installed SDK # 4. testhost + # 5. msquic interop sources (needed for HttpStress) $binArtifacts = "$REPO_ROOT_DIR\artifacts\bin" $dockerContext = "$REPO_ROOT_DIR\artifacts\docker-context" @@ -51,6 +52,8 @@ if ($buildWindowsContainers) -Destination $dockerContext\testhost Copy-Item -Recurse -Path $REPO_ROOT_DIR\eng\targetingpacks.targets ` -Destination $dockerContext\targetingpacks.targets + Copy-Item -Recurse -Path $REPO_ROOT_DIR\src\libraries\System.Net.Quic\src\System\Net\Quic\Interop ` + -Destination $dockerContext\msquic-interop # In case of non-CI builds, testhost may already contain Microsoft.AspNetCore.App (see build-local.ps1 in HttpStress): $testHostAspNetCorePath="$dockerContext\testhost\net$dotNetVersion-windows-$configuration-x64/shared/Microsoft.AspNetCore.App" diff --git a/eng/docker/libraries-sdk.linux.Dockerfile b/eng/docker/libraries-sdk.linux.Dockerfile index a06bd46fcb729a..401ce9f1ffd432 100644 --- a/eng/docker/libraries-sdk.linux.Dockerfile +++ b/eng/docker/libraries-sdk.linux.Dockerfile @@ -1,5 +1,5 @@ # Builds and copies library artifacts into target dotnet sdk image -ARG BUILD_BASE_IMAGE=mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-f39df28-20191023143754 +ARG BUILD_BASE_IMAGE=mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:7.0-bullseye-slim FROM $BUILD_BASE_IMAGE as corefxbuild @@ -26,6 +26,7 @@ RUN bash ./dotnet-install.sh --channel $_DOTNET_INSTALL_CHANNEL --quality daily # 2. Runtime pack (microsoft.netcore.app.runtime.linux-x64) # 3. targetingpacks.targets, so stress test builds can target the live-built runtime instead of the one in the pre-installed SDK # 4. testhost +# 5. msquic interop sources (needed for HttpStress) COPY --from=corefxbuild \ /repo/artifacts/bin/microsoft.netcore.app.ref \ @@ -43,6 +44,10 @@ COPY --from=corefxbuild \ /repo/artifacts/bin/testhost \ /live-runtime-artifacts/testhost +COPY --from=corefxbuild \ + /repo/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop \ + /live-runtime-artifacts/msquic-interop + # Add AspNetCore bits to testhost: ENV _ASPNETCORE_SOURCE="/usr/share/dotnet/shared/Microsoft.AspNetCore.App/$VERSION*" ENV _ASPNETCORE_DEST="/live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/shared/Microsoft.AspNetCore.App" diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index 286a5d9606d4e9..5f7dcb8c43b47c 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -77,7 +77,14 @@ $([MSBuild]::NormalizeDirectory('$(MonoArtifactsPath)')) - + + <_nativeAotRuntimeFiles Include="$(CoreCLRAotSdkDir)*" /> + + true + + + + @@ -170,6 +177,7 @@ "$2" +done > "$2" diff --git a/eng/native/init-distro-rid.sh b/eng/native/init-distro-rid.sh index 3f22de10061fa3..70503dd3e0bc03 100644 --- a/eng/native/init-distro-rid.sh +++ b/eng/native/init-distro-rid.sh @@ -1,105 +1,74 @@ #!/usr/bin/env bash -# initNonPortableDistroRid +# getNonPortableDistroRid # # Input: # targetOs: (str) -# buildArch: (str) -# isPortable: (int) +# targetArch: (str) # rootfsDir: (str) # # Return: -# None -# -# Notes: -# -# initNonPortableDistroRid will attempt to initialize a non portable rid. These -# rids are specific to distros need to build the product/package and consume -# them on the same platform. -# -# If -portablebuild=false is passed a non-portable rid will be created for any -# distro. -# -# It is important to note that the function does not return anything, but it -# exports __DistroRid, if there is a non-portable distro rid to be used. -# -initNonPortableDistroRid() +# non-portable rid +getNonPortableDistroRid() { - # Make sure out parameter is cleared. - __DistroRid= - local targetOs="$1" - local buildArch="$2" - local isPortable="$3" - local rootfsDir="$4" - local nonPortableBuildID="" + local targetArch="$2" + local rootfsDir="$3" + local nonPortableRid="" if [ "$targetOs" = "linux" ]; then if [ -e "${rootfsDir}/etc/os-release" ]; then source "${rootfsDir}/etc/os-release" - # We have forced __PortableBuild=0. This is because -portablebuld - # has been passed as false. - if (( isPortable == 0 )); then - if [[ "${ID}" == "rhel" || "${ID}" == "rocky" || "${ID}" == "alpine" ]]; then - # remove the last version digit - VERSION_ID="${VERSION_ID%.*}" - fi + if [[ "${ID}" == "rhel" || "${ID}" == "rocky" || "${ID}" == "alpine" ]]; then + # remove the last version digit + VERSION_ID="${VERSION_ID%.*}" + fi - if [[ "${VERSION_ID}" =~ ^([[:digit:]]|\.)+$ ]]; then - nonPortableBuildID="${ID}.${VERSION_ID}-${buildArch}" - else - # Rolling release distros either do not set VERSION_ID, set it as blank or - # set it to non-version looking string (such as TEMPLATE_VERSION_ID on ArchLinux); - # so omit it here to be consistent with everything else. - nonPortableBuildID="${ID}-${buildArch}" - fi + if [[ "${VERSION_ID:-}" =~ ^([[:digit:]]|\.)+$ ]]; then + nonPortableRid="${ID}.${VERSION_ID}-${targetArch}" + else + # Rolling release distros either do not set VERSION_ID, set it as blank or + # set it to non-version looking string (such as TEMPLATE_VERSION_ID on ArchLinux); + # so omit it here to be consistent with everything else. + nonPortableRid="${ID}-${targetArch}" fi elif [ -e "${rootfsDir}/android_platform" ]; then source "$rootfsDir"/android_platform - nonPortableBuildID="$RID" + nonPortableRid="$RID" fi fi if [ "$targetOs" = "freebsd" ]; then - if (( isPortable == 0 )); then - # $rootfsDir can be empty. freebsd-version is shell script and it should always work. - __freebsd_major_version=$($rootfsDir/bin/freebsd-version | { read v; echo "${v%%.*}"; }) - nonPortableBuildID="freebsd.$__freebsd_major_version-${buildArch}" - fi + # $rootfsDir can be empty. freebsd-version is shell script and it should always work. + __freebsd_major_version=$($rootfsDir/bin/freebsd-version | { read v; echo "${v%%.*}"; }) + nonPortableRid="freebsd.$__freebsd_major_version-${targetArch}" elif command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then __android_sdk_version=$(getprop ro.build.version.sdk) - nonPortableBuildID="android.$__android_sdk_version-${buildArch}" + nonPortableRid="android.$__android_sdk_version-${targetArch}" elif [ "$targetOs" = "illumos" ]; then __uname_version=$(uname -v) case "$__uname_version" in omnios-*) __omnios_major_version=$(echo "${__uname_version:8:2}") - nonPortableBuildID=omnios."$__omnios_major_version"-"$buildArch" + nonPortableRid=omnios."$__omnios_major_version"-"$targetArch" ;; joyent_*) __smartos_major_version=$(echo "${__uname_version:7:4}") - nonPortableBuildID=smartos."$__smartos_major_version"-"$buildArch" + nonPortableRid=smartos."$__smartos_major_version"-"$targetArch" ;; illumos_*) - nonPortableBuildID=openindiana-"$buildArch" + nonPortableRid=openindiana-"$targetArch" ;; esac elif [ "$targetOs" = "solaris" ]; then __uname_version=$(uname -v) __solaris_major_version=$(echo "${__uname_version%.*}") - nonPortableBuildID=solaris."$__solaris_major_version"-"$buildArch" + nonPortableRid=solaris."$__solaris_major_version"-"$targetArch" fi - if [ -n "${nonPortableBuildID}" ]; then - __DistroRid="${nonPortableBuildID}" - - # We are using a non-portable build rid. Force __PortableBuild to false. - __PortableBuild=0 - - export __DistroRid __PortableBuild - fi + echo "$(echo $nonPortableRid | tr '[:upper:]' '[:lower:]')" } # initDistroRidGlobal @@ -118,20 +87,13 @@ initNonPortableDistroRid() # It is important to note that the function does not return anything, but it # exports the following variables on success: # -# __DistroRid -# __PortableBuild +# __DistroRid : Non-portable rid of the target platform. +# __PortableTargetOS : OS-part of the portable rid that corresponds to the target platform. # initDistroRidGlobal() { - # __DistroRid must be set at the end of the function. - # Previously we would create a variable __HostDistroRid and/or __DistroRid. - # - # __HostDistroRid was used in the case of a non-portable build, it has been - # deprecated. Now only __DistroRid is supported. It will be used for both - # portable and non-portable rids and will be used in build-packages.sh - local targetOs="$1" - local buildArch="$2" + local targetArch="$2" local isPortable="$3" local rootfsDir="" if [ "$#" -ge 4 ]; then @@ -146,71 +108,17 @@ initDistroRidGlobal() fi fi - initNonPortableDistroRid "${targetOs}" "${buildArch}" "${isPortable}" "${rootfsDir}" - - if [ "$buildArch" = "wasm" ]; then - if [ "$targetOs" = "browser" ]; then - __DistroRid=browser-wasm - export __DistroRid - elif [ "$targetOs" = "wasi" ]; then - __DistroRid=wasi-wasm - export __DistroRid - fi - fi - - if [ -z "${__DistroRid}" ]; then - # The non-portable build rid was not set. Set the portable rid. + __DistroRid=$(getNonPortableDistroRid "${targetOs}" "${targetArch}" "${rootfsDir}") - __PortableBuild=1 - export __PortableBuild - local distroRid="" + if [ -z "${__PortableTargetOS:-}" ]; then + __PortableTargetOS="$targetOs" # Check for musl-based distros (e.g Alpine Linux, Void Linux). if "${rootfsDir}/usr/bin/ldd" --version 2>&1 | grep -q musl || strings "${rootfsDir}/usr/bin/ldd" 2>&1 | grep -q musl; then - distroRid="linux-musl-${buildArch}" + __PortableTargetOS="linux-musl" fi - - if [ -z "${distroRid}" ]; then - if [ "$targetOs" = "linux" ]; then - distroRid="linux-$buildArch" - elif [ "$targetOs" = "linux-bionic" ]; then - distroRid="linux-bionic-$buildArch" - elif [ "$targetOs" = "osx" ]; then - distroRid="osx-$buildArch" - elif [ "$targetOs" = "maccatalyst" ]; then - distroRid="maccatalyst-$buildArch" - elif [ "$targetOs" = "tvos" ]; then - distroRid="tvos-$buildArch" - elif [ "$targetOs" = "tvossimulator" ]; then - distroRid="tvossimulator-$buildArch" - elif [ "$targetOs" = "ios" ]; then - distroRid="ios-$buildArch" - elif [ "$targetOs" = "iossimulator" ]; then - distroRid="iossimulator-$buildArch" - elif [ "$targetOs" = "android" ]; then - distroRid="android-$buildArch" - elif [ "$targetOs" = "browser" ]; then - distroRid="browser-$buildArch" - elif [ "$targetOs" = "wasi" ]; then - distroRid="wasi-$buildArch" - elif [ "$targetOs" = "freebsd" ]; then - distroRid="freebsd-$buildArch" - elif [ "$targetOs" = "illumos" ]; then - distroRid="illumos-$buildArch" - elif [ "$targetOs" = "solaris" ]; then - distroRid="solaris-$buildArch" - fi - fi - - __DistroRid="${distroRid}" - export __DistroRid - fi - - if [ -z "$__DistroRid" ]; then - echo "DistroRid is not set. This is almost certainly an error" - exit 1 fi - echo "__DistroRid: ${__DistroRid}" + export __DistroRid __PortableTargetOS } diff --git a/eng/native/init-vs-env.cmd b/eng/native/init-vs-env.cmd index 68242ed725f67e..6c1ad8f3a17862 100644 --- a/eng/native/init-vs-env.cmd +++ b/eng/native/init-vs-env.cmd @@ -8,7 +8,7 @@ if /i "%~1" == "x86" (set __VCBuildArch=x86) if /i "%~1" == "x64" (set __VCBuildArch=x86_amd64) if /i "%~1" == "arm" (set __VCBuildArch=x86_arm) if /i "%~1" == "arm64" (set __VCBuildArch=x86_arm64) -if /i "%~1" == "wasm" (set __VCBuildArch=x86_amd64) +if /i "%~1" == "wasm" (if /i "%PROCESSOR_ARCHITECTURE%" == "ARM64" (set __VCBuildArch=x86_arm64) else (set __VCBuildArch=x86_amd64)) :: Default to highest Visual Studio version available that has Visual C++ tools. :: diff --git a/eng/nativepgo.targets b/eng/nativepgo.targets index cfd41d5e975a8f..9f5984efdb6332 100644 --- a/eng/nativepgo.targets +++ b/eng/nativepgo.targets @@ -1,8 +1,7 @@ true - - false + true false false diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 6124c13390ee6f..12f72b0d9e265f 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -73,7 +73,7 @@ jobs: - ${{ if and(eq(parameters.osGroup, 'linux'), eq(parameters.osSubGroup, '_bionic')) }}: - name: _osParameter - value: /p:RuntimeOS=linux-bionic + value: -os linux-bionic - name: crossArg value: '' diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index 5aa301933e21e5..15529c28b36f3d 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -402,6 +402,28 @@ jobs: crossBuild: true ${{ insert }}: ${{ parameters.jobParameters }} +# Linux RISCV64 + +- ${{ if containsValue(parameters.platforms, 'linux_riscv64') }}: + - template: xplat-setup.yml + parameters: + jobTemplate: ${{ parameters.jobTemplate }} + helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} + variables: ${{ parameters.variables }} + osGroup: linux + archType: riscv64 + targetRid: linux-riscv64 + platform: linux_riscv64 + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + container: linux_riscv64 + jobParameters: + runtimeFlavor: ${{ parameters.runtimeFlavor }} + buildConfig: ${{ parameters.buildConfig }} + helixQueueGroup: ${{ parameters.helixQueueGroup }} + crossBuild: true + disableClrTest: true + ${{ insert }}: ${{ parameters.jobParameters }} + # WASI WebAssembly - ${{ if containsValue(parameters.platforms, 'wasi_wasm') }}: diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index 4d6f8a22c6cc40..fac03cf7e5832c 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -63,17 +63,22 @@ resources: env: ROOTFS_DIR: /crossrootfs/ppc64le + - container: linux_riscv64 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-cross-riscv64 + env: + ROOTFS_DIR: /crossrootfs/riscv64 + - container: debian-11-gcc12-amd64 image: mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-gcc12-amd64 - container: linux_x64_llvmaot - image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 - container: browser_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-webassembly-net8-20230327150025-4404b5c + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-webassembly-net8 - container: wasi_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-webassembly-net8-20230327150037-4404b5c + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-webassembly-net8 - container: freebsd_x64 image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-12 diff --git a/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml b/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml index 174832216912bd..f1073500a44f54 100644 --- a/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml +++ b/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml @@ -14,6 +14,7 @@ parameters: nativeAotTest: false runtimeFlavor: 'mono' runtimeVariant: 'monointerpreter' + llvmAotStepContainer: '' scenarios: - normal variables: {} @@ -57,9 +58,11 @@ steps: - ${{ if eq(parameters.runtimeVariant, 'llvmaot') }}: - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot mono_aot ${{ parameters.buildConfig }} ${{ parameters.archType }} displayName: "LLVM AOT compile CoreCLR tests" + target: ${{ coalesce(parameters.llvmAotStepContainer, parameters.container) }} - ${{ if eq(parameters.runtimeVariant, 'llvmfullaot') }}: - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot mono_fullaot ${{ parameters.buildConfig }} ${{ parameters.archType }} displayName: "LLVM AOT compile CoreCLR tests" + target: ${{ coalesce(parameters.llvmAotStepContainer, parameters.container) }} - ${{ if eq(parameters.archType, 'arm64') }}: - ${{ if eq(parameters.runtimeVariant, 'llvmaot') }}: - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot mono_aot ${{ parameters.buildConfig }} ${{ parameters.archType }} $(_monoAotCrossCompileArg) /p:RuntimeVariant=llvmfullaot -maxcpucount:2 diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index d6c49f05be77b9..e7550889d02e9b 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -583,8 +583,8 @@ jobs: - jitpartialcompilation - jitpartialcompilation_pgo - jitobjectstackallocation - - jitgeneralizedpromotion - - jitgeneralizedpromotion_full + - jitphysicalpromotion + - jitphysicalpromotion_full ${{ if in(parameters.testGroup, 'jit-cfg') }}: scenarios: @@ -647,6 +647,14 @@ jobs: displayName: 'Upload artifacts SuperPMI $(CollectionName)-$(CollectionType) collection' condition: always() + # Add authenticated pip feed + - task: PipAuthenticate@1 + displayName: 'Pip Authenticate' + inputs: + artifactFeeds: public/dotnet-public-pypi + onlyAddExtraIndex: false + condition: always() + # Ensure the Python azure-storage-blob package is installed before doing the upload. - 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 diff --git a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml index 6cf2f828fd4351..323da64d340a07 100644 --- a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml +++ b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml @@ -316,25 +316,44 @@ jobs: runJobTemplate: /eng/pipelines/coreclr/templates/run-scenarios-job.yml logicalmachine: 'perftiger' - # Uncomment to reenable package replacement - ## build maui runtime packs - #- template: /eng/pipelines/common/platform-matrix.yml - # parameters: - # jobTemplate: /eng/pipelines/common/global-build-job.yml - # buildConfig: release - # runtimeFlavor: mono - # platforms: - # - android_x86 - # - android_x64 - # - android_arm - # - android_arm64 - # - maccatalyst_x64 - # - iossimulator_x64 - # - ios_arm64 - # jobParameters: - # buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) - # nameSuffix: Maui_Packs_Mono - # isOfficialBuild: false - # extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - # extraStepsParameters: - # name: MonoRuntimePacks + # build mono runtime packs + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + runtimeFlavor: mono + platforms: + - android_arm64 + jobParameters: + buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) + nameSuffix: Mono_Packs + isOfficialBuild: false + extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + extraStepsParameters: + name: MonoRuntimePacks + + # build PerfBDN app + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + runtimeFlavor: mono + platforms: + - ios_arm64 + jobParameters: + dependsOn: + - Build_android_arm64_release_Mono_Packs + buildArgs: -s mono -c $(_BuildConfig) + nameSuffix: PerfBDNApp + isOfficialBuild: false + pool: + vmImage: 'macos-12' + extraStepsTemplate: /eng/pipelines/coreclr/templates/build-perf-bdn-app.yml + extraStepsParameters: + rootFolder: '$(Build.SourcesDirectory)/artifacts/' + includeRootFolder: true + displayName: Android BDN App Artifacts + artifactName: PerfBDNAppArm + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz diff --git a/eng/pipelines/coreclr/release-tests.yml b/eng/pipelines/coreclr/release-tests.yml index 9eb62f900ca12e..b1d42000dd76df 100644 --- a/eng/pipelines/coreclr/release-tests.yml +++ b/eng/pipelines/coreclr/release-tests.yml @@ -28,6 +28,7 @@ extends: # Adding it here will enable it also - osx_arm64 jobParameters: + testGroup: outerloop isOfficialBuild: false # diff --git a/eng/pipelines/coreclr/templates/build-jit-job.yml b/eng/pipelines/coreclr/templates/build-jit-job.yml index e3c0a835fc92c7..5566f228b2f0e8 100644 --- a/eng/pipelines/coreclr/templates/build-jit-job.yml +++ b/eng/pipelines/coreclr/templates/build-jit-job.yml @@ -99,6 +99,13 @@ jobs: displayName: Build CoreCLR JIT - ${{ if eq(parameters.uploadAs, 'azureBlob') }}: + # Add authenticated pip feed + - task: PipAuthenticate@1 + displayName: 'Pip Authenticate' + inputs: + artifactFeeds: public/dotnet-public-pypi + onlyAddExtraIndex: false + # Ensure the Python azure-storage-blob package is installed before doing the upload. - 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 diff --git a/eng/pipelines/coreclr/templates/build-perf-bdn-app.yml b/eng/pipelines/coreclr/templates/build-perf-bdn-app.yml new file mode 100644 index 00000000000000..b7195855d7c395 --- /dev/null +++ b/eng/pipelines/coreclr/templates/build-perf-bdn-app.yml @@ -0,0 +1,179 @@ +parameters: + osGroup: '' + osSubgroup: '' + archType: '' + buildConfig: '' + runtimeFlavor: '' + helixQueues: '' + targetRid: '' + nameSuffix: '' + platform: '' + shouldContinueOnError: '' + rootFolder: '' + includeRootFolder: '' + displayName: '' + artifactName: '' + archiveExtension: '' + archiveType: '' + tarCompression: '' + framework: 'net8.0' # Framework version to get versions for and build for + perfRepo: 'main' # Perf repo to pull for the PerfLabExporter + + +steps: + - task: DownloadPipelineArtifact@2 + displayName: Download runtime packages + inputs: + artifact: 'IntermediateArtifacts' + path: $(Build.SourcesDirectory)/ArtifactPacks + patterns: | + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.android-!(*.symbols).nupkg + + # # Other artifacts to include once they are being built + # # EX. IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-*.nupkg + + - task: CopyFiles@2 + displayName: Flatten packages + inputs: + sourceFolder: $(Build.SourcesDirectory)/ArtifactPacks + contents: '*/Shipping/*.nupkg' + cleanTargetFolder: false + targetFolder: $(Build.SourcesDirectory)/ArtifactPacks + flattenFolders: true + + - script: | + for file in *.nupkg + do + mv -v "$file" "${file%.nupkg}.zip" + done + displayName: Change nupkgs to zips + workingDirectory: $(Build.SourcesDirectory)/ArtifactPacks + + - task: ExtractFiles@1 + displayName: Extract android-arm64 runtime + inputs: + archiveFilePatterns: $(Build.SourcesDirectory)/ArtifactPacks/Microsoft.NETCore.App.Runtime.Mono.android-arm64.*.zip + destinationFolder: $(Build.SourcesDirectory)/ArtifactPacks/Microsoft.NETCore.App.Runtime.Mono.android-arm64 + overwriteExistingFiles: true + cleanDestinationFolder: false + + - script: | + echo '{ }' > ./global.json + curl -o NuGet.config 'https://raw.githubusercontent.com/dotnet/maui/${{parameters.framework}}/NuGet.config' + curl -o dotnet-install.sh 'https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh' + curl -Lo maui-supported-sdk-version.json 'https://aka.ms/dotnet/sdk/maui/${{parameters.framework}}.json' + version=$(sed -nr 's/\s*"version": "(.*)"/\1/p' ./maui-supported-sdk-version.json) + chmod -R a+rx . + ./dotnet-install.sh --version $version --install-dir . + ./dotnet --info + ./dotnet workload install maui --from-rollback-file https://aka.ms/dotnet/maui/${{parameters.framework}}.json --configfile NuGet.config + ./dotnet workload install android --from-rollback-file https://aka.ms/dotnet/maui/${{parameters.framework}}.json --configfile NuGet.config + displayName: Install MAUI workload + workingDirectory: $(Build.SourcesDirectory) + + - script: $(Build.SourcesDirectory)/eng/testing/performance/create-provisioning-profile.sh + displayName: Create iOS code signing and provisioning profile + + - script: | + set -x + pwd + git clone https://github.com/dotnet/maui.git --depth 1 -b ${{parameters.framework}} --single-branch + displayName: Clone Maui + workingDirectory: $(Build.SourcesDirectory) + + - pwsh: | + $instrumentationFileContent = Get-Content .\maui\src\Core\tests\Benchmarks.Droid\MainInstrumentation.cs + $perfLabExportLine = $instrumentationFileContent | Select-String -Pattern 'using BenchmarkDotNet.Toolchains.InProcess.Emit;' + $lineNumber = $perfLabExportLine.LineNumber + $instrumentationFileContent[$lineNumber-1] += "using BenchmarkDotNet.Extensions;" + + $perfLabExportLine = $instrumentationFileContent | Select-String -Pattern 'var config = ManualConfig' + $lineNumber = $perfLabExportLine.LineNumber + $instrumentationFileContent[$lineNumber-1] += ".AddExporter(new PerfLabExporter()).WithArtifactsPath(`"/storage/emulated/0/Android/data/com.microsoft.maui.benchmarks/files`")" + $instrumentationFileContent | Set-Content .\maui\src\Core\tests\Benchmarks.Droid\MainInstrumentation.cs + + $benchmarksDroidConfigFileContent = Get-Content .\maui\src\Core\tests\Benchmarks.Droid\Benchmarks.Droid.csproj + + $propertyGroupLine = $benchmarksDroidConfigFileContent | Select-String -Pattern '' + $lineNumber = $propertyGroupLine.LineNumber + $benchmarksDroidConfigFileContent[$lineNumber-1] += "`$(DefineConstants);PERFLAB_INLAB" + + $projectReferenceLine = $benchmarksDroidConfigFileContent | Select-String -Pattern '' + $lineNumber = $projectReferenceLine.LineNumber + $benchmarksDroidConfigFileContent[$lineNumber-1] += "" + + $targetLine = $benchmarksDroidConfigFileContent | Select-String -Pattern '' + $lineNumber = $targetLine.LineNumber + $benchmarksDroidConfigFileContent[$lineNumber-1] += " + + + + + + + + + `$(Build.SourcesDirectory)/ArtifactPacks + + + + + + " + + $benchmarksDroidConfigFileContent | Set-Content .\maui\src\Core\tests\Benchmarks.Droid\Benchmarks.Droid.csproj + displayName: Insert Target Replace, BDN config link, and PerfLabExporter + workingDirectory: $(Build.SourcesDirectory) + + - script: | + set -x + pwd + git clone https://github.com/dotnet/performance.git --depth 1 -b ${{parameters.perfRepo}} --single-branch + displayName: Clone performance + workingDirectory: $(Build.SourcesDirectory) + +# Remove the embed assemblies from source + - script: | + ../dotnet build ./src/Core/tests/Benchmarks.Droid/Benchmarks.Droid.csproj --configuration Release -bl:BenchmarksDroid.binlog /p:TF_Build=False + mv ./src/Core/tests/Benchmarks.Droid/bin/Release/${{parameters.framework}}-android/android-arm64/com.microsoft.maui.benchmarks-Signed.apk ./MonoBenchmarksDroid.apk + displayName: Build BDN Android App + workingDirectory: $(Build.SourcesDirectory)/maui + + - task: PublishBuildArtifacts@1 + condition: succeededOrFailed() + displayName: 'Publish Benchmarks.Droid binlog' + inputs: + pathtoPublish: $(Build.SourcesDirectory)/maui/BenchmarksDroid.binlog + artifactName: ${{ parameters.artifactName }} + + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.SourcesDirectory)/maui/MonoBenchmarksDroid.apk + includeRootFolder: true + displayName: Android BDN Apk + artifactName: AndroidBDNApk + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz + + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + osGroup: ${{ parameters.osGroup }} + osSubgroup: ${{ parameters.osSubgroup }} + archType: ${{ parameters.archType }} + buildConfig: ${{ parameters.buildConfig }} + runtimeFlavor: ${{ parameters.runtimeFlavor }} + helixQueues: ${{ parameters.helixQueues }} + targetRid: ${{ parameters.targetRid }} + nameSuffix: ${{ parameters.nameSuffix }} + platform: ${{ parameters.platform }} + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + rootFolder: ${{ parameters.rootFolder }} + includeRootFolder: ${{ parameters.includeRootFolder }} + displayName: ${{ parameters.displayName }} + artifactName: ${{ parameters.artifactName }} + archiveExtension: ${{ parameters.archiveExtension }} + archiveType: ${{ parameters.archiveType }} + tarCompression: ${{ parameters.tarCompression }} diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml index c95a231e619855..5654aafb30e5c7 100644 --- a/eng/pipelines/coreclr/templates/perf-job.yml +++ b/eng/pipelines/coreclr/templates/perf-job.yml @@ -79,6 +79,7 @@ jobs: - ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.codeGenType) }} - ${{ if eq(parameters.runtimeType, 'AndroidMono')}}: - ${{ 'build_android_arm64_release_AndroidMono' }} + - ${{ 'Build_ios_arm64_release_PerfBDNApp' }} - ${{ if eq(parameters.runtimeType, 'iOSMono')}}: - ${{ 'build_ios_arm64_release_iOSMono' }} @@ -208,6 +209,13 @@ jobs: artifactFileName: 'AndroidMonoarm64.tar.gz' artifactName: 'AndroidMonoarm64' displayName: 'Mono Android HelloWorld' + - template: /eng/pipelines/common/download-artifact-step.yml + parameters: + unpackFolder: $(Build.SourcesDirectory) + cleanUnpackFolder: false + artifactFileName: 'AndroidBDNApk.tar.gz' + artifactName: 'AndroidBDNApk' + displayName: 'Mono Android BDN Apk' # Download iOSMono tests - ${{ if eq(parameters.runtimeType, 'iOSMono') }}: diff --git a/eng/pipelines/coreclr/templates/run-superpmi-collect-job.yml b/eng/pipelines/coreclr/templates/run-superpmi-collect-job.yml index d7fad218341b55..ef55089a230467 100644 --- a/eng/pipelines/coreclr/templates/run-superpmi-collect-job.yml +++ b/eng/pipelines/coreclr/templates/run-superpmi-collect-job.yml @@ -159,6 +159,13 @@ jobs: artifactName: 'SuperPMI_Collection_$(CollectionName)_$(CollectionType)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' displayName: ${{ format('Upload artifacts SuperPMI {0}-{1} collection', parameters.collectionName, parameters.collectionType) }} + # Add authenticated pip feed + - task: PipAuthenticate@1 + displayName: 'Pip Authenticate' + inputs: + artifactFeeds: public/dotnet-public-pypi + onlyAddExtraIndex: false + # Ensure the Python azure-storage-blob package is installed before doing the upload. - 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 diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml index 096579d9ff70ef..ca2aed4c166c0d 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml @@ -135,6 +135,64 @@ jobs: eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), eq(variables['isRollingBuild'], true)) +# +# CoreCLR NativeAOT release build (checked runtime) - SizeOpt and libraries tests +# Only when CoreCLR or library is changed +# +- 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 + isSingleFile: true + nameSuffix: NativeAOT_Checked_Libs_SizeOpt + buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:OptimizationPreference=Size + timeoutInMinutes: 240 + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_Checked_SizeOpt_$(_BuildConfig) + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + +# +# CoreCLR NativeAOT release build (checked runtime) - SpeedOpt and libraries tests +# Only when CoreCLR or library is changed +# +- 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 + isSingleFile: true + nameSuffix: NativeAOT_Checked_Libs_SpeedOpt + buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:OptimizationPreference=Speed + timeoutInMinutes: 240 + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_Checked_SpeedOpt_$(_BuildConfig) + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + # Run net48 tests on win-x64 - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -174,7 +232,7 @@ jobs: jobParameters: testScope: innerloop nameSuffix: AllSubsets_Mono - buildArgs: -s mono+mono.mscordbi+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( @@ -287,6 +345,7 @@ jobs: extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml extraStepsParameters: creator: dotnet-bot + llvmAotStepContainer: linux_x64_llvmaot testRunNamePrefixSuffix: Mono_Release extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index acfb67eaf79528..ac9304e1d692ec 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -197,6 +197,6 @@ jobs: # Browser WebAssembly windows - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}: - - (Windows.Amd64.Server2022.Open)windows.amd64.server2022.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly-net8-20230327150108-4404b5c + - (Windows.Amd64.Server2022.Open)windows.amd64.server2022.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly-net8 ${{ insert }}: ${{ parameters.jobParameters }} diff --git a/eng/pipelines/mono/templates/build-job.yml b/eng/pipelines/mono/templates/build-job.yml index cdcf76143f5fdc..2c3fc2c45cf1ce 100644 --- a/eng/pipelines/mono/templates/build-job.yml +++ b/eng/pipelines/mono/templates/build-job.yml @@ -59,8 +59,6 @@ jobs: value: '' - name: llvmParameter value: '' - - name: msCorDbi - value: '+mono.mscordbi' - name: darwinFrameworks value: '' - ${{ if eq(parameters.isOfficialBuild, true) }}: @@ -70,7 +68,7 @@ jobs: # Set output RID manually: musl isn't properly detected. Make sure to also convert linux to # lowercase for RID format. (Detection normally converts, but we're preventing it.) - name: OutputRidArg - value: /p:OutputRid=linux-musl-${{ parameters.archType }} + value: /p:OutputRID=linux-musl-${{ parameters.archType }} - name: _PortableBuild value: true - ${{ if eq(parameters.osGroup, 'tvos') }}: @@ -145,10 +143,10 @@ jobs: # Build - ${{ if ne(parameters.osGroup, 'windows') }}: - - script: ./build$(scriptExt) -subset mono$(msCorDbi)+clr.hosts $(crossArg) -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) $(darwinFrameworks) + - script: ./build$(scriptExt) -subset mono+clr.hosts $(crossArg) -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) $(darwinFrameworks) displayName: Build product - ${{ if eq(parameters.osGroup, 'windows') }}: - - script: build$(scriptExt) -subset mono$(msCorDbi)+clr.hosts -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) + - script: build$(scriptExt) -subset mono+clr.hosts -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) displayName: Build product - ${{ if in(parameters.osGroup, 'osx', 'ios', 'tvos') }}: @@ -170,10 +168,10 @@ jobs: # Build packages - ${{ if ne(parameters.osGroup, 'windows') }}: - - script: ./build$(scriptExt) -subset mono$(msCorDbi)+clr.hosts $(crossArg) -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) -pack $(OutputRidArg) + - script: ./build$(scriptExt) -subset mono+clr.hosts $(crossArg) -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) -pack $(OutputRidArg) displayName: Build nupkg - ${{ if eq(parameters.osGroup, 'windows') }}: - - script: build$(scriptExt) -subset mono$(msCorDbi)+clr.hosts -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) -pack $(OutputRidArg) + - script: build$(scriptExt) -subset mono+clr.hosts -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) -pack $(OutputRidArg) displayName: Build nupkg # Publish official build diff --git a/eng/pipelines/runtime-codeql.yml b/eng/pipelines/runtime-codeql.yml index 991fa0d4002dca..62c002926b70da 100644 --- a/eng/pipelines/runtime-codeql.yml +++ b/eng/pipelines/runtime-codeql.yml @@ -58,7 +58,7 @@ extends: - linux_x64 - windows_x64 jobParameters: - buildArgs: -s mono+libs+host+packs+mono.mscordbi -c $(_BuildConfig) + buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) nameSuffix: AllSubsets_Mono isOfficialBuild: ${{ variables.isOfficialBuild }} timeoutInMinutes: 360 diff --git a/eng/pipelines/runtime-llvm.yml b/eng/pipelines/runtime-llvm.yml index ea387f5ddcb6e1..e31e623a0353c8 100644 --- a/eng/pipelines/runtime-llvm.yml +++ b/eng/pipelines/runtime-llvm.yml @@ -176,7 +176,7 @@ extends: buildConfig: release runtimeFlavor: mono platforms: - - linux_x64 + - linux_x64_llvmaot # Disabled pending outcome of https://github.com/dotnet/runtime/issues/60234 investigation #- linux_arm64 helixQueueGroup: pr @@ -202,7 +202,7 @@ extends: buildConfig: release runtimeFlavor: mono platforms: - - linux_x64 + - linux_x64_llvmaot - linux_arm64 helixQueueGroup: pr helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 9b923a7975ec3c..323f7784fed557 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -51,7 +51,7 @@ extends: - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}: - template: /eng/common/templates/job/source-index-stage1.yml parameters: - sourceIndexBuildCommand: build.cmd -subset libs.sfx+libs.oob -binarylog -os linux -ci + sourceIndexBuildCommand: build.cmd -subset libs.sfx+libs.oob -binarylog -os linux -ci /p:SkipLibrariesNativeRuntimePackages=true # # Build CoreCLR @@ -97,6 +97,31 @@ extends: - windows_x64 - windows_arm - windows_arm64 + + # + # Build NativeAOT runtime packs + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - maccatalyst_x64 + - maccatalyst_arm64 + - tvossimulator_x64 + - tvossimulator_arm64 + - tvos_arm64 + - iossimulator_x64 + - iossimulator_arm64 + - ios_arm64 + jobParameters: + buildArgs: -s clr.nativeaotlibs+clr.nativeaotruntime+libs+packs -c $(_BuildConfig) /p:BuildNativeAOTRuntimePack=true + nameSuffix: AllSubsets_NativeAOT + isOfficialBuild: ${{ variables.isOfficialBuild }} + extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + extraStepsParameters: + name: NativeAOTRuntimePacks + # # Build Mono runtime packs # diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 3d8319f4188375..4ad81e6c23d7bd 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -74,6 +74,7 @@ extends: - linux_x64 - linux_arm - linux_arm64 + - linux_riscv64 - linux_musl_arm - linux_musl_arm64 - linux_musl_x64 @@ -392,6 +393,7 @@ extends: runtimeFlavor: mono platforms: - linux_musl_x64 + - linux_riscv64 jobParameters: testGroup: innerloop nameSuffix: AllSubsets_Mono @@ -1210,7 +1212,7 @@ extends: buildConfig: Release runtimeFlavor: mono platforms: - - linux_x64_llvmaot + - linux_x64 # Disabled pending outcome of https://github.com/dotnet/runtime/issues/60234 investigation #- linux_arm64 variables: @@ -1233,6 +1235,7 @@ extends: extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml extraStepsParameters: creator: dotnet-bot + llvmAotStepContainer: linux_x64_llvmaot testRunNamePrefixSuffix: Mono_Release extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml diff --git a/eng/testing/ProvisioningVersions.props b/eng/testing/ProvisioningVersions.props index 74362b4665e659..96a82270a9d96c 100644 --- a/eng/testing/ProvisioningVersions.props +++ b/eng/testing/ProvisioningVersions.props @@ -41,12 +41,18 @@ these snapshot urls. --> - + + + true + + + 109.0.5414.119 1070088 <_ChromeBaseSnapshotUrl>https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1070096 - + 109.0.5414.120 1070088 <_ChromeBaseSnapshotUrl>https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1070094 diff --git a/eng/testing/WasmRunnerAOTTemplate.sh b/eng/testing/WasmRunnerAOTTemplate.sh index 5fca4d3fba60ab..856fb7ebbea1bc 100644 --- a/eng/testing/WasmRunnerAOTTemplate.sh +++ b/eng/testing/WasmRunnerAOTTemplate.sh @@ -34,10 +34,6 @@ if [[ -z "$XHARNESS_COMMAND" ]]; then fi if [[ "$XHARNESS_COMMAND" == "test" ]]; then - if [[ -z "$JS_ENGINE_ARGS" ]]; then - JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000" - fi - if [[ -z "$JS_ENGINE" ]]; then if [[ "$SCENARIO" == "WasmTestOnNodeJS" || "$SCENARIO" == "wasmtestonnodejs" ]]; then JS_ENGINE="--engine=NodeJS" @@ -46,6 +42,16 @@ if [[ "$XHARNESS_COMMAND" == "test" ]]; then fi fi + if [[ -z "$JS_ENGINE_ARGS" ]]; then + JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000" + if [[ "$SCENARIO" != "WasmTestOnNodeJS" && "$SCENARIO" != "wasmtestonnodejs" ]]; then + JS_ENGINE_ARGS="$JS_ENGINE_ARGS --engine-arg=--module" + fi + if [[ "$SCENARIO" == "WasmTestOnNodeJS" || "$SCENARIO" == "wasmtestonnodejs" ]]; then + JS_ENGINE_ARGS="$JS_ENGINE_ARGS --engine-arg=--experimental-wasm-eh" + fi + fi + if [[ -z "$MAIN_JS" ]]; then MAIN_JS="--js-file=test-main.js" fi diff --git a/eng/testing/WasmRunnerTemplate.cmd b/eng/testing/WasmRunnerTemplate.cmd index 1fc0e6ef4f7697..a8c9c0ac571269 100644 --- a/eng/testing/WasmRunnerTemplate.cmd +++ b/eng/testing/WasmRunnerTemplate.cmd @@ -46,6 +46,12 @@ if /I [%XHARNESS_COMMAND%] == [test] ( if [%JS_ENGINE_ARGS%] == [] ( set "JS_ENGINE_ARGS=--engine-arg^=--stack-trace-limit^=1000" + if /I NOT [%SCENARIO%] == [WasmTestOnNodeJS] ( + set "JS_ENGINE_ARGS=%JS_ENGINE_ARGS% --engine-arg^=--module" + ) + if /I [%SCENARIO%] == [WasmTestOnNodeJS] ( + set "JS_ENGINE_ARGS=%JS_ENGINE_ARGS% --engine-arg^=--experimental-wasm-eh" + ) ) ) else ( if [%BROWSER_PATH%] == [] if not [%HELIX_CORRELATION_PAYLOAD%] == [] ( diff --git a/eng/testing/WasmRunnerTemplate.sh b/eng/testing/WasmRunnerTemplate.sh index aa623e7473556a..8b4e9adb10c2ef 100644 --- a/eng/testing/WasmRunnerTemplate.sh +++ b/eng/testing/WasmRunnerTemplate.sh @@ -48,6 +48,12 @@ if [[ "$XHARNESS_COMMAND" == "test" ]]; then if [[ -z "$JS_ENGINE_ARGS" ]]; then JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000" + if [[ "$SCENARIO" != "WasmTestOnNodeJS" && "$SCENARIO" != "wasmtestonnodejs" ]]; then + JS_ENGINE_ARGS="$JS_ENGINE_ARGS --engine-arg=--module" + fi + if [[ "$SCENARIO" == "WasmTestOnNodeJS" || "$SCENARIO" == "wasmtestonnodejs" ]]; then + JS_ENGINE_ARGS="$JS_ENGINE_ARGS --engine-arg=--experimental-wasm-eh" + fi fi fi diff --git a/eng/testing/linker/SupportFiles/Directory.Build.targets b/eng/testing/linker/SupportFiles/Directory.Build.targets index cfb263f604fa26..6a43ace84f6f59 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.targets +++ b/eng/testing/linker/SupportFiles/Directory.Build.targets @@ -13,7 +13,7 @@ Condition="'$(TargetArchitecture)' == 'wasm' And '$(TargetOS)' == 'browser'" /> - true + <_IlcReferencedAsPackage>false $(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets diff --git a/eng/testing/performance/android_scenarios.proj b/eng/testing/performance/android_scenarios.proj index 5d22af65c6cc67..4cdd0fdc8e55d7 100644 --- a/eng/testing/performance/android_scenarios.proj +++ b/eng/testing/performance/android_scenarios.proj @@ -35,6 +35,18 @@ $(Python) test.py sod --scenario-name "%(Identity)" $(Python) post.py + + $(WorkItemDirectory) + cd $(ScenarioDirectory)bdnandroid;copy %HELIX_CORRELATION_PAYLOAD%\MonoBenchmarksDroid.apk .;$(Python) pre.py --apk-name MonoBenchmarksDroid.apk + $(Python) test.py sod --scenario-name "%(Identity)" + $(Python) post.py + + + $(WorkItemDirectory) + cd $(ScenarioDirectory)bdnandroid;copy %HELIX_CORRELATION_PAYLOAD%\MonoBenchmarksDroid.apk .;$(Python) pre.py --unzip --apk-name MonoBenchmarksDroid.apk + $(Python) test.py sod --scenario-name "%(Identity)" + $(Python) post.py + $(WorkItemDirectory) echo on;set XHARNESSPATH=$(XharnessPath);cd $(ScenarioDirectory)helloandroid;copy %HELIX_CORRELATION_PAYLOAD%\HelloAndroid.apk .;$(Python) pre.py --apk-name HelloAndroid.apk @@ -47,5 +59,12 @@ $(Python) test.py devicestartup --device-type android --package-path pub\HelloAndroid.apk --package-name net.dot.HelloAndroid --scenario-name "%(Identity)" --disable-animations $(Python) post.py + + $(WorkItemDirectory) + echo on;set XHARNESSPATH=$(XharnessPath);cd $(ScenarioDirectory)bdnandroid;copy %HELIX_CORRELATION_PAYLOAD%\MonoBenchmarksDroid.apk .;$(Python) pre.py --apk-name MonoBenchmarksDroid.apk + $(Python) test.py androidinstrumentation --package-path .\pub\MonoBenchmarksDroid.apk --package-name com.microsoft.maui.benchmarks --instrumentation-name com.microsoft.maui.MainInstrumentation --scenario-name "%(Identity)" + $(Python) post.py + 00:30:00 + diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index 706737d5b2b933..29e3d6199cb788 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -163,6 +163,7 @@ if ($AndroidMono) { { mkdir $WorkItemDirectory } + Copy-Item -path "$SourceDirectory\MonoBenchmarksDroid.apk" $PayloadDirectory -Verbose Copy-Item -path "$SourceDirectory\androidHelloWorld\HelloAndroid.apk" $PayloadDirectory -Verbose $SetupArguments = $SetupArguments -replace $Architecture, 'arm64' } diff --git a/eng/testing/tests.browser.targets b/eng/testing/tests.browser.targets index 5b5383253c3c67..ac4796a41af24d 100644 --- a/eng/testing/tests.browser.targets +++ b/eng/testing/tests.browser.targets @@ -287,6 +287,7 @@ <_RuntimePackNugetAvailable Include="$(LibrariesShippingPackagesDir)Microsoft.NETCore.App.Runtime.Mono.$(RuntimeIdentifier).*$(PackageVersionForWorkloadManifests).nupkg" /> + <_RuntimePackNugetAvailable Include="$(LibrariesShippingPackagesDir)Microsoft.NETCore.App.Runtime.Mono.*.$(RuntimeIdentifier).*$(PackageVersionForWorkloadManifests).nupkg" /> <_RuntimePackNugetAvailable Remove="@(_RuntimePackNugetAvailable)" Condition="$([System.String]::new('%(_RuntimePackNugetAvailable.FileName)').EndsWith('.symbols'))" /> diff --git a/eng/testing/tests.props b/eng/testing/tests.props index ab58a76a58c3b5..2c555d1abaffe0 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -17,7 +17,7 @@ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(Configuration)', '$(NetCoreAppCurrent)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmTestRunner', '$(Configuration)', '$(NetCoreAppCurrent)')) - $(OutputRid) + $(OutputRID) true diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets index 6b869bd02c60a3..5fb0e1bd643ea2 100644 --- a/eng/testing/tests.singlefile.targets +++ b/eng/testing/tests.singlefile.targets @@ -4,7 +4,7 @@ $([MSBuild]::NormalizeDirectory('$(OutDir)', 'publish')) $([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)')) - $(OutputRid) + $(OutputRID) $(AssemblyName).exe chmod +rwx $(AssemblyName) && ./$(AssemblyName) diff --git a/global.json b/global.json index 4d666df3163ddd..823b0d22d03f5f 100644 --- a/global.json +++ b/global.json @@ -8,11 +8,11 @@ "dotnet": "8.0.100-preview.3.23178.7" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23217.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23217.1", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23217.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23253.3", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23253.3", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23253.3", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", - "Microsoft.NET.Sdk.IL": "8.0.0-preview.4.23177.1" + "Microsoft.NET.Sdk.IL": "8.0.0-preview.5.23251.1" } } diff --git a/src/coreclr/.nuget/Directory.Build.props b/src/coreclr/.nuget/Directory.Build.props index cb446cf9c41e72..150e9ccfb0b82b 100644 --- a/src/coreclr/.nuget/Directory.Build.props +++ b/src/coreclr/.nuget/Directory.Build.props @@ -120,8 +120,8 @@ - - + amd64 $(TargetArchitecture) diff --git a/src/coreclr/.nuget/builds.targets b/src/coreclr/.nuget/builds.targets index 4dd4d825baeb96..e9acb038c46073 100644 --- a/src/coreclr/.nuget/builds.targets +++ b/src/coreclr/.nuget/builds.targets @@ -7,11 +7,11 @@ - + - <_projectsToBuild Include="@(Project)" Condition="'%(Project.PackageTargetRuntime)' == '$(OutputRid)'" /> + <_projectsToBuild Include="@(Project)" Condition="'%(Project.PackageTargetRuntime)' == '$(OutputRID)'" /> diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt index d794641ebcd787..1495cb736f8cb6 100644 --- a/src/coreclr/CMakeLists.txt +++ b/src/coreclr/CMakeLists.txt @@ -109,7 +109,7 @@ if(CLR_CMAKE_HOST_UNIX) endif() endif() - if(CLR_CMAKE_TARGET_LINUX AND CLR_CMAKE_TARGET_ARCH_I386) + if(CLR_CMAKE_TARGET_LINUX AND (CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_RISCV64)) add_linker_flag(-Wl,-z,notext) endif() @@ -126,7 +126,9 @@ endif() #---------------------------------------------------- # Build the test watchdog alongside the CLR #---------------------------------------------------- -add_subdirectory("${CLR_SRC_NATIVE_DIR}/watchdog" test-watchdog) +if(NOT CLR_CMAKE_HOST_MACCATALYST AND NOT CLR_CMAKE_HOST_IOS AND NOT CLR_CMAKE_HOST_TVOS) + add_subdirectory("${CLR_SRC_NATIVE_DIR}/watchdog" test-watchdog) +endif() # Add this subdir. We install the headers for the jit. add_subdirectory(pal/prebuilt/inc) diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index b5cd4894cd5be4..3b82e34fce48fa 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -163,7 +163,6 @@ - @@ -172,6 +171,7 @@ + diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs index b740d461df3f8e..842ebaf3c3c97d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs @@ -21,10 +21,14 @@ namespace System.Reflection.Emit { public class CustomAttributeBuilder { - internal readonly ConstructorInfo m_con; + private readonly ConstructorInfo m_con; private readonly object?[] m_constructorArgs; private readonly byte[] m_blob; + internal ConstructorInfo Ctor => m_con; + + internal byte[] Data => m_blob; + // public constructor to form the custom attribute with constructor and constructor // parameters. public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs) : diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.cs index b2d82487f02321..dd6c84158a01fe 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.cs @@ -288,7 +288,7 @@ public override Assembly GetSatelliteAssembly(CultureInfo culture, Version? vers /// /// Use this function if client decides to form the custom attribute blob themselves. /// - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { lock (SyncRoot) { @@ -299,16 +299,5 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar binaryAttribute); } } - - /// - /// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder. - /// - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - lock (SyncRoot) - { - customBuilder.CreateCustomAttribute(_manifestModuleBuilder, AssemblyDefToken); - } - } } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.cs index 86b20be8e7ff09..bb1c16bf4fe3c4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.cs @@ -157,16 +157,11 @@ internal override Type GetReturnType() return m_methodBuilder.ReturnType; } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { m_methodBuilder.SetCustomAttribute(con, binaryAttribute); } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - m_methodBuilder.SetCustomAttribute(customBuilder); - } - protected override void SetImplementationFlagsCore(MethodImplAttributes attributes) { m_methodBuilder.SetImplementationFlags(attributes); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.cs index 3e81b8ed9fc874..2e14270c0d0265 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.cs @@ -274,18 +274,11 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit) } // Use this function if client decides to form the custom attribute blob themselves - - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { m_typeBuilder.SetCustomAttribute(con, binaryAttribute); } - // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - m_typeBuilder.SetCustomAttribute(customBuilder); - } - // Return the class that declared this Field. public override Type? DeclaringType => m_typeBuilder.DeclaringType; @@ -293,7 +286,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil public override Type? ReflectedType => m_typeBuilder.ReflectedType; - // Returns true if one or more instance of attributeType is defined on this member. public override bool IsDefined(Type attributeType, bool inherit) { @@ -329,7 +321,6 @@ public override Type MakeArrayType(int rank) return SymbolType.FormCompoundType(s, this, 0)!; } - // Constructs a EnumBuilder. // EnumBuilder can only be a top-level (not nested) enum type. [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2064:UnrecognizedReflectionPattern", diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.cs index 41befaa64ce550..cf3da5e026c41a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.cs @@ -80,7 +80,7 @@ protected override void AddOtherMethodCore(MethodBuilder mdBuilder) // Use this function if client decides to form the custom attribute blob themselves - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { m_type.ThrowIfCreated(); @@ -91,13 +91,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar binaryAttribute); } - // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - m_type.ThrowIfCreated(); - customBuilder.CreateCustomAttribute(m_module, m_evToken); - } - private readonly string m_name; // The name of the event private readonly int m_evToken; // The token of this event private readonly RuntimeModuleBuilder m_module; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.cs index da3341e744410a..e607b1523d7653 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.cs @@ -150,7 +150,7 @@ protected override void SetConstantCore(object? defaultValue) RuntimeTypeBuilder.SetConstantValue(m_typeBuilder.GetModuleBuilder(), m_fieldTok, m_fieldType, defaultValue); } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { RuntimeModuleBuilder moduleBuilder = (RuntimeModuleBuilder)m_typeBuilder.Module; @@ -160,13 +160,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar m_fieldTok, moduleBuilder.GetMethodMetadataToken(con), binaryAttribute); } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - m_typeBuilder.ThrowIfCreated(); - - customBuilder.CreateCustomAttribute((RuntimeModuleBuilder)m_typeBuilder.Module, m_fieldTok); - } - #endregion } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs index 6301e2ab4c5098..4245e409b28863 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs @@ -215,16 +215,11 @@ public override Type MakeArrayType(int rank) #endregion #region Protected Members Overrides - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { m_type.SetGenParamCustomAttribute(con, binaryAttribute); } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - m_type.SetGenParamCustomAttribute(customBuilder); - } - protected override void SetBaseTypeConstraintCore([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? baseTypeConstraint) { m_type.SetParent(baseTypeConstraint); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs index 6b2cdad3cc2582..bac45a0c5484f4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs @@ -646,7 +646,7 @@ protected override ParameterBuilder DefineParameterCore(int position, ParameterA throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_ParamSequence); attributes &= ~ParameterAttributes.ReservedMask; - return new ParameterBuilder(this, position, attributes, strParamName); + return new RuntimeParameterBuilder(this, position, attributes, strParamName); } protected override void SetImplementationFlagsCore(MethodImplAttributes attributes) @@ -695,7 +695,7 @@ internal Module GetModule() return GetModuleBuilder(); } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { ThrowIfGeneric(); RuntimeTypeBuilder.DefineCustomAttribute(m_module, MetadataToken, @@ -706,15 +706,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar ParseCA(con); } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - ThrowIfGeneric(); - customBuilder.CreateCustomAttribute(m_module, MetadataToken); - - if (IsKnownCA(customBuilder.m_con)) - ParseCA(customBuilder.m_con); - } - // this method should return true for any and every ca that requires more work // than just setting the ca private static bool IsKnownCA(ConstructorInfo con) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs index 637f7cd6c7e95f..496c24bb105ae9 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs @@ -1289,7 +1289,7 @@ internal int GetSignatureToken(byte[] sigBytes, int sigLength) #region Other - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { RuntimeTypeBuilder.DefineCustomAttribute( this, @@ -1298,11 +1298,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar binaryAttribute); } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - customBuilder.CreateCustomAttribute(this, 1); // This is hard coding the module token to 1 - } - #endregion #endregion diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeParameterBuilder.cs similarity index 61% rename from src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs rename to src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeParameterBuilder.cs index 9700939f2ec373..71980345a00776 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeParameterBuilder.cs @@ -5,10 +5,10 @@ namespace System.Reflection.Emit { - public class ParameterBuilder + internal sealed class RuntimeParameterBuilder : ParameterBuilder { // Set the default value of the parameter - public virtual void SetConstant(object? defaultValue) + public override void SetConstant(object? defaultValue) { RuntimeTypeBuilder.SetConstantValue( _methodBuilder.GetModuleBuilder(), @@ -17,12 +17,8 @@ public virtual void SetConstant(object? defaultValue) defaultValue); } - // Use this function if client decides to form the custom attribute blob themselves - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - ArgumentNullException.ThrowIfNull(con); - ArgumentNullException.ThrowIfNull(binaryAttribute); - RuntimeTypeBuilder.DefineCustomAttribute( _methodBuilder.GetModuleBuilder(), _token, @@ -30,15 +26,7 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) binaryAttribute); } - // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - ArgumentNullException.ThrowIfNull(customBuilder); - - customBuilder.CreateCustomAttribute((RuntimeModuleBuilder)(_methodBuilder.GetModule()), _token); - } - - internal ParameterBuilder( + internal RuntimeParameterBuilder( RuntimeMethodBuilder methodBuilder, int sequence, ParameterAttributes attributes, @@ -62,17 +50,11 @@ internal int GetToken() return _token; } - public virtual string? Name => _name; - - public virtual int Position => _position; - - public virtual int Attributes => (int)_attributes; - - public bool IsIn => (_attributes & ParameterAttributes.In) != 0; + public override string? Name => _name; - public bool IsOut => (_attributes & ParameterAttributes.Out) != 0; + public override int Position => _position; - public bool IsOptional => (_attributes & ParameterAttributes.Optional) != 0; + public override int Attributes => (int)_attributes; private readonly string? _name; private readonly int _position; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.cs index ee71d32ceb710f..eccafa7da3f2f6 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.cs @@ -97,8 +97,7 @@ protected override void AddOtherMethodCore(MethodBuilder mdBuilder) } // Use this function if client decides to form the custom attribute blob themselves - - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { m_containingType.ThrowIfCreated(); RuntimeTypeBuilder.DefineCustomAttribute( @@ -108,13 +107,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar binaryAttribute); } - // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) - { - m_containingType.ThrowIfCreated(); - customBuilder.CreateCustomAttribute(m_moduleBuilder, m_tkProperty); - } - // Not supported functions in dynamic module. public override object GetValue(object? obj, object?[]? index) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs index 02108de51c1c52..d550f656c32455 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs @@ -111,13 +111,12 @@ private sealed class CustAttr private readonly byte[]? m_binaryAttribute; private readonly CustomAttributeBuilder? m_customBuilder; - public CustAttr(ConstructorInfo con, byte[] binaryAttribute) + public CustAttr(ConstructorInfo con, ReadOnlySpan binaryAttribute) { ArgumentNullException.ThrowIfNull(con); - ArgumentNullException.ThrowIfNull(binaryAttribute); m_con = con; - m_binaryAttribute = binaryAttribute; + m_binaryAttribute = binaryAttribute.ToArray(); } public CustAttr(CustomAttributeBuilder customBuilder) @@ -173,21 +172,13 @@ private static partial void SetMethodIL(QCallModule module, int tk, [MarshalAs(U [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeBuilder_DefineCustomAttribute")] private static partial void DefineCustomAttribute(QCallModule module, int tkAssociate, int tkConstructor, - byte[]? attr, int attrLength); + ReadOnlySpan attr, int attrLength); internal static void DefineCustomAttribute(RuntimeModuleBuilder module, int tkAssociate, int tkConstructor, - byte[]? attr) + ReadOnlySpan attr) { - byte[]? localAttr = null; - - if (attr != null) - { - localAttr = new byte[attr.Length]; - Buffer.BlockCopy(attr, 0, localAttr, 0, attr.Length); - } - DefineCustomAttribute(new QCallModule(ref module), tkAssociate, tkConstructor, - localAttr, (localAttr != null) ? localAttr.Length : 0); + attr, attr.Length); } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeBuilder_DefineProperty", StringMarshalling = StringMarshalling.Utf16)] @@ -670,7 +661,7 @@ internal void SetGenParamAttributes(GenericParameterAttributes genericParameterA m_genParamAttributes = genericParameterAttributes; } - internal void SetGenParamCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + internal void SetGenParamCustomAttribute(ConstructorInfo con, ReadOnlySpan binaryAttribute) { CustAttr ca = new CustAttr(con, binaryAttribute); @@ -1858,14 +1849,14 @@ internal int TypeToken } } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) + internal void SetCustomAttribute(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - DefineCustomAttribute(m_module, m_tdType, m_module.GetMethodMetadataToken(con), binaryAttribute); + SetCustomAttributeCore(con, binaryAttribute); } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - customBuilder.CreateCustomAttribute(m_module, m_tdType); + DefineCustomAttribute(m_module, m_tdType, m_module.GetMethodMetadataToken(con), binaryAttribute); } #endregion diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs index 26ef9ed252df4e..ff1c5b855032c4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs @@ -54,7 +54,7 @@ public static void ApplyUpdate(Assembly assembly, ReadOnlySpan metadataDel /// /// Returns the metadata update capabilities. /// - internal static string GetCapabilities() => "Baseline AddMethodToExistingType AddStaticFieldToExistingType AddInstanceFieldToExistingType NewTypeDefinition ChangeCustomAttributes UpdateParameters"; + internal static string GetCapabilities() => "Baseline AddMethodToExistingType AddStaticFieldToExistingType AddInstanceFieldToExistingType NewTypeDefinition ChangeCustomAttributes UpdateParameters GenericUpdateMethod GenericAddMethodToExistingType GenericAddFieldToExistingType"; /// /// Returns true if the apply assembly update is enabled and available. diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs index 8468e8f9529e80..671206f80e821c 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs @@ -22,7 +22,7 @@ public MethodInvoker(MethodBase method, Signature signature) } else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke) { - // Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing. + // Always use emit invoke (if IsDynamicCodeSupported == true); useful for testing. _invoked = true; } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs index 8bb43158fdc838..677cfb17183254 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs @@ -11,7 +11,7 @@ namespace System.Threading /// /// A LIFO semaphore implemented using the PAL's semaphore with uninterruptible waits. /// - internal sealed partial class LowLevelLifoSemaphore : IDisposable + internal sealed partial class LowLevelLifoSemaphore : LowLevelLifoSemaphoreBase, IDisposable { private Semaphore? _semaphore; @@ -34,7 +34,7 @@ public bool WaitCore(int timeoutMs) [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_CorWaitOnePrioritizedNative")] private static partial int WaitNative(SafeWaitHandle handle, int timeoutMs); - public void ReleaseCore(int count) + protected override void ReleaseCore(int count) { Debug.Assert(_semaphore != null); Debug.Assert(count > 0); diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index 2b99c9b9eed5f0..49d2627630a426 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -81,7 +81,6 @@ __Compiler=clang __CommonMSBuildArgs= __ConfigureOnly=0 __CrossBuild=0 -__DistroRid="" __PgoInstrument=0 __PgoOptDataPath="" __PgoOptimize=0 diff --git a/src/coreclr/debug/createdump/createdump.h b/src/coreclr/debug/createdump/createdump.h index a89fdc3793be63..0bc6ea73bcfa68 100644 --- a/src/coreclr/debug/createdump/createdump.h +++ b/src/coreclr/debug/createdump/createdump.h @@ -101,7 +101,7 @@ typedef struct int Pid; int CrashThread; int Signal; -#if defined(HOST_UNIX) && !defined(HOST_OSX) +#if defined(HOST_UNIX) int SignalCode; int SignalErrno; void* SignalAddress; diff --git a/src/coreclr/debug/createdump/main.cpp b/src/coreclr/debug/createdump/main.cpp index b54cab825025e9..75a616dc2e47b4 100644 --- a/src/coreclr/debug/createdump/main.cpp +++ b/src/coreclr/debug/createdump/main.cpp @@ -70,7 +70,7 @@ int __cdecl main(const int argc, const char* argv[]) options.Signal = 0; options.CrashThread = 0; options.Pid = 0; -#if defined(HOST_UNIX) && !defined(HOST_OSX) +#if defined(HOST_UNIX) options.SignalCode = 0; options.SignalErrno = 0; options.SignalAddress = nullptr; @@ -161,7 +161,6 @@ int __cdecl main(const int argc, const char* argv[]) { g_checkForSingleFile = true; } -#ifndef HOST_OSX else if (strcmp(*argv, "--code") == 0) { options.SignalCode = atoi(*++argv); @@ -174,7 +173,6 @@ int __cdecl main(const int argc, const char* argv[]) { options.SignalAddress = (void*)atoll(*++argv); } -#endif #endif else if ((strcmp(*argv, "-d") == 0) || (strcmp(*argv, "--diag") == 0)) { diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 2d546ece1ccec3..5be32be906bf1a 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -1728,8 +1728,7 @@ void DacDbiInterfaceImpl::CollectFields(TypeHandle thExact, // FieldDesc::GetExactDeclaringType to get at the correct field. This requires the exact // TypeHandle. EncApproxFieldDescIterator fdIterator(thApprox.GetMethodTable(), - ApproxFieldDescIterator::ALL_FIELDS, - FALSE); // don't fixup EnC (we can't, we're stopped) + ApproxFieldDescIterator::ALL_FIELDS); // don't fixup EnC (we can't, we're stopped) PTR_FieldDesc pCurrentFD; unsigned int index = 0; @@ -3873,8 +3872,7 @@ void DacDbiInterfaceImpl::GetCachedWinRTTypes( PTR_FieldDesc DacDbiInterfaceImpl::FindField(TypeHandle thApprox, mdFieldDef fldToken) { EncApproxFieldDescIterator fdIterator(thApprox.GetMethodTable(), - ApproxFieldDescIterator::ALL_FIELDS, - FALSE); // don't fixup EnC (we can't, we're stopped) + ApproxFieldDescIterator::ALL_FIELDS); // don't fixup EnC (we can't, we're stopped) PTR_FieldDesc pCurrentFD; diff --git a/src/coreclr/debug/ee/controller.cpp b/src/coreclr/debug/ee/controller.cpp index 12e486a773bb5e..266b860ebcfdcf 100644 --- a/src/coreclr/debug/ee/controller.cpp +++ b/src/coreclr/debug/ee/controller.cpp @@ -94,7 +94,7 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu return m_pSharedPatchBypassBuffer; } -#endif // FEATURE_EMULATE_SINGLESTEP +#endif // !FEATURE_EMULATE_SINGLESTEP // @todo - remove all this splicing trash // This Sort/Splice stuff just reorders the patches within a particular chain such @@ -105,7 +105,7 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu #if 1 void DebuggerPatchTable::SortPatchIntoPatchList(DebuggerControllerPatch **ppPatch) { - LOG((LF_CORDB, LL_EVERYTHING, "DPT::SPIPL called.\n")); + LOG((LF_CORDB, LL_EVERYTHING, "DPT::SPIPL ppPatch: %p, pPatch: %p \n", ppPatch, (*ppPatch))); #ifdef _DEBUG DebuggerControllerPatch *patchFirst = (DebuggerControllerPatch *) Find(Hash((*ppPatch)), Key((*ppPatch))); @@ -113,12 +113,11 @@ void DebuggerPatchTable::SortPatchIntoPatchList(DebuggerControllerPatch **ppPatc _ASSERTE((*ppPatch)->controller->GetDCType() != DEBUGGER_CONTROLLER_STATIC); #endif //_DEBUG DebuggerControllerPatch *patchNext = GetNextPatch((*ppPatch)); -LOG((LF_CORDB, LL_EVERYTHING, "DPT::SPIPL GetNextPatch passed\n")); + //List contains one, (sorted) element if (patchNext == NULL) { - LOG((LF_CORDB, LL_INFO10000, - "DPT::SPIPL: Patch 0x%x is a sorted singleton\n", (*ppPatch))); + LOG((LF_CORDB, LL_INFO10000, "DPT::SPIPL: %p single element\n", (*ppPatch))); return; } @@ -144,12 +143,12 @@ LOG((LF_CORDB, LL_EVERYTHING, "DPT::SPIPL GetNextPatch passed\n")); if (patchNext == GetNextPatch((*ppPatch))) { LOG((LF_CORDB, LL_INFO10000, - "DPT::SPIPL: Patch 0x%x is already sorted\n", (*ppPatch))); + "DPT::SPIPL: Patch %p is already sorted\n", (*ppPatch))); return; //already sorted } LOG((LF_CORDB, LL_INFO10000, - "DPT::SPIPL: Patch 0x%x will be moved \n", (*ppPatch))); + "DPT::SPIPL: Patch %p will be moved \n", (*ppPatch))); //remove it from the list SpliceOutOfList((*ppPatch)); @@ -162,7 +161,7 @@ LOG((LF_CORDB, LL_EVERYTHING, "DPT::SPIPL GetNextPatch passed\n")); SpliceInBackOf((*ppPatch), patchCur); LOG((LF_CORDB, LL_INFO10000, - "DPT::SPIPL: Patch 0x%x is now sorted\n", (*ppPatch))); + "DPT::SPIPL: Patch %p is now sorted\n", (*ppPatch))); } // This can leave the list empty, so don't do this unless you put @@ -470,7 +469,7 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForMethodDef(DebuggerContro DebuggerPatchKind kind, FramePointer fp, AppDomain *pAppDomain, - SIZE_T masterEnCVersion, + SIZE_T primaryEnCVersion, DebuggerJitInfo *dji) { CONTRACTL @@ -481,12 +480,8 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForMethodDef(DebuggerContro } CONTRACTL_END; - - - LOG( (LF_CORDB,LL_INFO10000,"DCP:AddPatchForMethodDef unbound " - "relative in methodDef 0x%x with dji 0x%x " - "controller:0x%x AD:0x%x\n", md, - dji, controller, pAppDomain)); + LOG( (LF_CORDB,LL_INFO10000,"DPT:APFMD 0x%x with dji %p, %s offset 0x%zx controller:%p AD:%p\n", + md, dji, (offsetIsIL ? "IL" : "native"), offset, controller, pAppDomain)); DebuggerFunctionKey key; @@ -494,15 +489,13 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForMethodDef(DebuggerContro key.md = md; // Get a new uninitialized patch object - DebuggerControllerPatch *patch = - (DebuggerControllerPatch *) Add(HashKey(&key)); + DebuggerControllerPatch *patch = (DebuggerControllerPatch *) Add(HashKey(&key)); if (patch == NULL) - { ThrowOutOfMemory(); - } + #ifndef FEATURE_EMULATE_SINGLESTEP patch->Initialize(); -#endif +#endif // !FEATURE_EMULATE_SINGLESTEP //initialize the patch data structure. InitializePRD(&(patch->opcode)); @@ -518,12 +511,12 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForMethodDef(DebuggerContro patch->refCount = 1; // AddRef() patch->fSaveOpcode = false; patch->pAppDomain = pAppDomain; - patch->pid = m_pid++; + patch->patchId = m_patchId++; - if (kind == PATCH_KIND_IL_MASTER) + if (kind == PATCH_KIND_IL_PRIMARY) { _ASSERTE(dji == NULL); - patch->encVersion = masterEnCVersion; + patch->encVersion = primaryEnCVersion; } else { @@ -531,32 +524,38 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForMethodDef(DebuggerContro } patch->kind = kind; - if (dji) - LOG((LF_CORDB,LL_INFO10000,"AddPatchForMethodDef w/ version 0x%04x, " - "pid:0x%x\n", dji->m_encVersion, patch->pid)); - else if (kind == PATCH_KIND_IL_MASTER) - LOG((LF_CORDB,LL_INFO10000,"AddPatchForMethodDef w/ version 0x%04x, " - "pid:0x%x\n", masterEnCVersion,patch->pid)); + if (dji != NULL) + { + LOG((LF_CORDB,LL_INFO10000,"DPT:APFMD w/ encVersion 0x%zx, patchId:0x%zx\n", + dji->m_encVersion, patch->patchId)); + } + else if (kind == PATCH_KIND_IL_PRIMARY) + { + LOG((LF_CORDB,LL_INFO10000,"DPT:APFMD w/ encVersion 0x%zx, patchId:0x%zx (primary)\n", + primaryEnCVersion, patch->patchId)); + } else - LOG((LF_CORDB,LL_INFO10000,"AddPatchForMethodDef w/ no dji or dmi, pid:0x%x\n",patch->pid)); - + { + LOG((LF_CORDB,LL_INFO10000,"DPT:APFMD w/ no dji or dmi, patchId:0x%zx\n", + patch->patchId)); + } // This patch is not yet bound or activated _ASSERTE( !patch->IsBound() ); _ASSERTE( !patch->IsActivated() ); - // The only kind of patch with IL offset is the IL master patch. - _ASSERTE(patch->IsILMasterPatch() || patch->offsetIsIL == FALSE); + // The only kind of patch with IL offset is the IL primary patch. + _ASSERTE(patch->IsILPrimaryPatch() || patch->offsetIsIL == FALSE); - // The only kind of patch that allows a MethodDescFilter is the IL master patch - _ASSERTE(patch->IsILMasterPatch() || patch->pMethodDescFilter == NULL); + // The only kind of patch that allows a MethodDescFilter is the IL primary patch + _ASSERTE(patch->IsILPrimaryPatch() || patch->pMethodDescFilter == NULL); // Zero is the only native offset that we allow to bind across different jitted // code bodies. There isn't any sensible meaning to binding at some other native offset. // Even if all the code bodies had an instruction that started at that offset there is // no guarantee those instructions represent a semantically equivalent point in the // method's execution. - _ASSERTE(!(patch->IsILMasterPatch() && !patch->offsetIsIL && patch->offset != 0)); + _ASSERTE(!(patch->IsILPrimaryPatch() && !patch->offsetIsIL && patch->offset != 0)); return patch; } @@ -572,7 +571,7 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForAddress(DebuggerControll FramePointer fp, AppDomain *pAppDomain, DebuggerJitInfo *dji, - SIZE_T pid, + SIZE_T patchId, TraceType traceType) { @@ -602,7 +601,7 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForAddress(DebuggerControll } #ifndef FEATURE_EMULATE_SINGLESTEP patch->Initialize(); -#endif +#endif // !FEATURE_EMULATE_SINGLESTEP // initialize the patch data structure InitializePRD(&(patch->opcode)); @@ -627,20 +626,22 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForAddress(DebuggerControll patch->refCount = 1; // AddRef() patch->fSaveOpcode = false; patch->pAppDomain = pAppDomain; - if (pid == DCP_PID_INVALID) - patch->pid = m_pid++; + if (patchId == DCP_PATCHID_INVALID) + patch->patchId = m_patchId++; else - patch->pid = pid; + patch->patchId = patchId; patch->dji = dji; patch->kind = kind; if (dji == NULL) - LOG((LF_CORDB,LL_INFO10000,"AddPatchForAddress w/ version with no dji, pid:0x%x\n", patch->pid)); + { + LOG((LF_CORDB,LL_INFO10000,"AddPatchForAddress w/ version with no dji, patchId:0x%zx\n", patch->patchId)); + } else { - LOG((LF_CORDB,LL_INFO10000,"AddPatchForAddress w/ version 0x%04x, " - "pid:0x%x\n", dji->m_methodInfo->GetCurrentEnCVersion(), patch->pid)); + LOG((LF_CORDB,LL_INFO10000,"AddPatchForAddress w/ version 0x%zx, " + "patchId:0x%zx\n", dji->m_methodInfo->GetCurrentEnCVersion(), patch->patchId)); _ASSERTE( fd==NULL || fd == dji->m_nativeCodeVersion.GetMethodDesc() ); } @@ -651,8 +652,8 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForAddress(DebuggerControll _ASSERTE( patch->IsBound() ); _ASSERTE( !patch->IsActivated() ); - // The only kind of patch with IL offset is the IL master patch. - _ASSERTE(patch->IsILMasterPatch() || patch->offsetIsIL == FALSE); + // The only kind of patch with IL offset is the IL primary patch. + _ASSERTE(patch->IsILPrimaryPatch() || patch->offsetIsIL == FALSE); return patch; } @@ -661,7 +662,7 @@ void DebuggerPatchTable::BindPatch(DebuggerControllerPatch *patch, CORDB_ADDRESS { _ASSERTE(patch != NULL); _ASSERTE(address != NULL); - _ASSERTE( !patch->IsILMasterPatch() ); + _ASSERTE( !patch->IsILPrimaryPatch() ); _ASSERTE(!patch->IsBound() ); //Since the actual patch doesn't move, we don't have to worry about @@ -684,7 +685,7 @@ void DebuggerPatchTable::BindPatch(DebuggerControllerPatch *patch, CORDB_ADDRESS void DebuggerPatchTable::UnbindPatch(DebuggerControllerPatch *patch) { _ASSERTE(patch != NULL); - _ASSERTE(patch->kind != PATCH_KIND_IL_MASTER); + _ASSERTE(patch->kind != PATCH_KIND_IL_PRIMARY); _ASSERTE(patch->IsBound() ); _ASSERTE(!patch->IsActivated() ); @@ -721,7 +722,7 @@ void DebuggerPatchTable::RemovePatch(DebuggerControllerPatch *patch) _ASSERTE( !patch->IsActivated() ); #ifndef FEATURE_EMULATE_SINGLESTEP patch->DoCleanup(); -#endif +#endif // !FEATURE_EMULATE_SINGLESTEP // // Because of the implementation of CHashTable, we can safely @@ -730,7 +731,6 @@ void DebuggerPatchTable::RemovePatch(DebuggerControllerPatch *patch) // implementation without considering this fact. // Delete(Hash(patch), (HASHENTRY *) patch); - } DebuggerControllerPatch *DebuggerPatchTable::GetNextPatch(DebuggerControllerPatch *prev) @@ -767,34 +767,25 @@ DebuggerControllerPatch *DebuggerPatchTable::GetNextPatch(DebuggerControllerPatc return NULL; } -#ifdef _DEBUG_PATCH_TABLE - // DEBUG An internal debugging routine, it iterates - // through the hashtable, stopping at every - // single entry, no matter what it's state. For this to - // compile, you're going to have to add friend status - // of this class to CHashTableAndData in - // to $\Com99\Src\inc\UtilCode.h +#ifdef _DEBUG void DebuggerPatchTable::CheckPatchTable() { if (NULL != m_pcEntries) { + LOG((LF_CORDB,LL_INFO1000, "DPT:CPT: %u\n", m_iEntries)); DebuggerControllerPatch *dcp; - int i = 0; - while (i++ opcode != 0 ) { - LOG((LF_CORDB,LL_INFO1000, "dcp->addr:0x%8x " - "mdMD:0x%8x, offset:0x%x, native:%d\n", - dcp->address, dcp->key.md, dcp->offset, - dcp->IsNativePatch())); + dcp->LogInstance(); } } } } - -#endif // _DEBUG_PATCH_TABLE +#endif // _DEBUG // Count how many patches are in the table. // Use for asserts @@ -851,7 +842,7 @@ void DebuggerController::EnsureUniqueThreadStarter(DebuggerThreadStarter * pNew) void DebuggerController::CancelOutstandingThreadStarter(Thread * pThread) { _ASSERTE(pThread != NULL); - LOG((LF_CORDB, LL_EVERYTHING, "DC:CancelOutstandingThreadStarter - checking on thread =0x%p\n", pThread)); + LOG((LF_CORDB, LL_EVERYTHING, "DC:CancelOutstandingThreadStarter - checking on thread=%p\n", pThread)); ControllerLockHolder lockController; DebuggerController * p = g_controllers; @@ -861,7 +852,7 @@ void DebuggerController::CancelOutstandingThreadStarter(Thread * pThread) { if (p->GetThread() == pThread) { - LOG((LF_CORDB, LL_EVERYTHING, "DC:CancelOutstandingThreadStarter, pThread=0x%p, Found=0x%p\n", p)); + LOG((LF_CORDB, LL_EVERYTHING, "DC:CancelOutstandingThreadStarter Found=%p\n", p)); // There's only 1 DTS per thread, so once we find it, we can quit. p->Delete(); @@ -962,7 +953,7 @@ DebuggerController::DebuggerController(Thread * pThread, AppDomain * pAppDomain) } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO10000, "DC: 0x%x m_eventQueuedCount to 0 - DC::DC\n", this)); + LOG((LF_CORDB, LL_INFO10000, "DC::DC %p m_eventQueuedCount=%d\n", this, m_eventQueuedCount)); ControllerLockHolder lockController; { m_next = g_controllers; @@ -1053,15 +1044,13 @@ void DebuggerController::Delete() if (m_eventQueuedCount == 0) { - LOG((LF_CORDB|LF_ENC, LL_INFO100000, "DC::Delete: actual delete of this:0x%x!\n", this)); + LOG((LF_CORDB|LF_ENC, LL_INFO100000, "DC::Delete: actual delete of this: %p\n", this)); TRACE_FREE(this); DeleteInteropSafe(this); } else { - LOG((LF_CORDB|LF_ENC, LL_INFO100000, "DC::Delete: marked for " - "future delete of this:0x%x!\n", this)); - LOG((LF_CORDB|LF_ENC, LL_INFO10000, "DC:0x%x m_eventQueuedCount at 0x%x\n", + LOG((LF_CORDB|LF_ENC, LL_INFO100000, "DC::Delete: marked for future delete of this: %p, m_eventQueuedCount=%d\n", this, m_eventQueuedCount)); m_deleted = true; } @@ -1073,18 +1062,19 @@ void DebuggerController::DebuggerDetachClean() } //static -void DebuggerController::AddRef(DebuggerControllerPatch *patch) +void DebuggerController::AddRefPatch(DebuggerControllerPatch *patch) { + LOG((LF_CORDB, LL_INFO10000, "DC::ARP: patchId:0x%zx\n", patch->patchId)); patch->refCount++; } //static -void DebuggerController::Release(DebuggerControllerPatch *patch) +void DebuggerController::ReleasePatch(DebuggerControllerPatch *patch) { patch->refCount--; if (patch->refCount == 0) { - LOG((LF_CORDB, LL_INFO10000, "DCP::R: patch deleted, deactivating\n")); + LOG((LF_CORDB, LL_INFO10000, "DC::RP: patchId:0x%zx deleted, deactivating\n", patch->patchId)); DeactivatePatch(patch); GetPatchTable()->RemovePatch(patch); } @@ -1128,7 +1118,7 @@ void DebuggerController::DisableAll() { if (patch->controller == this) { - Release(patch); + ReleasePatch(patch); } } } @@ -1165,7 +1155,7 @@ void DebuggerController::Enqueue() LIMITED_METHOD_CONTRACT; m_eventQueuedCount++; - LOG((LF_CORDB, LL_INFO10000, "DC::Enq DC:0x%x m_eventQueuedCount at 0x%x\n", + LOG((LF_CORDB, LL_INFO10000, "DC::Enq DC: %p m_eventQueuedCount at 0x%x\n", this, m_eventQueuedCount)); } @@ -1183,7 +1173,7 @@ void DebuggerController::Dequeue() } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO10000, "DC::Deq DC:0x%x m_eventQueuedCount at 0x%x\n", + LOG((LF_CORDB, LL_INFO10000, "DC::Deq DC: %p m_eventQueuedCount at 0x%x\n", this, m_eventQueuedCount)); if (--m_eventQueuedCount == 0) { @@ -1221,7 +1211,7 @@ void DebuggerController::Dequeue() // mapping with. Future calls will fail too. // returns false, *pFail = true bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, - MethodDesc *fd, + MethodDesc *pMD, CORDB_ADDRESS_TYPE *startAddr) { CONTRACTL @@ -1235,8 +1225,11 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, CONTRACTL_END; _ASSERTE(patch != NULL); - _ASSERTE(!patch->IsILMasterPatch()); - _ASSERTE(fd != NULL); + _ASSERTE(!patch->IsILPrimaryPatch()); + _ASSERTE(pMD != NULL); + + LOG((LF_CORDB,LL_INFO10000, "DC::BP: Patch %p (patchId:0x%zx) to %s::%s (pMD: %p) at %p\n", + patch, patch->patchId, pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, pMD, startAddr)); // // Translate patch to address, if it hasn't been already. @@ -1258,10 +1251,10 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, { // Should not be trying to place patches on MethodDecs's for stubs. // These stubs will never get jitted. - CONSISTENCY_CHECK_MSGF(!fd->IsWrapperStub(), ("Can't place patch at stub md %p, %s::%s", - fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName)); + CONSISTENCY_CHECK_MSGF(!pMD->IsWrapperStub(), ("Can't place patch at stub md %p, %s::%s", + pMD, pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); - startAddr = (CORDB_ADDRESS_TYPE *)g_pEEInterface->GetFunctionAddress(fd); + startAddr = (CORDB_ADDRESS_TYPE *)g_pEEInterface->GetFunctionAddress(pMD); // // Code is not available yet to patch. The prestub should // notify us when it is executed. @@ -1269,7 +1262,7 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, if (startAddr == NULL) { LOG((LF_CORDB, LL_INFO10000, - "DC::BP:Patch at 0x%x not bindable yet.\n", patch->offset)); + "DC::BP: Patch at 0x%zx not bindable yet.\n", patch->offset)); return false; } @@ -1279,12 +1272,12 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, _ASSERTE(!g_pEEInterface->IsStub((const BYTE *)startAddr)); // If we've jitted, map to a native offset. - DebuggerJitInfo *info = g_pDebugger->GetJitInfo(fd, (const BYTE *)startAddr); + DebuggerJitInfo *info = g_pDebugger->GetJitInfo(pMD, (const BYTE *)startAddr); #ifdef LOGGING if (info == NULL) { - LOG((LF_CORDB,LL_INFO10000, "DC::BindPa: For startAddr 0x%x, didn't find a DJI\n", startAddr)); + LOG((LF_CORDB,LL_INFO10000, "DC::BP: For startAddr %p, didn't find a DJI\n", startAddr)); } #endif //LOGGING if (info != NULL) @@ -1292,21 +1285,21 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, // There is a strange case with prejitted code and unjitted trace patches. We can enter this function // with no DebuggerJitInfo created, then have the call just above this actually create the // DebuggerJitInfo, which causes JitComplete to be called, which causes all patches to be bound! If this - // happens, then we don't need to continue here (its already been done recursivley) and we don't need to - // re-active the patch, so we return false from right here. We can check this by seeing if we suddently + // happens, then we don't need to continue here (its already been done recursively) and we don't need to + // re-active the patch, so we return false from right here. We can check this by seeing if we suddenly // have the address in the patch set. if (patch->address != NULL) { - LOG((LF_CORDB,LL_INFO10000, "DC::BindPa: patch bound recursivley by GetJitInfo, bailing...\n")); + LOG((LF_CORDB,LL_INFO10000, "DC::BP: patch bound recursively by GetJitInfo, bailing...\n")); return false; } - LOG((LF_CORDB,LL_INFO10000, "DC::BindPa: For startAddr 0x%p, got DJI " - "0x%p, from 0x%p size: 0x%x\n", startAddr, info, info->m_addrOfCode, info->m_sizeOfCode)); + LOG((LF_CORDB,LL_INFO10000, "DC::BP: For startAddr %p, got DJI %p, from %p size: 0x%zu\n", + startAddr, info, info->m_addrOfCode, info->m_sizeOfCode)); } - LOG((LF_CORDB, LL_INFO10000, "DC::BP:Trying to bind patch in %s::%s version %d\n", - fd->m_pszDebugClassName, fd->m_pszDebugMethodName, info ? info->m_encVersion : (SIZE_T)-1)); + LOG((LF_CORDB, LL_INFO10000, "DC::BP: Trying to bind patch in %s::%s version %zu\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, info ? info->m_encVersion : (SIZE_T)-1)); _ASSERTE(g_patches != NULL); @@ -1314,7 +1307,7 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, CodeRegionInfo::GetCodeRegionInfo(NULL, NULL, startAddr).OffsetToAddress(patch->offset); g_patches->BindPatch(patch, addr); - LOG((LF_CORDB, LL_INFO10000, "DC::BP:Binding patch at 0x%x(off:%x)\n", addr, patch->offset)); + LOG((LF_CORDB, LL_INFO10000, "DC::BP:Binding patch at %p (off:0x%zx)\n", addr, patch->offset)); return true; } @@ -1333,23 +1326,21 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, // placed into the code-stream, false otherwise bool DebuggerController::ApplyPatch(DebuggerControllerPatch *patch) { - LOG((LF_CORDB, LL_INFO10000, "DC::ApplyPatch at addr 0x%p\n", - patch->address)); + _ASSERTE(patch != NULL); + + LOG((LF_CORDB, LL_INFO10000, "DC::ApplyPatch %p, patchId:0x%zx at addr %p\n", + patch, patch->patchId, patch->address)); // If we try to apply an already applied patch, we'll override our saved opcode // with the break opcode and end up getting a break in out patch bypass buffer. _ASSERTE(!patch->IsActivated() ); _ASSERTE(patch->IsBound()); - // Note we may be patching at certain "blessed" points in mscorwks. - // This is very dangerous b/c we can't be sure patch->Address is blessed or not. - - // // Apply the patch. // _ASSERTE(!(g_pConfig->GetGCStressLevel() & (EEConfig::GCSTRESS_INSTR_JIT|EEConfig::GCSTRESS_INSTR_NGEN)) - && "Debugger does not work with GCSTRESS 4"); + && "Debugger does not work with GCSTRESS 0x4 or 0x8"); if (patch->IsNativePatch()) { @@ -1390,7 +1381,8 @@ bool DebuggerController::ApplyPatch(DebuggerControllerPatch *patch) patch->opcode = CORDbgGetInstruction(patch->address); CORDbgInsertBreakpoint((CORDB_ADDRESS_TYPE *)patch->address); - LOG((LF_CORDB, LL_EVERYTHING, "Breakpoint was inserted at %p for opcode %x\n", patch->address, patch->opcode)); + LOG((LF_CORDB, LL_EVERYTHING, "DC::ApplyPatch Breakpoint was inserted at %p for opcode %x\n", + patch->address, patch->opcode)); #if !defined(HOST_OSX) || !defined(HOST_ARM64) if (!VirtualProtect(baseAddress, @@ -1455,11 +1447,12 @@ bool DebuggerController::ApplyPatch(DebuggerControllerPatch *patch) // Returns: true if the patch was unapplied, false otherwise bool DebuggerController::UnapplyPatch(DebuggerControllerPatch *patch) { + _ASSERTE(patch != NULL); _ASSERTE(patch->address != NULL); _ASSERTE(patch->IsActivated() ); - LOG((LF_CORDB,LL_INFO1000, "DC::UP unapply patch at addr 0x%p\n", - patch->address)); + LOG((LF_CORDB, LL_INFO1000, "DC::UnapplyPatch %p, patchId:0x%zx\n", + patch, patch->patchId)); if (patch->IsNativePatch()) { @@ -1563,54 +1556,16 @@ bool DebuggerController::UnapplyPatch(DebuggerControllerPatch *patch) return true; } -// void DebuggerController::UnapplyPatchAt() -// NO LOCKING -// UnapplyPatchAt removes the patch from a copy of the patched code. -// Like UnapplyPatch, except that we don't bother checking -// memory permissions, but instead replace the breakpoint instruction -// with the opcode at an arbitrary memory address. -void DebuggerController::UnapplyPatchAt(DebuggerControllerPatch *patch, - CORDB_ADDRESS_TYPE *address) -{ - _ASSERTE(patch->IsBound() ); - - if (patch->IsNativePatch()) - { - CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)address, patch->opcode); - //note that we don't have to zero out opcode field - //since we're unapplying at something other than - //the original spot. We assert this is true: - _ASSERTE( patch->address != address ); - } - else - { - // - // !!! IL patch logic assumes reference encoding - // -// TODO: : determine if this is needed for AMD64 -#ifdef TARGET_X86 - _ASSERTE(*(unsigned short*)(address+1) == CEE_BREAK); - - *(unsigned short *) (address+1) - = (unsigned short) patch->opcode; - _ASSERTE( patch->address != address ); -#endif // this makes no sense on anything but X86 - } -} - // bool DebuggerController::IsPatched() Is there a patch at addr? // How: if fNative && the instruction at addr is the break // instruction for this platform. bool DebuggerController::IsPatched(CORDB_ADDRESS_TYPE *address, BOOL native) { LIMITED_METHOD_CONTRACT; - if (native) - { return AddressIsBreakpoint(address); - } - else - return false; + + return false; } // DWORD DebuggerController::GetPatchedOpcode() Gets the opcode @@ -1730,8 +1685,10 @@ BOOL DebuggerController::CheckGetPatchedOpcode(CORDB_ADDRESS_TYPE *address, _ASSERTE(patch->IsBound() ); _ASSERTE(!patch->IsActivated() ); - bool fApply = true; + LOG((LF_CORDB|LF_ENC,LL_INFO1000,"DC::ActivatePatch: patchId:0x%zx\n", patch->patchId)); + patch->LogInstance(); + bool fApply = true; // // See if we already have an active patch at this address. // @@ -1744,6 +1701,8 @@ BOOL DebuggerController::CheckGetPatchedOpcode(CORDB_ADDRESS_TYPE *address, // If we're going to skip activating 'patch' because 'p' already exists at the same address // then 'p' must be activated. We expect that all bound patches are activated. _ASSERTE( p->IsActivated() ); + LOG((LF_CORDB, LL_INFO10000, "DC::ActivatePatch: There is another patch at this address, no need to apply it.\n")); + p->LogInstance(); patch->opcode = p->opcode; fApply = false; break; @@ -1759,7 +1718,7 @@ BOOL DebuggerController::CheckGetPatchedOpcode(CORDB_ADDRESS_TYPE *address, ApplyPatch(patch); } - _ASSERTE(patch->IsActivated() ); + _ASSERTE(patch->IsActivated()); } // void DebuggerController::DeactivatePatch() Make sure that a @@ -1771,11 +1730,12 @@ BOOL DebuggerController::CheckGetPatchedOpcode(CORDB_ADDRESS_TYPE *address, void DebuggerController::DeactivatePatch(DebuggerControllerPatch *patch) { _ASSERTE(g_patches != NULL); + _ASSERTE(patch != NULL); - if( !patch->IsBound() ) { - // patch is not bound, nothing to do + LOG((LF_CORDB|LF_ENC,LL_INFO1000,"DC::DeactivatePatch: patchId:0x%zx\n", patch->patchId)); + patch->LogInstance(); + if( !patch->IsBound() ) return; - } // We expect that all bound patches are also activated. // One exception to this is if the shutdown thread killed another thread right after @@ -1795,6 +1755,8 @@ void DebuggerController::DeactivatePatch(DebuggerControllerPatch *patch) { // There is another patch at this address, so don't remove it // However, clear the patch data so that we no longer consider this particular patch activated + LOG((LF_CORDB, LL_INFO10000, "DC::DeactivatePatch: There is another patch at this address, don't unapply it.\n")); + p->LogInstance(); fUnapply = false; InitializePRD(&(patch->opcode)); break; @@ -1813,9 +1775,9 @@ void DebuggerController::DeactivatePatch(DebuggerControllerPatch *patch) // } -// AddILMasterPatch: record a patch on IL code but do not bind it or activate it. The master b.p. +// AddILPrimaryPatch: record a patch on IL code but do not bind it or activate it. The primary b.p. // is associated with a module/token pair. It is used later -// (e.g. in MapAndBindFunctionPatches) to create one or more "slave" +// (e.g. in MapAndBindFunctionPatches) to create one or more "replica" // breakpoints which are associated with particular MethodDescs/JitInfos. // // Rationale: For generic code a single IL patch (e.g a breakpoint) @@ -1825,14 +1787,14 @@ void DebuggerController::DeactivatePatch(DebuggerControllerPatch *patch) // // So we keep one patch which describes // the breakpoint but which is never actually bound or activated. -// This is then used to apply new "slave" patches to all copies of +// This is then used to apply new "replica" patches to all copies of // JITted code associated with the method. // -// In theory we could bind and apply the master patch when the +// In theory we could bind and apply the primary patch when the // code is known not to be generic (as used to happen to all breakpoint // patches in V1). However this seems like a premature // optimization. -DebuggerControllerPatch *DebuggerController::AddILMasterPatch(Module *module, +DebuggerControllerPatch *DebuggerController::AddILPrimaryPatch(Module *module, mdMethodDef md, MethodDesc *pMethodDescFilter, SIZE_T offset, @@ -1858,51 +1820,52 @@ DebuggerControllerPatch *DebuggerController::AddILMasterPatch(Module *module, pMethodDescFilter, offset, offsetIsIL, - PATCH_KIND_IL_MASTER, + PATCH_KIND_IL_PRIMARY, LEAF_MOST_FRAME, NULL, encVersion, NULL); LOG((LF_CORDB, LL_INFO10000, - "DC::AP: Added IL master patch 0x%p for mdTok 0x%x, desc 0x%p at %s offset %d encVersion %d\n", - patch, md, pMethodDescFilter, offsetIsIL ? "il" : "native", offset, encVersion)); + "DC::AP: Added IL primary patch %p for mdTok 0x%x, filter %p at %s offset 0x%zx encVersion %zx\n", + patch, md, pMethodDescFilter, (offsetIsIL ? "IL" : "native"), offset, encVersion)); return patch; } -// See notes above on AddILMasterPatch -BOOL DebuggerController::AddBindAndActivateILSlavePatch(DebuggerControllerPatch *master, +// See notes above on AddILPrimaryPatch +BOOL DebuggerController::AddBindAndActivateILReplicaPatch(DebuggerControllerPatch *primary, DebuggerJitInfo *dji) { _ASSERTE(g_patches != NULL); - _ASSERTE(master->IsILMasterPatch()); + _ASSERTE(primary->IsILPrimaryPatch()); _ASSERTE(dji != NULL); - BOOL result = FALSE; + BOOL result = FALSE; + MethodDesc* pMD = dji->m_nativeCodeVersion.GetMethodDesc(); - if (!master->offsetIsIL) + if (primary->offsetIsIL == 0) { // Zero is the only native offset that we allow to bind across different jitted // code bodies. - _ASSERTE(master->offset == 0); + _ASSERTE(primary->offset == 0); INDEBUG(BOOL fOk = ) - AddBindAndActivatePatchForMethodDesc(dji->m_nativeCodeVersion.GetMethodDesc(), dji, - 0, PATCH_KIND_IL_SLAVE, + AddBindAndActivatePatchForMethodDesc(pMD, dji, + 0, PATCH_KIND_IL_REPLICA, LEAF_MOST_FRAME, m_pAppDomain); _ASSERTE(fOk); result = TRUE; } else // bind by IL offset { - // Do not dereference the "master" pointer in the loop! The loop may add more patches, + // Do not dereference the "primary" pointer in the loop! The loop may add more patches, // causing the patch table to grow and move. - SIZE_T masterILOffset = master->offset; + SIZE_T primaryILOffset = primary->offset; // Loop through all the native offsets mapped to the given IL offset. On x86 the mapping // should be 1:1. On WIN64, because there are funclets, we have a 1:N mapping. DebuggerJitInfo::ILToNativeOffsetIterator it; - for (dji->InitILToNativeOffsetIterator(it, masterILOffset); !it.IsAtEnd(); it.Next()) + for (dji->InitILToNativeOffsetIterator(it, primaryILOffset); !it.IsAtEnd(); it.Next()) { BOOL fExact; SIZE_T offsetNative = it.Current(&fExact); @@ -1911,21 +1874,18 @@ BOOL DebuggerController::AddBindAndActivateILSlavePatch(DebuggerControllerPatch // at the beginning of a method that hasn't been jitted yet. In // that case it's possible that offset 0 has been optimized out, // but we still want to set the closest breakpoint to that. - if (!fExact && (masterILOffset != 0)) + if (!fExact && (primaryILOffset != 0)) { - LOG((LF_CORDB, LL_INFO10000, "DC::BP:Failed to bind patch at IL offset 0x%p in %s::%s\n", - masterILOffset, dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugClassName, dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugMethodName)); - + LOG((LF_CORDB, LL_INFO10000, "DC::BP:Failed to bind patch in %s::%s at IL offset 0x%zx, native offset 0x%zx\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, primaryILOffset, offsetNative)); continue; } - else - { - result = TRUE; - } + + result = TRUE; INDEBUG(BOOL fOk = ) - AddBindAndActivatePatchForMethodDesc(dji->m_nativeCodeVersion.GetMethodDesc(), dji, - offsetNative, PATCH_KIND_IL_SLAVE, + AddBindAndActivatePatchForMethodDesc(pMD, dji, + offsetNative, PATCH_KIND_IL_REPLICA, LEAF_MOST_FRAME, m_pAppDomain); _ASSERTE(fOk); } @@ -1945,8 +1905,8 @@ BOOL DebuggerController::AddBindAndActivateILSlavePatch(DebuggerControllerPatch // This routine will return FALSE only if we will _never_ be able to // place the patch in any native code corresponding to the given offset. // Otherwise it will: -// (a) record a "master" patch -// (b) apply as many slave patches as it can to existing copies of code +// (a) record a "primary" patch +// (b) apply as many replica patches as it can to existing copies of code // that have debugging information BOOL DebuggerController::AddILPatch(AppDomain * pAppDomain, Module *module, mdMethodDef md, @@ -1962,9 +1922,9 @@ BOOL DebuggerController::AddILPatch(AppDomain * pAppDomain, Module *module, BOOL fOk = FALSE; DebuggerMethodInfo *dmi = g_pDebugger->GetOrCreateMethodInfo(module, md); // throws - LOG((LF_CORDB,LL_INFO10000,"DC::AILP: dmi:0x%p, mdToken:0x%x, mdFilter:0x%p, " - "encVer:%zu, offset:0x%zx <- isIL:%d, Mod:0x%p\n", - dmi, md, pMethodDescFilter, encVersion, offset, offsetIsIL, module)); + LOG((LF_CORDB,LL_INFO10000,"DC::AILP: dmi:%p, mdToken:0x%x, mdFilter:%p, " + "encVer:%zu, offset:0x%zx <- isIL:%s, Mod:%p\n", + dmi, md, pMethodDescFilter, encVersion, offset, (offsetIsIL ? "true" : "false"), module)); if (dmi == NULL) { @@ -1975,15 +1935,15 @@ BOOL DebuggerController::AddILPatch(AppDomain * pAppDomain, Module *module, { // OK, we either have (a) no code at all or (b) we have both JIT information and code //. - // Either way, lay down the MasterPatch. + // Either way, lay down the PrimaryPatch. // // MapAndBindFunctionPatches will take care of any instantiations that haven't - // finished JITting, by making a copy of the master breakpoint. - DebuggerControllerPatch *master = AddILMasterPatch(module, md, pMethodDescFilter, offset, offsetIsIL, encVersion); + // finished JITting, by making a copy of the primary breakpoint. + DebuggerControllerPatch *primary = AddILPrimaryPatch(module, md, pMethodDescFilter, offset, offsetIsIL, encVersion); // We have to keep the index here instead of the pointer. The loop below adds more patches, // which may cause the patch table to grow and move. - ULONG masterIndex = g_patches->GetItemIndex((HASHENTRY*)master); + ULONG primaryIndex = g_patches->GetItemIndex((HASHENTRY*)primary); // Iterate through every existing NativeCodeBlob (with the same EnC version). // This includes generics + prejitted code. @@ -2012,14 +1972,14 @@ BOOL DebuggerController::AddILPatch(AppDomain * pAppDomain, Module *module, { fVersionMatch = TRUE; - master = (DebuggerControllerPatch *)g_patches->GetEntryPtr(masterIndex); + primary = (DebuggerControllerPatch *)g_patches->GetEntryPtr(primaryIndex); // If we're missing JIT info for any then // we won't have applied the bp to every instantiation. That should probably be reported // as a new kind of condition to the debugger, i.e. report "bp only partially applied". It would be // a shame to completely fail just because on instantiation is missing debug info: e.g. just because // one component hasn't been prejitted with debugging information. - fOk = (AddBindAndActivateILSlavePatch(master, dji) || fOk); + fOk = (AddBindAndActivateILReplicaPatch(primary, dji) || fOk); } it.Next(); } @@ -2028,6 +1988,7 @@ BOOL DebuggerController::AddILPatch(AppDomain * pAppDomain, Module *module, // because we don't have a matching version of the method, we need to return TRUE. if (fVersionMatch == FALSE) { + LOG((LF_CORDB,LL_INFO10000,"DC::AILP: No matching DebuggerJitInfo found\n")); fOk = TRUE; } } @@ -2106,17 +2067,15 @@ BOOL DebuggerController::AddBindAndActivatePatchForMethodDesc(MethodDesc *fd, MODE_ANY; // don't really care what mode we're in. PRECONDITION(ThisMaybeHelperThread()); - PRECONDITION(kind != PATCH_KIND_IL_MASTER); + PRECONDITION(kind != PATCH_KIND_IL_PRIMARY); } CONTRACTL_END; BOOL ok = FALSE; ControllerLockHolder ch; - LOG((LF_CORDB|LF_ENC,LL_INFO10000,"DC::AP: Add to %s::%s, at offs 0x%x " - "fp:0x%p AD:0x%p\n", fd->m_pszDebugClassName, - fd->m_pszDebugMethodName, - nativeOffset, fp.GetSPValue(), pAppDomain)); + LOG((LF_CORDB|LF_ENC,LL_INFO10000,"DC::ABAAPFMD: Add to %s::%s, at offs 0x%zx kind:%d fp:%p AD:%p\n", + fd->m_pszDebugClassName, fd->m_pszDebugMethodName, nativeOffset, kind, fp.GetSPValue(), pAppDomain)); DebuggerControllerPatch *patch = g_patches->AddPatchForMethodDef( this, @@ -2133,7 +2092,6 @@ BOOL DebuggerController::AddBindAndActivatePatchForMethodDesc(MethodDesc *fd, if (DebuggerController::BindPatch(patch, fd, NULL)) { - LOG((LF_CORDB|LF_ENC,LL_INFO1000,"BindPatch went fine, doing ActivatePatch\n")); DebuggerController::ActivatePatch(patch); ok = TRUE; } @@ -2171,7 +2129,7 @@ DebuggerControllerPatch *DebuggerController::AddAndActivateNativePatchForAddress fp, NULL, NULL, - DebuggerPatchTable::DCP_PID_INVALID, + DebuggerPatchTable::DCP_PATCHID_INVALID, traceType); ActivatePatch(patch); @@ -2229,7 +2187,7 @@ void DebuggerController::RemovePatchesFromModule(Module *pModule, AppDomain *pAp // we shouldn't be both hitting this patch AND // unloading the module it belongs to. _ASSERTE(!patch->IsTriggering()); - Release( patch ); + ReleasePatch( patch ); } } } @@ -2612,8 +2570,8 @@ DPOSS_ACTION DebuggerController::ScanForTriggers(CORDB_ADDRESS_TYPE *address, CONTRACT_VIOLATION(ThrowsViolation); - LOG((LF_CORDB, LL_INFO10000, "DC::SFT: starting scan for addr:0x%p" - " thread:0x%x\n", address, thread)); + LOG((LF_CORDB, LL_INFO10000, "DC::SFT: starting scan for addr:%p thread:%p\n", + address, thread)); _ASSERTE( pTpr != NULL ); DebuggerControllerPatch *patch = NULL; @@ -2651,7 +2609,7 @@ DPOSS_ACTION DebuggerController::ScanForTriggers(CORDB_ADDRESS_TYPE *address, DebuggerControllerPatch *patchNext = g_patches->GetNextPatch(patch); - LOG((LF_CORDB, LL_INFO10000, "DC::SFT: patch 0x%x, patchNext 0x%x\n", patch, patchNext)); + LOG((LF_CORDB, LL_INFO10000, "DC::SFT: patch:%p, patchNext:%p\n", patch, patchNext)); // Annoyingly, TriggerPatch may add patches, which may cause // the patch table to move, which may, in turn, invalidate @@ -2666,7 +2624,7 @@ DPOSS_ACTION DebuggerController::ScanForTriggers(CORDB_ADDRESS_TYPE *address, if (MatchPatch(thread, context, patch)) { LOG((LF_CORDB, LL_INFO10000, "DC::SFT: patch matched\n")); - AddRef(patch); + AddRefPatch(patch); // We are hitting a patch at a virtual trace call target, so let's trigger trace call here. if (patch->trace.GetTraceType() == TRACE_ENTRY_STUB) @@ -2717,9 +2675,9 @@ DPOSS_ACTION DebuggerController::ScanForTriggers(CORDB_ADDRESS_TYPE *address, if (patchNext != NULL) iEventNext = g_patches->GetItemIndex((HASHENTRY *)patchNext); - // Note that Release() actually removes the patch if its ref count + // Note that ReleasePatch() actually removes the patch if its ref count // reaches 0 after the release. - Release(patch); + ReleasePatch(patch); } if (tpr == TPR_IGNORE_AND_STOP || @@ -2829,55 +2787,58 @@ DPOSS_ACTION DebuggerController::ScanForTriggers(CORDB_ADDRESS_TYPE *address, // Significant speed increase from single dereference, I bet :) (*pTpr) = tpr; - LOG((LF_CORDB, LL_INFO10000, "DC::SFT returning 0x%x as used\n",used)); + LOG((LF_CORDB, LL_INFO10000, "DC::SFT: returning 0x%x as used\n",used)); return used; } #ifdef EnC_SUPPORTED -DebuggerControllerPatch *DebuggerController::IsXXXPatched(const BYTE *PC, - DEBUGGER_CONTROLLER_TYPE dct) -{ - _ASSERTE(g_patches != NULL); - - DebuggerControllerPatch *patch = g_patches->GetPatch((CORDB_ADDRESS_TYPE *)PC); - - while(patch != NULL && - (int)patch->controller->GetDCType() <= (int)dct) - { - if (patch->IsNativePatch() && - patch->controller->GetDCType()==dct) - { - return patch; - } - patch = g_patches->GetNextPatch(patch); - } - - return NULL; -} - // This function will check for an EnC patch at the given address and return // it if one is there, otherwise it will return NULL. -DebuggerControllerPatch *DebuggerController::GetEnCPatch(const BYTE *address) + DebuggerControllerPatch *DebuggerController::GetEnCPatch(const BYTE *address) { _ASSERTE(address); + LOG((LF_CORDB|LF_ENC,LL_INFO1000,"DC:GEnCP at %p\n", address)); if( g_pEEInterface->IsManagedNativeCode(address) ) { + LOG((LF_CORDB|LF_ENC,LL_INFO1000,"DC:GEnCP address is managed code\n")); DebuggerJitInfo *dji = g_pDebugger->GetJitInfoFromAddr((TADDR) address); if (dji == NULL) return NULL; + dji->LogInstance(); + // we can have two types of patches - one in code where the IL has been updated to trigger // the switch and the other in the code we've switched to in order to trigger FunctionRemapComplete // callback. If version == default then can't be the latter, but otherwise if haven't handled the // remap for this function yet is certainly the latter. - if (! dji->m_encBreakpointsApplied && - (dji->m_encVersion == CorDB_DEFAULT_ENC_FUNCTION_VERSION)) + if (! dji->m_encBreakpointsApplied + && (dji->m_encVersion == CorDB_DEFAULT_ENC_FUNCTION_VERSION)) { return NULL; } } - return IsXXXPatched(address, DEBUGGER_CONTROLLER_ENC); + + // Look for EnC patch + DebuggerControllerPatch *patch = g_patches->GetPatch((CORDB_ADDRESS_TYPE *)address); + LOG((LF_CORDB|LF_ENC,LL_INFO1000,"DC:GEnCP Searching, beginning patch: %p\n", patch)); + + while (patch != NULL) + { + // Patches are ordered by DEBUGGER_CONTROLLER_TYPE value + DEBUGGER_CONTROLLER_TYPE dct = patch->controller->GetDCType(); + if ((int)dct > (int)DEBUGGER_CONTROLLER_ENC) + break; + + if (dct == DEBUGGER_CONTROLLER_ENC + && patch->IsNativePatch()) + { + return patch; + } + patch = g_patches->GetNextPatch(patch); + } + + return NULL; } #endif //EnC_SUPPORTED @@ -2935,8 +2896,7 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE // debugger wants to remap the function at this point, then we'll call ResumeInUpdatedFunction and // not return, otherwise we will just continue with regular patch-handling logic dcpEnCOriginal = GetEnCPatch(dac_cast(GetIP(context))); - - if (dcpEnCOriginal) + if (dcpEnCOriginal != NULL) { LOG((LF_CORDB|LF_ENC,LL_INFO10000, "DC::DPOSS EnC short-circuit\n")); TP_RESULT tpres = @@ -3416,7 +3376,7 @@ void DebuggerController::EnableUnwind(FramePointer fp) CONTRACTL_END; ASSERT(m_thread != NULL); - LOG((LF_CORDB,LL_EVERYTHING,"DC:EU EnableUnwind at 0x%x\n", fp.GetSPValue())); + LOG((LF_CORDB,LL_EVERYTHING,"DC:EU EnableUnwind at %p\n", fp.GetSPValue())); ControllerLockHolder lockController; m_unwindFP = fp; @@ -4210,15 +4170,16 @@ bool DebuggerController::DispatchNativeException(EXCEPTION_RECORD *pException, // In most cases it is an error to nest, however in the patch-skipping logic we must // copy an unknown amount of code into another buffer and it occasionally triggers - // an AV. This heuristic should filter that case out. See DDB 198093. + // an AV. This heuristic should filter that case out. // Ensure we perform this exception nesting filtering even before the call to // DebuggerController::DispatchExceptionHook, otherwise the nesting will continue when // a contract check is triggered in DispatchExceptionHook and another BP exception is - // raised. See Dev11 66058. - if ((pOldContext != NULL) && pCurThread->AVInRuntimeImplOkay() && - pException->ExceptionCode == STATUS_ACCESS_VIOLATION) + // raised. + if (pOldContext != NULL + && pCurThread->AVInRuntimeImplOkay() + && pException->ExceptionCode == STATUS_ACCESS_VIOLATION) { - STRESS_LOG1(LF_CORDB, LL_INFO100, "DC::DNE Nested Access Violation at 0x%p is being ignored\n", + STRESS_LOG1(LF_CORDB, LL_INFO100, "DC::DNE Nested Access Violation at %p is being ignored\n", pException->ExceptionAddress); return false; } @@ -4340,7 +4301,7 @@ bool DebuggerController::DispatchNativeException(EXCEPTION_RECORD *pException, #ifdef FEATURE_EMULATE_SINGLESTEP if (pCurThread->IsSingleStepEnabled()) pCurThread->ApplySingleStep(pContext); -#endif +#endif // FEATURE_EMULATE_SINGLESTEP FireEtwDebugExceptionProcessingEnd(); @@ -4531,8 +4492,7 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, if (context ==(T_CONTEXT*) &c) thread->SetThreadContext(&c); - - LOG((LF_CORDB, LL_INFO10000, "DPS::DPS Bypass at 0x%p for opcode %p \n", patchBypassRX, patch->opcode)); + LOG((LF_CORDB, LL_INFO10000, "DPS::DPS Bypass at %p for opcode 0x%zx \n", patchBypassRX, patch->opcode)); // // Turn on single step (if the platform supports it) so we can @@ -4542,7 +4502,7 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, EnableSingleStep(); -#endif // FEATURE_EMULATE_SINGLESTEP +#endif // !FEATURE_EMULATE_SINGLESTEP EnableExceptionHook(); } @@ -4552,7 +4512,7 @@ DebuggerPatchSkip::~DebuggerPatchSkip() #ifndef FEATURE_EMULATE_SINGLESTEP _ASSERTE(m_pSharedPatchBypassBuffer); m_pSharedPatchBypassBuffer->Release(); -#endif +#endif // !FEATURE_EMULATE_SINGLESTEP } void DebuggerPatchSkip::DebuggerDetachClean() @@ -4587,7 +4547,7 @@ void DebuggerPatchSkip::DebuggerDetachClean() SetIP(context, (PCODE)((BYTE *)GetIP(context) - (patchBypass - (BYTE *)m_address))); } } -#endif +#endif // !FEATURE_EMULATE_SINGLESTEP } @@ -4979,7 +4939,6 @@ DebuggerBreakpoint::DebuggerBreakpoint(Module *module, if (native && !nativeCodeBindAllVersions) { (*pSucceed) = AddBindAndActivateNativeManagedPatch(nativeMethodDesc, nativeJITInfo, offset, LEAF_MOST_FRAME, pAppDomain); - return; } else { @@ -5198,7 +5157,7 @@ bool DebuggerStepper::IsRangeAppropriate(ControllerStackInfo *info) bool DebuggerStepper::IsInRange(SIZE_T ip, COR_DEBUG_STEP_RANGE *range, SIZE_T rangeCount, ControllerStackInfo *pInfo) { - LOG((LF_CORDB,LL_INFO10000,"DS::IIR: off=0x%p\n", ip)); + LOG((LF_CORDB,LL_INFO10000,"DS::IIR: off=%zx\n", ip)); if (range == NULL) { @@ -5218,15 +5177,13 @@ bool DebuggerStepper::IsInRange(SIZE_T ip, COR_DEBUG_STEP_RANGE *range, SIZE_T r while (r < rEnd) { SIZE_T endOffset = r->endOffset ? r->endOffset : ~0; - LOG((LF_CORDB,LL_INFO100000,"DS::IIR: so=0x%x, eo=0x%x\n", + LOG((LF_CORDB,LL_INFO100000,"DS::IIR: so=0x%x, eo=0x%zx\n", r->startOffset, endOffset)); if (ip >= r->startOffset && ip < endOffset) { - LOG((LF_CORDB,LL_INFO1000,"DS::IIR:this:0x%p Found native offset " - "0x%x to be in the range" - "[0x%x, 0x%x), index 0x%x\n\n", this, ip, r->startOffset, - endOffset, ((r-range)/sizeof(COR_DEBUG_STEP_RANGE *)) )); + LOG((LF_CORDB,LL_INFO1000,"DS::IIR: this:%p, Found native offset 0x%zx to be in the range [0x%x, 0x%zx), index 0x%zx\n", + this, ip, r->startOffset, endOffset, ((r-range)/sizeof(COR_DEBUG_STEP_RANGE *)) )); return true; } @@ -5637,7 +5594,6 @@ bool DebuggerStepper::TrapStepInHelper( StubManager::DbgBeginLog((TADDR) ipNext, (TADDR) ipCallTarget); #endif - if (TrapStepInto(pInfo, ipCallTarget, &td)) { // If we placed a patch, see if we need to update our step-reason @@ -5653,22 +5609,19 @@ bool DebuggerStepper::TrapStepInHelper( CodeRegionInfo code = CodeRegionInfo::GetCodeRegionInfo(pDJI, md); if (code.AddressToOffset((const BYTE *)td.GetAddress()) == 0) { - - LOG((LF_CORDB,LL_INFO1000,"\tDS::TS 0x%x m_reason = STEP_CALL" - "@ip0x%x\n", this, (BYTE*)GetControlPC(&(pInfo->m_activeFrame.registers)))); + LOG((LF_CORDB,LL_INFO1000,"DS::TS %p m_reason = STEP_CALL @ip%p\n", + this, (BYTE*)GetControlPC(&(pInfo->m_activeFrame.registers)))); m_reason = STEP_CALL; } else { - LOG((LF_CORDB, LL_INFO1000, "Didn't step: md:0x%x" - "td.type:%s td.address:0x%p, hot code address:0x%p\n", - md, GetTType(td.GetTraceType()), td.GetAddress(), - code.getAddrOfHotCode())); + LOG((LF_CORDB, LL_INFO1000, "Didn't step: md:%p td.type:%s td.address:%p, hot code address:%p\n", + md, GetTType(td.GetTraceType()), td.GetAddress(), code.getAddrOfHotCode())); } } else { - LOG((LF_CORDB,LL_INFO10000,"DS::TS else 0x%x m_reason = STEP_CALL\n", + LOG((LF_CORDB,LL_INFO10000,"DS::TS else %p m_reason = STEP_CALL\n", this)); m_reason = STEP_CALL; } @@ -5767,7 +5720,7 @@ static bool IsTailCallThatReturns(const BYTE * ip, ControllerStackInfo* info) // on the method that called the current frame's method. bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in) { - LOG((LF_CORDB,LL_INFO10000,"DS::TS: this:0x%x\n", this)); + LOG((LF_CORDB,LL_INFO10000,"DS::TS: this:%p\n", this)); if (!info->m_activeFrame.managed) { // @@ -6733,10 +6686,8 @@ bool DebuggerStepper::SetRangesFromIL(DebuggerJitInfo *dji, COR_DEBUG_STEP_RANGE if (dji != NULL) { - LOG((LF_CORDB,LL_INFO10000,"DeSt::St: For code md=0x%p, got DJI 0x%p, from 0x%p to 0x%p\n", - fd, - dji, dji->m_addrOfCode, (ULONG)dji->m_addrOfCode - + (ULONG)dji->m_sizeOfCode)); + LOG((LF_CORDB,LL_INFO10000,"DeSt::St: For code md=%p, got DJI %p, from %p to %p\n", + fd, dji, dji->m_addrOfCode, dji->m_addrOfCode + dji->m_sizeOfCode)); // // Map ranges to native offsets for jitted code @@ -6889,7 +6840,7 @@ bool DebuggerStepper::Step(FramePointer fp, bool in, COR_DEBUG_STEP_RANGE *ranges, SIZE_T rangeCount, bool rangeIL) { - LOG((LF_CORDB, LL_INFO1000, "DeSt:Step this:0x%x ", this)); + LOG((LF_CORDB, LL_INFO1000, "DeSt:Step this:%p ", this)); if (rangeCount>0) LOG((LF_CORDB,LL_INFO10000," start,end[0]:(0x%x,0x%x)\n", ranges[0].startOffset, ranges[0].endOffset)); @@ -8269,7 +8220,7 @@ bool DebuggerJMCStepper::DetectHandleInterceptors(ControllerStackInfo * info) DebuggerThreadStarter::DebuggerThreadStarter(Thread *thread) : DebuggerController(thread, NULL) { - LOG((LF_CORDB, LL_INFO1000, "DTS::DTS: this:0x%x Thread:0x%x\n", + LOG((LF_CORDB, LL_INFO1000, "DTS::DTS: this: %p Thread: %p\n", this, thread)); // Check to make sure we only have 1 ThreadStarter on a given thread. (Inspired by NDPWhidbey issue 16888) @@ -8720,17 +8671,34 @@ DebuggerEnCBreakpoint::DebuggerEnCBreakpoint(SIZE_T offset, DebuggerJitInfo *jitInfo, DebuggerEnCBreakpoint::TriggerType fTriggerType, AppDomain *pAppDomain) - : DebuggerController(NULL, pAppDomain), - m_jitInfo(jitInfo), - m_fTriggerType(fTriggerType) + : DebuggerController(NULL, pAppDomain), + m_jitInfo(jitInfo), + m_fTriggerType(fTriggerType) { - _ASSERTE( jitInfo != NULL ); - // Add and activate the specified patch - AddBindAndActivateNativeManagedPatch(jitInfo->m_nativeCodeVersion.GetMethodDesc(), jitInfo, offset, LEAF_MOST_FRAME, pAppDomain); - LOG((LF_ENC,LL_INFO1000, "DEnCBPDEnCBP::adding %s patch!\n", - fTriggerType == REMAP_PENDING ? "remap pending" : "remap complete")); -} + _ASSERTE( m_jitInfo != NULL ); + BOOL success; + MethodDesc* pMD = m_jitInfo->m_nativeCodeVersion.GetMethodDesc(); + if (m_fTriggerType == DebuggerEnCBreakpoint::REMAP_COMPLETE) + { + success = AddBindAndActivateNativeManagedPatch(pMD, m_jitInfo, offset, LEAF_MOST_FRAME, pAppDomain); + } + else + { + _ASSERTE(m_fTriggerType == DebuggerEnCBreakpoint::REMAP_PENDING); + + // Add and activate the specified patch + Module* module = m_jitInfo->m_pLoaderModule; + mdMethodDef tkMethod = pMD->GetMemberDef(); + SIZE_T encVersion = m_jitInfo->m_encVersion; + success = AddILPatch(pAppDomain, module, tkMethod, NULL, encVersion, offset, TRUE); + } + + _ASSERTE(success != FALSE); + + LOG((LF_ENC,LL_INFO1000, "DEnCBP::DEnCBP adding %s patch to 0x%x encVersion: %zx\n", + fTriggerType == REMAP_PENDING ? "ResumePending" : "ResumeComplete", pMD->GetMemberDef(), m_jitInfo->m_encVersion)); +} //--------------------------------------------------------------------------------------- // @@ -8753,26 +8721,9 @@ TP_RESULT DebuggerEnCBreakpoint::TriggerPatch(DebuggerControllerPatch *patch, { _ASSERTE(HasLock()); - Module *module = patch->key.module; - mdMethodDef md = patch->key.md; - SIZE_T offset = patch->offset; - - // Map the current native offset back to the IL offset in the old - // function. This will be mapped to the new native offset within - // ResumeInUpdatedFunction - CorDebugMappingResult map; - DWORD which; - SIZE_T currentIP = (SIZE_T)m_jitInfo->MapNativeOffsetToIL(offset, - &map, &which); - - // We only lay DebuggerEnCBreakpoints at sequence points - _ASSERTE(map == MAPPING_EXACT); - LOG((LF_ENC, LL_ALWAYS, - "DEnCBP::TP: triggered E&C %s breakpoint: tid=0x%x, module=0x%08x, " - "method def=0x%08x, version=%d, native offset=0x%x, IL offset=0x%x\n this=0x%x\n", - m_fTriggerType == REMAP_PENDING ? "ResumePending" : "ResumeComplete", - thread, module, md, m_jitInfo->m_encVersion, offset, currentIP, this)); + "DEnCBP::TP: Triggered EnC %s breakpoint: tid=%p, this=%p\n", + m_fTriggerType == REMAP_PENDING ? "ResumePending" : "ResumeComplete", thread, this)); // If this is a REMAP_COMPLETE patch, then dispatch the RemapComplete callback if (m_fTriggerType == REMAP_COMPLETE) @@ -8788,25 +8739,43 @@ TP_RESULT DebuggerEnCBreakpoint::TriggerPatch(DebuggerControllerPatch *patch, return TPR_IGNORE; } - _ASSERTE(patch->IsManagedPatch()); - - // Grab the MethodDesc for this function. - _ASSERTE(module != NULL); - - // GENERICS: @todo generics. This should be replaced by a similar loop - // over the DJIs for the DMI as in BindPatch up above. - MethodDesc *pFD = g_pEEInterface->FindLoadedMethodRefOrDef(module, md); + // Map the current native offset back to the IL offset in the old + // function. This will be mapped to the new native offset within + // ResumeInUpdatedFunction + CorDebugMappingResult map; + DWORD which; + SIZE_T currentIL = (SIZE_T)m_jitInfo->MapNativeOffsetToIL(patch->offset, &map, &which); - _ASSERTE(pFD != NULL); + // We only lay DebuggerEnCBreakpoints at sequence points + _ASSERTE(map == MAPPING_EXACT); + _ASSERTE(patch->IsManagedPatch()); - LOG((LF_ENC, LL_ALWAYS, - "DEnCBP::TP: in %s::%s\n", pFD->m_pszDebugClassName,pFD->m_pszDebugMethodName)); + Module *module = patch->key.module; + mdMethodDef md = patch->key.md; + LOG((LF_ENC, LL_INFO10000, + "DEnCBP::TP: methodDef=0x%08x, encVersion=%zx, IL offset=0x%zx\n", + md, m_jitInfo->m_encVersion, currentIL)); + patch->LogInstance(); // Grab the jit info for the original copy of the method, which is // what we are executing right now. - DebuggerJitInfo *pJitInfo = m_jitInfo; - _ASSERTE(pJitInfo); - _ASSERTE(pJitInfo->m_nativeCodeVersion.GetMethodDesc() == pFD); + DebuggerJitInfo* pJitInfo = m_jitInfo; + // Grab the MethodDesc for this function. + MethodDesc* pMD = pJitInfo->m_nativeCodeVersion.GetMethodDesc(); + + _ASSERTE(pJitInfo != NULL); + _ASSERTE(pMD != NULL); + LOG((LF_ENC, LL_INFO10000, + "DEnCBP::TP: DJI: %p pMD: %p (%s::%s)\n", pJitInfo, pMD, pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); + +#if defined(_DEBUG) + { + // Either the current method matches what we are executing or it is + // the typical definition for a generic method (i.e., typical). + MethodDesc* loadedMD = g_pEEInterface->FindLoadedMethodRefOrDef(module, md); + _ASSERTE(loadedMD == pMD || loadedMD->IsTypicalMethodDefinition()); + } +#endif // _DEBUG // Grab the context for this thread. This is the context that was // passed to COMPlusFrameHandler. @@ -8819,13 +8788,13 @@ TP_RESULT DebuggerEnCBreakpoint::TriggerPatch(DebuggerControllerPatch *patch, // Release the controller lock for the rest of this method CrstBase::UnsafeCrstInverseHolder inverseLock(&g_criticalSection); - // resumeIP is the native offset in the new version of the method the debugger wants + // resumeIL is the IL offset in the new version of the method the debugger wants // to resume to. We'll pass the address of this variable over to the right-side // and if it modifies the contents while we're stopped dispatching the RemapOpportunity, // then we know it wants a remap. // This form of side-channel communication seems like an error-prone workaround. Ideally the - // remap IP (if any) would just be returned in a response event. - SIZE_T resumeIP = (SIZE_T) -1; + // remap IL (if any) would just be returned in a response event. + SIZE_T resumeIL = (SIZE_T) -1; // Debugging code to enable a break after N RemapOpportunities #ifdef _DEBUG @@ -8842,29 +8811,29 @@ TP_RESULT DebuggerEnCBreakpoint::TriggerPatch(DebuggerControllerPatch *patch, } #endif - // Send an event to the RS to call the RemapOpportunity callback, passing the address of resumeIP. - // If the debugger responds with a call to RemapFunction, the supplied IP will be copied into resumeIP + // Send an event to the RS to call the RemapOpportunity callback, passing the address of resumeIL. + // If the debugger responds with a call to RemapFunction, the supplied IP will be copied into resumeIL // and we will know to update the context and resume the function at the new IP. Otherwise we just do // nothing and try again on next RemapFunction breakpoint - g_pDebugger->LockAndSendEnCRemapEvent(pJitInfo, currentIP, &resumeIP); + g_pDebugger->LockAndSendEnCRemapEvent(pJitInfo, currentIL, &resumeIL); LOG((LF_ENC, LL_ALWAYS, - "DEnCBP::TP: resume IL offset is 0x%x\n", resumeIP)); + "DEnCBP::TP: resume IL is %zx\n", resumeIL)); // Has the debugger requested a remap? - if (resumeIP != (SIZE_T) -1) + if (resumeIL != (SIZE_T) -1) { // This will jit the function, update the context, and resume execution at the new location. g_pEEInterface->ResumeInUpdatedFunction(pModule, - pFD, + pMD, (void*)pJitInfo, - resumeIP, + resumeIL, pContext); _ASSERTE(!"Returned from ResumeInUpdatedFunction!"); } - LOG((LF_CORDB, LL_ALWAYS, "DEnCB::TP: We've returned from ResumeInUpd" - "atedFunction, we're going to skip the EnC patch ####\n")); + LOG((LF_CORDB, LL_ALWAYS, "DEnCB::TP: We've returned from ResumeInUpdatedFunction" + "we're going to skip the EnC patchId:0x%zx\n", patch->patchId)); // We're returning then we'll have to re-get this lock. Be careful that we haven't kept any controller/patches // in the caller. They can move when we unlock, so when we release the lock and reget it here, things might have @@ -8886,7 +8855,7 @@ TP_RESULT DebuggerEnCBreakpoint::HandleRemapComplete(DebuggerControllerPatch *pa Thread *thread, TRIGGER_WHY tyWhy) { - LOG((LF_ENC, LL_ALWAYS, "DEnCBP::HRC: HandleRemapComplete\n")); + LOG((LF_ENC, LL_ALWAYS, "DEnCBP::HRC: HandleRemapComplete: %p\n", this)); // Debugging code to enable a break after N RemapCompletes #ifdef _DEBUG @@ -8903,13 +8872,19 @@ TP_RESULT DebuggerEnCBreakpoint::HandleRemapComplete(DebuggerControllerPatch *pa #endif _ASSERTE(HasLock()); - bool fApplied = m_jitInfo->m_encBreakpointsApplied; + MethodDesc* pMD = m_jitInfo->m_nativeCodeVersion.GetMethodDesc(); + _ASSERTE(pMD != NULL); + LOG((LF_ENC, LL_INFO10000, "DEnCBP::HRC: Applied: %s, pMD: %p (%s::%s)\n", + (fApplied ? "true" : "false"), pMD, pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); + // Need to delete this before unlock below so if any other thread come in after the unlock // they won't handle this patch. Delete(); - // We just deleted ourselves. Can't access anything any instances after this point. + // + // NOTE: We just deleted ourselves. Can't access anything any instances after this point. + // // if have somehow updated this function before we resume into it then just bail if (fApplied) @@ -8918,9 +8893,14 @@ TP_RESULT DebuggerEnCBreakpoint::HandleRemapComplete(DebuggerControllerPatch *pa return TPR_IGNORE_AND_STOP; } - // GENERICS: @todo generics. This should be replaced by a similar loop - // over the DJIs for the DMI as in BindPatch up above. - MethodDesc *pFD = g_pEEInterface->FindLoadedMethodRefOrDef(patch->key.module, patch->key.md); +#if defined(_DEBUG) + { + // Either the current method matches what we are executing or it is + // the typical definition for a generic method (i.e., typical). + MethodDesc* loadedMD = g_pEEInterface->FindLoadedMethodRefOrDef(patch->key.module, patch->key.md); + _ASSERTE(loadedMD == pMD || loadedMD->IsTypicalMethodDefinition()); + } +#endif // _DEBUG LOG((LF_ENC, LL_ALWAYS, "DEnCBP::HRC: unlocking controller\n")); @@ -8929,7 +8909,7 @@ TP_RESULT DebuggerEnCBreakpoint::HandleRemapComplete(DebuggerControllerPatch *pa LOG((LF_ENC, LL_ALWAYS, "DEnCBP::HRC: sending RemapCompleteEvent\n")); - g_pDebugger->LockAndSendEnCRemapCompleteEvent(pFD); + g_pDebugger->LockAndSendEnCRemapCompleteEvent(pMD); // We're returning then we'll have to re-get this lock. Be careful that we haven't kept any controller/patches // in the caller. They can move when we unlock, so when we release the lock and reget it here, things might have diff --git a/src/coreclr/debug/ee/controller.h b/src/coreclr/debug/ee/controller.h index 27666a6eed6d8b..0b8a32927c326d 100644 --- a/src/coreclr/debug/ee/controller.h +++ b/src/coreclr/debug/ee/controller.h @@ -331,23 +331,23 @@ struct DebuggerFunctionKey1 typedef DebuggerFunctionKey1 UNALIGNED DebuggerFunctionKey; -// IL Master: Breakpoints on IL code may need to be applied to multiple +// IL Primary: Breakpoints on IL code may need to be applied to multiple // copies of code. Historically generics was the only way IL code was JITTed // multiple times but more recently the CodeVersionManager and tiered compilation // provide more open-ended mechanisms to have multiple native code bodies derived // from a single IL method body. -// The "master" is a patch we keep to record the IL offset or native offset, and -// is used to create new "slave"patches. For native offsets only offset 0 is allowed +// The "primary" is a patch we keep to record the IL offset or native offset, and +// is used to create new "replica" patches. For native offsets only offset 0 is allowed // because that is the only one that we think would have a consistent semantic // meaning across different code bodies. // There can also be multiple IL bodies for the same method given EnC or ReJIT. -// A given master breakpoint is tightly bound to one particular IL body determined +// A given primary breakpoint is tightly bound to one particular IL body determined // by encVersion. ReJIT + breakpoints isn't currently supported. // // -// IL Slave: The slaves created from Master patches. If the master used an IL offset -// then the slave also initially has an IL offset that will later become a native offset. -// If the master uses a native offset (0) then the slave will also have a native offset (0). +// IL Replica: The replicas created from Primary patches. If the primary used an IL offset +// then the replica also initially has an IL offset that will later become a native offset. +// If the primary uses a native offset (0) then the replica will also have a native offset (0). // These patches always resolve to addresses in jitted code. // // @@ -360,7 +360,7 @@ typedef DebuggerFunctionKey1 UNALIGNED DebuggerFunctionKey; // // NativeUnmanaged: A patch applied to any kind of native code. -enum DebuggerPatchKind { PATCH_KIND_IL_MASTER, PATCH_KIND_IL_SLAVE, PATCH_KIND_NATIVE_MANAGED, PATCH_KIND_NATIVE_UNMANAGED }; +enum DebuggerPatchKind { PATCH_KIND_IL_PRIMARY, PATCH_KIND_IL_REPLICA, PATCH_KIND_NATIVE_MANAGED, PATCH_KIND_NATIVE_UNMANAGED }; // struct DebuggerControllerPatch: An entry in the patch (hash) table, // this should contain all the info that's needed over the course of a @@ -369,7 +369,8 @@ enum DebuggerPatchKind { PATCH_KIND_IL_MASTER, PATCH_KIND_IL_SLAVE, PATCH_KIND_N // FREEHASHENTRY entry: Three ULONGs, this is required // by the underlying hashtable implementation // DWORD opcode: A nonzero opcode && address field means that -// the patch has been applied to something. +// the patch has been applied to something. This may not be a full +// opcode, it is possible it is a partial opcode. // A patch with a zero'd opcode field means that the patch isn't // actually tracking a valid break opcode. See DebuggerPatchTable // for more details. @@ -405,7 +406,7 @@ enum DebuggerPatchKind { PATCH_KIND_IL_MASTER, PATCH_KIND_IL_SLAVE, PATCH_KIND_N // the method (and version) that this patch is applied to. This field may // also have the value DebuggerJitInfo::DMI_VERSION_INVALID -// SIZE_T pid: Within a given patch table, all patches have a +// SIZE_T patchId: Within a given patch table, all patches have a // semi-unique ID. There should be one and only 1 patch for a given // {pid,nVersion} tuple, thus ensuring that we don't duplicate // patches from multiple, previous versions. @@ -427,40 +428,41 @@ struct DebuggerControllerPatch SIZE_T offset; PTR_CORDB_ADDRESS_TYPE address; FramePointer fp; - PRD_TYPE opcode; //this name will probably change because it is a misnomer + PRD_TYPE opcode; // See description above. BOOL fSaveOpcode; - PRD_TYPE opcodeSaved;//also a misnomer + PRD_TYPE opcodeSaved; BOOL offsetIsIL; TraceDestination trace; - MethodDesc* pMethodDescFilter; // used for IL Master patches that should only bind to jitted + MethodDesc* pMethodDescFilter; // used for IL Primary patches that should only bind to jitted // code versions for a single generic instantiation private: + DebuggerPatchKind kind; int refCount; union { - SIZE_T encVersion; // used for Master patches, to record which EnC version this Master applies to - DebuggerJitInfo *dji; // used for Slave and native patches, though only when tracking JIT Info + SIZE_T encVersion; // used for Primary patches, to record which EnC version this Primary applies to + DebuggerJitInfo *dji; // used for Replica and native patches, though only when tracking JIT Info }; #ifndef FEATURE_EMULATE_SINGLESTEP // this is shared among all the skippers for this controller. see the comments // right before the definition of SharedPatchBypassBuffer for lifetime info. SharedPatchBypassBuffer* m_pSharedPatchBypassBuffer; -#endif // TARGET_ARM +#endif // !FEATURE_EMULATE_SINGLESTEP public: - SIZE_T pid; + SIZE_T patchId; AppDomain *pAppDomain; BOOL IsNativePatch(); BOOL IsManagedPatch(); - BOOL IsILMasterPatch(); - BOOL IsILSlavePatch(); + BOOL IsILPrimaryPatch(); + BOOL IsILReplicaPatch(); DebuggerPatchKind GetKind(); // A patch has DJI if it was created with it or if it has been mapped to a // function that has been jitted while JIT tracking was on. It does not - // necessarily mean the patch is bound. ILMaster patches never have DJIs. + // necessarily mean the patch is bound. ILPrimary patches never have DJIs. // Patches will never have DJIs if we are not tracking JIT information. // // Patches can also be unbound, e.g. in UnbindFunctionPatches. Any DJI gets cleared @@ -469,27 +471,30 @@ struct DebuggerControllerPatch // we don't skip the patch when we get new code. BOOL HasDJI() { - return (!IsILMasterPatch() && dji != NULL); + return (!IsILPrimaryPatch() && dji != NULL); } DebuggerJitInfo *GetDJI() { - _ASSERTE(!IsILMasterPatch()); + _ASSERTE(!IsILPrimaryPatch()); return dji; } + // Determine if the patch is related to EnC remap logic. + BOOL IsEnCRemapPatch(); + // These tell us which EnC version a patch relates to. They are used // to determine if we are mapping a patch to a new version. // BOOL HasEnCVersion() { - return (IsILMasterPatch() || HasDJI()); + return (IsILPrimaryPatch() || HasDJI()); } SIZE_T GetEnCVersion() { _ASSERTE(HasEnCVersion()); - return (IsILMasterPatch() ? encVersion : (HasDJI() ? GetDJI()->m_encVersion : CorDB_DEFAULT_ENC_FUNCTION_VERSION)); + return (IsILPrimaryPatch() ? encVersion : (HasDJI() ? GetDJI()->m_encVersion : CorDB_DEFAULT_ENC_FUNCTION_VERSION)); } // We set the DJI explicitly after mapping a patch @@ -498,7 +503,7 @@ struct DebuggerControllerPatch // should not skip the patch. void SetDJI(DebuggerJitInfo *newDJI) { - _ASSERTE(!IsILMasterPatch()); + _ASSERTE(!IsILPrimaryPatch()); dji = newDJI; } @@ -516,8 +521,8 @@ struct DebuggerControllerPatch return FALSE; } - // IL Master patches are never bound. - _ASSERTE( !IsILMasterPatch() ); + // IL Primary patches are never bound. + _ASSERTE( !IsILPrimaryPatch() ); return TRUE; } @@ -562,10 +567,29 @@ struct DebuggerControllerPatch if (m_pSharedPatchBypassBuffer != NULL) m_pSharedPatchBypassBuffer->Release(); } -#endif // TARGET_ARM +#endif // !FEATURE_EMULATE_SINGLESTEP -private: - DebuggerPatchKind kind; + void LogInstance() + { + LOG((LF_CORDB, LL_INFO10000, " DCP: %p\n" + " patchId: 0x%zx\n" + " offset: 0x%zx\n" + " address: %p\n" + " offsetIsIL: %s\n" + " refCount: %d\n" + " kind: %d\n" + " IsBound: %s\n" + " IsNativePatch: %s\n" + " IsManagedPatch: %s\n" + " IsILPrimaryPatch: %s\n" + " IsILReplicaPatch: %s\n", + this, patchId, offset, address, (offsetIsIL ? "true" : "false"), refCount, GetKind(), + (IsBound() ? "true" : "false"), + (IsNativePatch() ? "true" : "false"), + (IsManagedPatch() ? "true" : "false"), + (IsILPrimaryPatch() ? "true" : "false"), + (IsILReplicaPatch() ? "true" : "false"))); + } }; typedef DPTR(DebuggerControllerPatch) PTR_DebuggerControllerPatch; @@ -625,7 +649,7 @@ class DebuggerPatchTable : private CHashTableAndData private: //incremented so that we can get DPT-wide unique PIDs. // pid = Patch ID. - SIZE_T m_pid; + SIZE_T m_patchId; // Given a patch, retrieves the correct key. The return value of this function is passed to Cmp(), Find(), etc. SIZE_T Key(DebuggerControllerPatch *patch) { @@ -700,8 +724,8 @@ class DebuggerPatchTable : private CHashTableAndData //Public Members public: enum { - DCP_PID_INVALID, - DCP_PID_FIRST_VALID, + DCP_PATCHID_INVALID, + DCP_PATCHID_FIRST_VALID, }; #ifndef DACCESS_COMPILE @@ -712,7 +736,7 @@ class DebuggerPatchTable : private CHashTableAndData { WRAPPER_NO_CONTRACT; - m_pid = DCP_PID_FIRST_VALID; + m_patchId = DCP_PATCHID_FIRST_VALID; SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE; return NewInit(17, sizeof(DebuggerControllerPatch), 101); @@ -722,7 +746,7 @@ class DebuggerPatchTable : private CHashTableAndData // GetNextPatch from this patch) are either sorted or NULL, take the given // patch (which should be the first patch in the chain). This // is called by AddPatch to make sure that the order of the - // patches is what we want for things like E&C, DePatchSkips,etc. + // patches is what we want for things like EnC, DePatchSkips,etc. void SortPatchIntoPatchList(DebuggerControllerPatch **ppPatch); void SpliceOutOfList(DebuggerControllerPatch *patch); @@ -742,7 +766,7 @@ class DebuggerPatchTable : private CHashTableAndData DebuggerPatchKind kind, FramePointer fp, AppDomain *pAppDomain, - SIZE_T masterEnCVersion, + SIZE_T primaryEnCVersion, DebuggerJitInfo *dji); DebuggerControllerPatch *AddPatchForAddress(DebuggerController *controller, @@ -753,7 +777,7 @@ class DebuggerPatchTable : private CHashTableAndData FramePointer fp, AppDomain *pAppDomain, DebuggerJitInfo *dji = NULL, - SIZE_T pid = DCP_PID_INVALID, + SIZE_T patchId = DCP_PATCHID_INVALID, TraceType traceType = DPT_DEFAULT_TRACE_TYPE); // Set the native address for this patch. @@ -859,21 +883,17 @@ class DebuggerPatchTable : private CHashTableAndData return ItemIndex(p); } -#ifdef _DEBUG_PATCH_TABLE +#ifdef _DEBUG public: // DEBUG An internal debugging routine, it iterates // through the hashtable, stopping at every - // single entry, no matter what it's state. For this to - // compile, you're going to have to add friend status - // of this class to CHashTableAndData in - // to $\Com99\Src\inc\UtilCode.h + // single entry, no matter what it's state. void CheckPatchTable(); -#endif // _DEBUG_PATCH_TABLE +#endif // _DEBUG // Count how many patches are in the table. // Use for asserts int GetNumberOfPatches(); - }; typedef VPTR(class DebuggerPatchTable) PTR_DebuggerPatchTable; @@ -909,8 +929,6 @@ enum DEBUGGER_CONTROLLER_TYPE { DEBUGGER_CONTROLLER_THREAD_STARTER, DEBUGGER_CONTROLLER_ENC, - DEBUGGER_CONTROLLER_ENC_PATCH_TO_SKIP, // At any one address, - // There can be only one! DEBUGGER_CONTROLLER_PATCH_SKIP, DEBUGGER_CONTROLLER_BREAKPOINT, DEBUGGER_CONTROLLER_STEPPER, @@ -1007,8 +1025,7 @@ inline void VerifyExecutableAddress(const BYTE* address) // DebuggerController: DebuggerController serves // both as a static class that dispatches exceptions coming from the -// EE, and as an abstract base class for the five classes that derrive -// from it. +// EE, and as an abstract base class for other debugger concepts. class DebuggerController { VPTR_BASE_CONCRETE_VTABLE_CLASS(DebuggerController); @@ -1084,9 +1101,6 @@ class DebuggerController static bool ModuleHasPatches( Module* pModule ); #if EnC_SUPPORTED - static DebuggerControllerPatch *IsXXXPatched(const BYTE *eip, - DEBUGGER_CONTROLLER_TYPE dct); - static DebuggerControllerPatch *GetEnCPatch(const BYTE *address); #endif //EnC_SUPPORTED @@ -1129,8 +1143,8 @@ class DebuggerController // destroys the thread before it fires, then we'd still have an active DTS. static void CancelOutstandingThreadStarter(Thread * pThread); - static void AddRef(DebuggerControllerPatch *patch); - static void Release(DebuggerControllerPatch *patch); + static void AddRefPatch(DebuggerControllerPatch *patch); + static void ReleasePatch(DebuggerControllerPatch *patch); private: @@ -1177,7 +1191,6 @@ class DebuggerController CORDB_ADDRESS_TYPE *startAddr); static bool ApplyPatch(DebuggerControllerPatch *patch); static bool UnapplyPatch(DebuggerControllerPatch *patch); - static void UnapplyPatchAt(DebuggerControllerPatch *patch, CORDB_ADDRESS_TYPE *address); static bool IsPatched(CORDB_ADDRESS_TYPE *address, BOOL native); static void ActivatePatch(DebuggerControllerPatch *patch); @@ -1238,17 +1251,6 @@ class DebuggerController Thread *GetThread() { return m_thread; } - // This one should be made private - BOOL AddBindAndActivateILSlavePatch(DebuggerControllerPatch *master, - DebuggerJitInfo *dji); - - BOOL AddILPatch(AppDomain * pAppDomain, Module *module, - mdMethodDef md, - MethodDesc* pMethodFilter, - SIZE_T encVersion, // what encVersion does this apply to? - SIZE_T offset, - BOOL offsetIsIL); - // The next two are very similar. Both work on offsets, // but one takes a "patch id". I don't think these are really needed: the // controller itself can act as the id of the patch. @@ -1314,17 +1316,27 @@ class DebuggerController void Enqueue(); void Dequeue(); - private: + protected: // Helper function that is called on each virtual trace call target to set a trace patch static void PatchTargetVisitor(TADDR pVirtualTraceCallTarget, VOID* pUserData); - DebuggerControllerPatch *AddILMasterPatch(Module *module, + DebuggerControllerPatch *AddILPrimaryPatch(Module *module, mdMethodDef md, MethodDesc *pMethodDescFilter, SIZE_T offset, BOOL offsetIsIL, SIZE_T encVersion); + BOOL AddBindAndActivateILReplicaPatch(DebuggerControllerPatch *primary, + DebuggerJitInfo *dji); + + BOOL AddILPatch(AppDomain * pAppDomain, Module *module, + mdMethodDef md, + MethodDesc* pMethodFilter, + SIZE_T encVersion, // what encVersion does this apply to? + SIZE_T offset, + BOOL offsetIsIL); + BOOL AddBindAndActivatePatchForMethodDesc(MethodDesc *fd, DebuggerJitInfo *dji, SIZE_T nativeOffset, @@ -1332,7 +1344,6 @@ class DebuggerController FramePointer fp, AppDomain *pAppDomain); - protected: // @@ -1482,7 +1493,7 @@ class DebuggerPatchSkip : public DebuggerController BYTE* patchBypass = m_pSharedPatchBypassBuffer->PatchBypass; return (CORDB_ADDRESS_TYPE *)patchBypass; } -#endif // TARGET_ARM +#endif // !FEATURE_EMULATE_SINGLESTEP }; /* ------------------------------------------------------------------------- * @@ -1911,25 +1922,25 @@ class DebuggerContinuableExceptionBreakpoint : public DebuggerController // DebuggerEnCBreakpoint - used by edit and continue to support remapping // // When a method is updated, we make no immediate attempt to remap any existing execution -// of the old method. Instead we mine the old method with EnC breakpoints, and prompt the -// debugger whenever one is hit, giving it the opportunity to request a remap to the +// of the previous version. Instead we set EnC breakpoints in the previous version, and +// prompt the debugger whenever one is hit, giving it the opportunity to request a remap to the // latest version of the method. // // Over long debugging sessions which make many edits to large methods, we can create // a large number of these breakpoints. We currently make no attempt to reclaim the -// code or patch overhead for old methods. Ideally we'd be able to detect when there are -// no outstanding references to the old method version and clean up after it. At the -// very least, we could remove all but the first patch when there are no outstanding +// code or patch overhead for previous versions. Ideally we'd be able to detect when there are +// no outstanding references to older method versions and clean up. At the very least, we +// could remove all but the first patch when there are no outstanding // frames for a specific version of an edited method. // -class DebuggerEnCBreakpoint : public DebuggerController +class DebuggerEnCBreakpoint final : public DebuggerController { public: // We have two types of EnC breakpoints. The first is the one we - // sprinkle through old code to let us know when execution is occurring - // in a function that now has a new version. The second is when we've - // actually resumed excecution into a remapped function and we need - // to then notify the debugger. + // sprinkle through previous code versions to let us know when execution + // is occurring in a function that now has a new version. + // The second is when we've actually resumed excecution into a remapped + // function and we need to then notify the debugger. enum TriggerType {REMAP_PENDING, REMAP_COMPLETE}; // Create and activate an EnC breakpoint at the specified native offset @@ -1938,13 +1949,13 @@ class DebuggerEnCBreakpoint : public DebuggerController TriggerType fTriggerType, AppDomain *pAppDomain); - virtual DEBUGGER_CONTROLLER_TYPE GetDCType( void ) + virtual DEBUGGER_CONTROLLER_TYPE GetDCType( void ) override { return DEBUGGER_CONTROLLER_ENC; } private: TP_RESULT TriggerPatch(DebuggerControllerPatch *patch, Thread *thread, - TRIGGER_WHY tyWhy); + TRIGGER_WHY tyWhy) override; TP_RESULT HandleRemapComplete(DebuggerControllerPatch *patch, Thread *thread, diff --git a/src/coreclr/debug/ee/controller.inl b/src/coreclr/debug/ee/controller.inl index 059e9b255ece9e..3f660d8a42feac 100644 --- a/src/coreclr/debug/ee/controller.inl +++ b/src/coreclr/debug/ee/controller.inl @@ -27,29 +27,32 @@ inline DebuggerPatchKind DebuggerControllerPatch::GetKind() { return kind; } -inline BOOL DebuggerControllerPatch::IsILMasterPatch() + +inline BOOL DebuggerControllerPatch::IsILPrimaryPatch() { LIMITED_METHOD_CONTRACT; - - return (kind == PATCH_KIND_IL_MASTER); + return (kind == PATCH_KIND_IL_PRIMARY); } -inline BOOL DebuggerControllerPatch::IsILSlavePatch() +inline BOOL DebuggerControllerPatch::IsILReplicaPatch() { LIMITED_METHOD_CONTRACT; - - return (kind == PATCH_KIND_IL_SLAVE); + return (kind == PATCH_KIND_IL_REPLICA); } inline BOOL DebuggerControllerPatch::IsManagedPatch() { - return (IsILMasterPatch() || IsILSlavePatch() || kind == PATCH_KIND_NATIVE_MANAGED); - + return (IsILPrimaryPatch() || IsILReplicaPatch() || kind == PATCH_KIND_NATIVE_MANAGED); } + inline BOOL DebuggerControllerPatch::IsNativePatch() { - return (kind == PATCH_KIND_NATIVE_MANAGED || kind == PATCH_KIND_NATIVE_UNMANAGED || (IsILSlavePatch() && !offsetIsIL)); + return (kind == PATCH_KIND_NATIVE_MANAGED || kind == PATCH_KIND_NATIVE_UNMANAGED || (IsILReplicaPatch() && !offsetIsIL)); +} +inline BOOL DebuggerControllerPatch::IsEnCRemapPatch() +{ + return (controller->GetDCType() == DEBUGGER_CONTROLLER_ENC); } #endif // CONTROLLER_INL_ diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 7603524319670a..aa433342287331 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -2465,10 +2465,6 @@ DebuggerMethodInfo *Debugger::CreateMethodInfo(Module *module, mdMethodDef md) } - - - - /****************************************************************************** // void Debugger::JITComplete(): JITComplete is called by // the jit interface when the JIT completes, successfully or not. @@ -2496,9 +2492,8 @@ void Debugger::JITComplete(NativeCodeVersion nativeCodeVersion, TADDR newAddress MethodDesc* fd = nativeCodeVersion.GetMethodDesc(); - LOG((LF_CORDB, LL_INFO100000, "D::JITComplete: md:0x%p (%s::%s), address:0x%p.\n", - fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, - newAddress)); + LOG((LF_CORDB, LL_INFO100000, "D::JITComplete: md:%p (%s::%s), address:%p.\n", + fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, newAddress)); #ifdef TARGET_ARM newAddress = newAddress|THUMB_CODE; @@ -2521,7 +2516,7 @@ void Debugger::JITComplete(NativeCodeVersion nativeCodeVersion, TADDR newAddress goto Exit; } BOOL jiWasCreated = FALSE; - DebuggerJitInfo * ji = dmi->CreateInitAndAddJitInfo(nativeCodeVersion, newAddress, &jiWasCreated); + DebuggerJitInfo * dji = dmi->CreateInitAndAddJitInfo(nativeCodeVersion, newAddress, &jiWasCreated); if (!jiWasCreated) { // we've already been notified about this code, no work remains. @@ -2529,19 +2524,17 @@ void Debugger::JITComplete(NativeCodeVersion nativeCodeVersion, TADDR newAddress // method on two threads. When this occurs both threads will // return the same code pointer and this callback is invoked // multiple times. - LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:0x%p (%s::%s), address:0x%p. Already created\n", - fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, - newAddress)); + LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:%p (%s::%s), address:%p. Already created\n", + fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, newAddress)); goto Exit; } - LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:0x%p (%s::%s), address:0x%p. Created ji:0x%p\n", - fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, - newAddress, ji)); + LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:0x%p (%s::%s), address:%p. Created dji:%p\n", + fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, newAddress, dji)); // Bind any IL patches to the newly jitted native code. HRESULT hr; - hr = MapAndBindFunctionPatches(ji, fd, (CORDB_ADDRESS_TYPE *)newAddress); + hr = MapAndBindFunctionPatches(dji, fd, (CORDB_ADDRESS_TYPE *)newAddress); _ASSERTE(SUCCEEDED(hr)); } @@ -2639,7 +2632,7 @@ DebuggerJitInfo *Debugger::GetJitInfoFromAddr(TADDR addr) // Get a DJI for a Native MD (MD for a native function). // In the EnC scenario, the MethodDesc refers to the most recent method. // This is very dangerous since there may be multiple versions alive at the same time. -// This will give back the wrong DJI if we're lookikng for a stale method desc. +// This will give back the wrong DJI if we're looking for a stale method desc. // @todo - can a caller possibly use this correctly? DebuggerJitInfo *Debugger::GetLatestJitInfoFromMethodDesc(MethodDesc * pMethodDesc) { @@ -4450,7 +4443,7 @@ HRESULT Debugger::GetVariablesFromOffset(MethodDesc *pMD, memset( rgVal1, 0, sizeof(SIZE_T)*uRgValSize); memset( rgVal2, 0, sizeof(SIZE_T)*uRgValSize); - LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::GVFO: %s::%s, infoCount:0x%x, from:0x%p\n", + LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::GVFO: %s::%s, infoCount:0x%x, from: %p\n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, varNativeInfoCount, @@ -4475,9 +4468,7 @@ HRESULT Debugger::GetVariablesFromOffset(MethodDesc *pMD, hr = S_OK; - LOG((LF_CORDB|LF_ENC, - LL_INFO10000, - "D::GVFO rgVal1 0x%X, rgVal2 0x%X\n", + LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::GVFO rgVal1 %p, rgVal2 %p\n", rgVal1, rgVal2)); @@ -4508,7 +4499,7 @@ HRESULT Debugger::GetVariablesFromOffset(MethodDesc *pMD, (varNativeInfo[i].endOffset < offsetFrom) || (varNativeInfo[i].loc.vlType == ICorDebugInfo::VLT_INVALID)) { - LOG((LF_CORDB|LF_ENC,LL_INFO10000, "D::GVFO [%2d] invalid\n", i)); + LOG((LF_CORDB|LF_ENC,LL_INFO10000, "D::GVFO [%2u] invalid\n", i)); continue; } @@ -4530,7 +4521,7 @@ HRESULT Debugger::GetVariablesFromOffset(MethodDesc *pMD, BIT64_ARG(cbClass)); LOG((LF_CORDB|LF_ENC,LL_INFO10000, - "D::GVFO [%2d] varnum %d, nonVC type %x, addr %8.8x: %8.8x;%8.8x\n", + "D::GVFO [%2u] varnum %u, nonVC type %x, addr %p: %zx;%zx\n", i, varNativeInfo[i].varNumber, varNativeInfo[i].loc.vlType, @@ -4565,7 +4556,7 @@ HRESULT Debugger::GetVariablesFromOffset(MethodDesc *pMD, cValueClasses++; #ifdef _DEBUG LOG((LF_CORDB|LF_ENC,LL_INFO10000, - "D::GVFO [%2d] varnum %d, VC len %d, addr %8.8x, sample: %8.8x%8.8x\n", + "D::GVFO [%2u] varnum %d, VC len %d, addr %p, sample: %8.8x%8.8x\n", i, varNativeInfo[i].varNumber, cbClass, @@ -4574,7 +4565,7 @@ HRESULT Debugger::GetVariablesFromOffset(MethodDesc *pMD, #endif } - LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::GVFO: returning %8.8x\n", hr)); + LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::GVFO: returning 0x%x\n", hr)); if (SUCCEEDED(hr)) { (*rgpVCs) = rgpValueClasses; @@ -4734,15 +4725,15 @@ HRESULT Debugger::SetVariablesAtOffset(MethodDesc *pMD, return hr; } -BOOL IsDuplicatePatch(SIZE_T *rgEntries, - ULONG cEntries, - SIZE_T Entry ) +static BOOL IsDuplicatePatch(SIZE_T_UNORDERED_ARRAY* unorderedArray, SIZE_T Entry) { LIMITED_METHOD_CONTRACT; - for( ULONG i = 0; i < cEntries;i++) + SIZE_T* entries = unorderedArray->Table(); + ULONG count = unorderedArray->Count(); + for (ULONG i = 0; i < count; ++i) { - if (rgEntries[i] == Entry) + if (entries[i] == Entry) return TRUE; } return FALSE; @@ -4761,7 +4752,6 @@ BOOL IsDuplicatePatch(SIZE_T *rgEntries, // // Parameters: // djiNew - this is the DJI created in D::JitComplete. -// If djiNew == NULL iff we aren't tracking debug-info. // fd - the method desc that we're binding too. // addrOfCode - address of the native blob of code we just jitted // @@ -4780,7 +4770,8 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, { THROWS; CALLED_IN_DEBUGGERDATALOCK_HOLDER_SCOPE_MAY_GC_TRIGGERS_CONTRACT; - PRECONDITION(!djiNew || djiNew->m_nativeCodeVersion.GetMethodDesc() == fd); + PRECONDITION(djiNew != NULL); + PRECONDITION(djiNew->m_nativeCodeVersion.GetMethodDesc() == fd); } CONTRACTL_END; @@ -4791,8 +4782,8 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, Module *pModule = g_pEEInterface->MethodDescGetModule(fd); mdMethodDef md = fd->GetMemberDef(); - LOG((LF_CORDB,LL_INFO10000,"D::MABFP: All BPs will be mapped to " - "Ver:0x%04x (DJI:0x%p)\n", djiNew?djiNew->m_methodInfo->GetCurrentEnCVersion():0, djiNew)); + LOG((LF_CORDB,LL_INFO10000,"D::MABFP: All BPs will be mapped to encVersion: %zx (DJI:%p)\n", + djiNew->m_methodInfo->GetCurrentEnCVersion(), djiNew)); // We need to traverse the patch list while under the controller lock (small lock). // But we can only send BreakpointSetErrors while under the debugger lock (big lock). @@ -4800,7 +4791,6 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, // and then send the whole list when under the big lock. PATCH_UNORDERED_ARRAY listUnbindablePatches; - // First lock the patch table so it doesn't move while we're // examining it. LOG((LF_CORDB,LL_INFO10000, "D::MABFP: About to lock patch table\n")); @@ -4815,15 +4805,14 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, dcp != NULL; dcp = pPatchTable->GetNextPatch( &hf )) { - - LOG((LF_CORDB, LL_INFO10000, "D::MABFP: got patch 0x%p\n", dcp)); + LOG((LF_CORDB, LL_INFO10000, "D::MABFP: Got patch %p, patchId:0x%zx\n", dcp, dcp->patchId)); // Only copy over breakpoints that are in this method // Ideally we'd have a per-method index since there can be a lot of patches // when the EnCBreakpoint patches are included. if (dcp->key.module != pModule || dcp->key.md != md) { - LOG((LF_CORDB, LL_INFO10000, "Patch not in this method\n")); + LOG((LF_CORDB, LL_INFO10000, "D::MABFP: Patch not in this method\n")); continue; } @@ -4831,16 +4820,15 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, // elsewhere. if(dcp->pMethodDescFilter != NULL && dcp->pMethodDescFilter != djiNew->m_nativeCodeVersion.GetMethodDesc()) { - LOG((LF_CORDB, LL_INFO10000, "Patch not in this generic instance, filter 0x%p\n", dcp->pMethodDescFilter)); + LOG((LF_CORDB, LL_INFO10000, "D::MABFP: Patch not in this generic instance, filter %p\n", dcp->pMethodDescFilter)); continue; } - - // Do not copy over slave breakpoint patches. Instead place a new slave - // based off the master. - if (dcp->IsILSlavePatch()) + // Do not copy over replica breakpoint patches. Instead place a new replica + // based off the primary. + if (dcp->IsILReplicaPatch()) { - LOG((LF_CORDB, LL_INFO10000, "Not copying over slave breakpoint patch\n")); + LOG((LF_CORDB, LL_INFO10000, "D::MABFP: Not copying over replica breakpoint patch\n")); continue; } @@ -4848,16 +4836,17 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, // Eg. It may be bound to a different generic method instantiation. if (dcp->IsBound()) { - LOG((LF_CORDB, LL_INFO10000, "Skipping already bound patch\n")); + LOG((LF_CORDB, LL_INFO10000, "D::MABFP: Skipping already bound patch\n")); continue; } - // Only apply breakpoint patches that are for this version. - // If the patch doesn't have a particular EnCVersion available from its data then + // Only apply breakpoint and EnC remap patches that are for this version. + // If the patches doesn't have a particular EnCVersion available from its data then // we're (probably) not tracking JIT info. - if (dcp->IsBreakpointPatch() && dcp->HasEnCVersion() && djiNew && dcp->GetEnCVersion() != djiNew->m_encVersion) + if ((dcp->IsBreakpointPatch() || dcp->IsEnCRemapPatch()) + && dcp->HasEnCVersion() && dcp->GetEnCVersion() != djiNew->m_encVersion) { - LOG((LF_CORDB, LL_INFO10000, "Not applying breakpoint patch to new version\n")); + LOG((LF_CORDB, LL_INFO10000, "Not applying breakpoint or EnC remap patch to new version\n")); continue; } @@ -4867,98 +4856,61 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, // This is to signal that we should not skip here. // under exactly what scenarios (EnC, code pitching etc.) will this apply?... // can't we be a little clearer about why we don't want to bind the patch in this arcane situation? - if (dcp->HasDJI() && !dcp->IsBreakpointPatch() && !dcp->IsStepperPatch()) + if (dcp->HasDJI() && !dcp->IsBreakpointPatch() && !dcp->IsStepperPatch()) { - LOG((LF_CORDB, LL_INFO10000, "Neither stepper nor BP but we have valid a DJI (i.e. the DJI hasn't been deleted as part of the Unbind/MovedCode/Rebind mess)! - getting next patch!\n")); + LOG((LF_CORDB, LL_INFO10000, "D::MABFP: Neither stepper nor BP but we have valid a DJI (i.e. the DJI hasn't been deleted as part of the Unbind/MovedCode/Rebind mess)! - getting next patch!\n")); continue; } - // Now check if we're tracking JIT info or not - if (djiNew == NULL) - { - // This means we put a patch in a method w/ no debug info. - _ASSERTE(dcp->IsBreakpointPatch() || - dcp->IsStepperPatch() || - dcp->controller->GetDCType() == DEBUGGER_CONTROLLER_THREAD_STARTER); - - // W/o Debug-info, We can only patch native offsets, and only at the start of the method (native offset 0). - // Why can't we patch other native offsets?? - // Maybe b/c we don't know if we're patching - // in the middle of an instruction. Though that's not a - // strict requirement. - // We can't even do a IL-offset 0 because that's after the prolog and w/o the debug-info, - // we don't know where the prolog ends. - // Failing this assert is arguably an API misusage - the debugger should have enabled - // jit-tracking if they wanted to put bps at offsets other than native:0. - if (dcp->IsNativePatch() && (dcp->offset == 0)) - { - DebuggerController::g_patches->BindPatch(dcp, addrOfCode); - DebuggerController::ActivatePatch(dcp); - } - else - { - // IF a debugger calls EnableJitDebugging(true, ...) in the module-load callback, - // we should never get here. - *(listUnbindablePatches.AppendThrowing()) = dcp; - } + pidInCaseTableMoves = dcp->patchId; + // If we've already mapped this one to the current version, + // don't map it again. + LOG((LF_CORDB,LL_INFO10000,"D::MABFP: Checking if 0x%zx is a dup... ", + pidInCaseTableMoves)); + + if ( IsDuplicatePatch(GetBPMappingDuplicates(), pidInCaseTableMoves) ) + { + LOG((LF_CORDB,LL_INFO10000,"it is!\n")); + continue; } - else + LOG((LF_CORDB,LL_INFO10000,"nope, applying.\n")); + dcp->LogInstance(); + + // Attempt mapping from patch to new version of code, and + // we don't care if it turns out that there isn't a mapping. + // @todo-postponed: EnC: Make sure that this doesn't cause + // the patch-table to shift. + hr = MapPatchToDJI( dcp, djiNew ); + if (CORDBG_E_CODE_NOT_AVAILABLE == hr ) { - pidInCaseTableMoves = dcp->pid; - - // If we've already mapped this one to the current version, - // don't map it again. - LOG((LF_CORDB,LL_INFO10000,"D::MABFP: Checking if 0x%x is a dup...", - pidInCaseTableMoves)); - - if ( IsDuplicatePatch(GetBPMappingDuplicates()->Table(), - GetBPMappingDuplicates()->Count(), - pidInCaseTableMoves) ) - { - LOG((LF_CORDB,LL_INFO10000,"it is!\n")); - continue; - } - LOG((LF_CORDB,LL_INFO10000,"nope!\n")); - - // Attempt mapping from patch to new version of code, and - // we don't care if it turns out that there isn't a mapping. - // @todo-postponed: EnC: Make sure that this doesn't cause - // the patch-table to shift. - hr = MapPatchToDJI( dcp, djiNew ); - if (CORDBG_E_CODE_NOT_AVAILABLE == hr ) - { - *(listUnbindablePatches.AppendThrowing()) = dcp; - hr = S_OK; - } - - if (FAILED(hr)) - break; + *(listUnbindablePatches.AppendThrowing()) = dcp; + hr = S_OK; + } - //Remember the patch id to prevent duplication later - pidTableEntry = GetBPMappingDuplicates()->Append(); - if (NULL == pidTableEntry) - { - hr = E_OUTOFMEMORY; - break; - } + if (FAILED(hr)) + break; - *pidTableEntry = pidInCaseTableMoves; - LOG((LF_CORDB,LL_INFO10000,"D::MABFP Adding 0x%x to list of " - "already mapped patches\n", pidInCaseTableMoves)); + //Remember the patch id to prevent duplication later + pidTableEntry = GetBPMappingDuplicates()->Append(); + if (NULL == pidTableEntry) + { + hr = E_OUTOFMEMORY; + break; } + + *pidTableEntry = pidInCaseTableMoves; + LOG((LF_CORDB,LL_INFO10000,"D::MABFP Adding 0x%zx to list of already mapped patches\n", + pidInCaseTableMoves)); } // unlock controller lock before sending events. } LOG((LF_CORDB,LL_INFO10000, "D::MABFP: Unlocked patch table\n")); - // Now send any Breakpoint bind error events. if (listUnbindablePatches.Count() > 0) - { LockAndSendBreakpointSetError(&listUnbindablePatches); - } return hr; } @@ -4971,7 +4923,7 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, // available, and thus no patch was placed. The caller may or may // not care. ******************************************************************************/ -HRESULT Debugger::MapPatchToDJI( DebuggerControllerPatch *dcp,DebuggerJitInfo *djiTo) +HRESULT Debugger::MapPatchToDJI(DebuggerControllerPatch *dcp, DebuggerJitInfo *djiTo) { CONTRACTL { @@ -4993,14 +4945,10 @@ HRESULT Debugger::MapPatchToDJI( DebuggerControllerPatch *dcp,DebuggerJitInfo *d } #endif - LOG((LF_CORDB, LL_EVERYTHING, "Calling MapPatchToDJI\n")); + LOG((LF_CORDB, LL_EVERYTHING, "D::MPTDJI Begin %p, patchId:0x%zx\n", dcp, dcp->patchId)); // We shouldn't have been asked to map an already bound patch _ASSERTE( !dcp->IsBound() ); - if ( dcp->IsBound() ) - { - return S_OK; - } // If the patch has no DJI then we're doing a UnbindFunctionPatches/RebindFunctionPatches. Either // way, we simply want the most recent version. In the absence of EnC we should have djiCur == djiTo. @@ -5011,20 +4959,20 @@ HRESULT Debugger::MapPatchToDJI( DebuggerControllerPatch *dcp,DebuggerJitInfo *d // decays into BindFunctionPatch's BindPatch function if (djiCur->m_encVersion == djiTo->m_encVersion) { - // If the patch is a "master" then make a new "slave" patch instead of - // binding the old one. This is to stop us mucking with the master breakpoint patch + // If the patch is a "primary" then make a new "replica" patch instead of + // binding the old one. This is to stop us mucking with the primary breakpoint patch // which we may need to bind several times for generic code. - if (dcp->IsILMasterPatch()) + if (dcp->IsILPrimaryPatch()) { - LOG((LF_CORDB, LL_EVERYTHING, "Add, Bind, Activate new patch from master patch\n")); - if (dcp->controller->AddBindAndActivateILSlavePatch(dcp, djiTo)) + LOG((LF_CORDB, LL_EVERYTHING, "D::MPTDJI Add, Bind, Activate new patch from primary patch\n")); + if (dcp->controller->AddBindAndActivateILReplicaPatch(dcp, djiTo)) { - LOG((LF_CORDB, LL_INFO1000, "Add, Bind Activate went fine!\n" )); + LOG((LF_CORDB, LL_INFO1000, "D::MPTDJI Applied from primary patch!\n" )); return S_OK; } else { - LOG((LF_CORDB, LL_INFO1000, "Didn't work for some reason!\n")); + LOG((LF_CORDB, LL_INFO1000, "D::MPTDJI Didn't work for some reason!\n")); // Caller can track this HR and send error. return CORDBG_E_CODE_NOT_AVAILABLE; @@ -5040,16 +4988,16 @@ HRESULT Debugger::MapPatchToDJI( DebuggerControllerPatch *dcp,DebuggerJitInfo *d // We have an unbound native patch (eg. for PatchTrace), lets try to bind and activate it dcp->SetDJI(djiTo); - LOG((LF_CORDB, LL_EVERYTHING, "trying to bind patch... could be problem\n")); + LOG((LF_CORDB, LL_EVERYTHING, "D::MPTDJI trying to bind patch... could be problem\n")); if (DebuggerController::BindPatch(dcp, djiTo->m_nativeCodeVersion.GetMethodDesc(), NULL)) { DebuggerController::ActivatePatch(dcp); - LOG((LF_CORDB, LL_INFO1000, "Application went fine!\n" )); + LOG((LF_CORDB, LL_INFO1000, "D::MPTDJI Binding went fine!\n" )); return S_OK; } else { - LOG((LF_CORDB, LL_INFO1000, "Didn't apply for some reason!\n")); + LOG((LF_CORDB, LL_INFO1000, "D::MPTDJI Binding failed for some reason!\n")); // Caller can track this HR and send error. return CORDBG_E_CODE_NOT_AVAILABLE; @@ -5178,9 +5126,9 @@ void Debugger::SendSyncCompleteIPCEvent(bool isEESuspendedForGC) DebuggerModule * Debugger::LookupOrCreateModule(DomainAssembly * pDomainAssembly) { _ASSERTE(pDomainAssembly != NULL); - LOG((LF_CORDB, LL_INFO1000, "D::LOCM df=0x%x\n", pDomainAssembly)); + LOG((LF_CORDB, LL_INFO1000, "D::LOCM df=%p\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)); + LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=%p ad=%p -> dm=%p\n", pDomainAssembly->GetModule(), pDomainAssembly->GetAppDomain(), pDModule)); _ASSERTE(pDModule != NULL); _ASSERTE(pDModule->GetDomainAssembly() == pDomainAssembly); @@ -5225,7 +5173,7 @@ DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppD } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x\n", pModule, pAppDomain)); + LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=%p ad=%p\n", pModule, pAppDomain)); // DebuggerModules are relative to a specific AppDomain so we should always be looking up a module / // AppDomain pair. @@ -5253,7 +5201,7 @@ DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppD // If it doesn't exist, create it. if (dmod == NULL) { - LOG((LF_CORDB, LL_INFO1000, "D::LOCM dmod for m=0x%x ad=0x%x not found, creating.\n", pModule, pAppDomain)); + LOG((LF_CORDB, LL_INFO1000, "D::LOCM dmod for m=%p ad=%p not found, creating.\n", pModule, pAppDomain)); HRESULT hr = S_OK; EX_TRY { @@ -5268,7 +5216,7 @@ DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppD // The module must be in the AppDomain that was requested _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", + LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=%p ad=%p -> dm=%p(Mod=%p, DomFile=%p, AD=%p)\n", pModule, pAppDomain, dmod, dmod->GetRuntimeModule(), dmod->GetDomainAssembly(), dmod->GetAppDomain())); return dmod; } @@ -6204,7 +6152,7 @@ void Debugger::LockAndSendEnCRemapEvent(DebuggerJitInfo * dji, SIZE_T currentIP, if (CORDBUnrecoverableError(this)) return; - MethodDesc * pFD = dji->m_nativeCodeVersion.GetMethodDesc(); + MethodDesc * pMD = dji->m_nativeCodeVersion.GetMethodDesc(); // Note that the debugger lock is reentrant, so we may or may not hold it already. Thread *thread = g_pEEInterface->GetThread(); @@ -6221,21 +6169,18 @@ void Debugger::LockAndSendEnCRemapEvent(DebuggerJitInfo * dji, SIZE_T currentIP, ipce->EnCRemap.resumeVersionNumber = dji->m_methodInfo->GetCurrentEnCVersion();; ipce->EnCRemap.currentILOffset = currentIP; ipce->EnCRemap.resumeILOffset = resumeIP; - ipce->EnCRemap.funcMetadataToken = pFD->GetMemberDef(); + ipce->EnCRemap.funcMetadataToken = pMD->GetMemberDef(); - LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: token 0x%x, from version %d to %d\n", + LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: methodDef 0x%x, from version %zx to %zx\n", ipce->EnCRemap.funcMetadataToken, ipce->EnCRemap.currentVersionNumber, ipce->EnCRemap.resumeVersionNumber)); - Module *pRuntimeModule = pFD->GetModule(); + Module *pRuntimeModule = pMD->GetModule(); DebuggerModule * pDModule = LookupOrCreateModule(pRuntimeModule, thread->GetDomain()); ipce->EnCRemap.vmDomainAssembly.SetRawPtr((pDModule ? pDModule->GetDomainAssembly() : NULL)); - LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: %s::%s " - "dmod:0x%x, methodDef:0x%x \n", - pFD->m_pszDebugClassName, pFD->m_pszDebugMethodName, - pDModule, - ipce->EnCRemap.funcMetadataToken)); + LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: %s::%s dmod:%p\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, pDModule)); // IPC event is now initialized, so we can send it over. SendSimpleIPCEventAndBlock(); @@ -6244,12 +6189,11 @@ void Debugger::LockAndSendEnCRemapEvent(DebuggerJitInfo * dji, SIZE_T currentIP, SENDIPCEVENT_END; LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: done\n")); - } // Send the RemapComplete event and block until the debugger Continues -// pFD - specifies the method in which we've remapped into -void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pFD) +// pMD - specifies the method in which we've remapped into +void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pMD) { CONTRACTL { @@ -6272,7 +6216,7 @@ void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pFD) // Ensure the DJI for the latest version of this method has been pre-created. // It's not clear whether this is necessary or not, but it shouldn't hurt since // we're going to need to create it anyway since we'll be debugging inside it. - DebuggerJitInfo *dji = g_pDebugger->GetLatestJitInfoFromMethodDesc(pFD); + DebuggerJitInfo *dji = g_pDebugger->GetLatestJitInfoFromMethodDesc(pMD); (void)dji; //prevent "unused variable" error from GCC _ASSERTE( dji != NULL ); } @@ -6292,18 +6236,15 @@ void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pFD) thread, thread->GetDomain()); + ipce->EnCRemapComplete.funcMetadataToken = pMD->GetMemberDef(); - ipce->EnCRemapComplete.funcMetadataToken = pFD->GetMemberDef(); - - Module *pRuntimeModule = pFD->GetModule(); + Module *pRuntimeModule = pMD->GetModule(); DebuggerModule * pDModule = LookupOrCreateModule(pRuntimeModule, thread->GetDomain()); ipce->EnCRemapComplete.vmDomainAssembly.SetRawPtr((pDModule ? pDModule->GetDomainAssembly() : NULL)); - - LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRC: %s::%s " - "dmod:0x%x, methodDef:0x%x \n", - pFD->m_pszDebugClassName, pFD->m_pszDebugMethodName, + LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: %s::%s dmod:%p, methodDef:0x%08x \n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, pDModule, ipce->EnCRemap.funcMetadataToken)); @@ -6313,7 +6254,7 @@ void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pFD) // This will block on the continue SENDIPCEVENT_END; - LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRC: done\n")); + LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: done\n")); } // @@ -6335,7 +6276,8 @@ void Debugger::SendEnCUpdateEvent(DebuggerIPCEventType eventType, } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO10000, "D::LASEnCUFE:\n")); + LOG((LF_CORDB, LL_INFO10000, "D::SEnCUE: type: 0x%x module: %p tkMember: 0x%08x tkType: 0x%08x, ver: %zu\n", + eventType, pModule, memberToken, classToken, enCVersion)); _ASSERTE(eventType == DB_IPCE_ENC_UPDATE_FUNCTION || eventType == DB_IPCE_ENC_ADD_FUNCTION || @@ -6368,8 +6310,7 @@ void Debugger::SendEnCUpdateEvent(DebuggerIPCEventType eventType, m_pRCThread->SendIPCEvent(); - LOG((LF_CORDB, LL_INFO10000, "D::LASEnCUE: done\n")); - + LOG((LF_CORDB, LL_INFO10000, "D::SEnCUE: done\n")); } @@ -6391,10 +6332,9 @@ void Debugger::LockAndSendBreakpointSetError(PATCH_UNORDERED_ARRAY * listUnbinda if (CORDBUnrecoverableError(this)) return; - ULONG count = listUnbindablePatches->Count(); _ASSERTE(count > 0); // must send at least 1 event. - + LOG((LF_CORDB, LL_INFO10000, "D::LASBSE: Failed to bind %u patch(s)\n", count)); Thread *thread = g_pEEInterface->GetThread(); // Note that the debugger lock is reentrant, so we may or may not hold it already. @@ -6402,7 +6342,7 @@ void Debugger::LockAndSendBreakpointSetError(PATCH_UNORDERED_ARRAY * listUnbinda DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); - for(ULONG i = 0; i < count; i++) + for(ULONG i = 0; i < count; i++) { DebuggerControllerPatch *patch = listUnbindablePatches->Table()[i]; _ASSERTE(patch != NULL); @@ -6411,11 +6351,10 @@ void Debugger::LockAndSendBreakpointSetError(PATCH_UNORDERED_ARRAY * listUnbinda DebuggerController *controller = patch->controller; if (controller->GetDCType() != DEBUGGER_CONTROLLER_BREAKPOINT) - { continue; - } - LOG((LF_CORDB, LL_INFO10000, "D::LASBSE:\n")); + LOG((LF_CORDB, LL_INFO10000, "D::LASBSE: Breakpoint binding failure (%u/%u) %p type: %u\n", + i+1, count, controller, controller->GetDCType())); // Send a breakpoint set error event to the Right Side. InitIPCEvent(ipce, DB_IPCE_BREAKPOINT_SET_ERROR, thread, thread->GetDomain()); @@ -9411,12 +9350,8 @@ void Debugger::UnloadAssembly(DomainAssembly * pDomainAssembly) // This will block on the continue SENDIPCEVENT_END; - } - - - // // LoadModule is called when a Runtime thread loads a new module and a debugger // is attached. This also includes when a domain-neutral module is "loaded" into @@ -10593,13 +10528,12 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) case DB_IPCE_STEP: { - LOG((LF_CORDB,LL_INFO10000, "D::HIPCE: stepIn:0x%x frmTok:0x%x" - "StepIn:0x%x RangeIL:0x%x RangeCount:0x%x MapStop:0x%x " - "InterceptStop:0x%x AppD:0x%x\n", - pEvent->StepData.stepIn, + LOG((LF_CORDB,LL_INFO10000, "D::HIPCE: frame SP:%p " + "StepIn:%s RangeIL:%s RangeCount:%u MapStop:0x%x " + "InterceptStop:0x%x AppD:%p\n", pEvent->StepData.frameToken.GetSPValue(), - pEvent->StepData.stepIn, - pEvent->StepData.rangeIL, + (pEvent->StepData.stepIn ? "true" : "false"), + (pEvent->StepData.rangeIL ? "true" : "false"), pEvent->StepData.rangeCount, pEvent->StepData.rgfMappingStop, pEvent->StepData.rgfInterceptStop, @@ -10861,8 +10795,8 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) _ASSERTE(pDebuggerModule != NULL); LOG((LF_CORDB, LL_INFO10000, - "D::HIPCE: class load flag is %d for module 0x%p\n", - pEvent->SetClassLoad.flag, + "D::HIPCE: class load flag is %s for module %p\n", + (pEvent->SetClassLoad.flag ? "true" : "false"), pDebuggerModule)); pDebuggerModule->EnableClassLoadCallbacks((BOOL)pEvent->SetClassLoad.flag); @@ -11178,7 +11112,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) case DB_IPCE_FUNC_EVAL_ABORT: { - LOG((LF_CORDB, LL_INFO1000, "D::HIPCE: Got FuncEvalAbort for pDE:%08x\n", + LOG((LF_CORDB, LL_INFO1000, "D::HIPCE: Got FuncEvalAbort for pDE:%p\n", pEvent->FuncEvalAbort.debuggerEvalKey.UnWrap())); // This is a synchronous event (reply required) @@ -11194,7 +11128,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) case DB_IPCE_FUNC_EVAL_RUDE_ABORT: { - LOG((LF_CORDB, LL_INFO1000, "D::HIPCE: Got FuncEvalRudeAbort for pDE:%08x\n", + LOG((LF_CORDB, LL_INFO1000, "D::HIPCE: Got FuncEvalRudeAbort for pDE:%p\n", pEvent->FuncEvalRudeAbort.debuggerEvalKey.UnWrap())); // This is a synchronous event (reply required) @@ -11565,21 +11499,21 @@ HRESULT Debugger::GetAndSendInterceptCommand(DebuggerIPCEvent *event) if (DbgIsSpecialILOffset(pJitInfo->GetSequenceMap()[i].ilOffset)) { LOG((LF_CORDB, LL_INFO10000, - "D::HIPCE: not placing breakpoint at special offset 0x%x\n", startOffset)); + "D::HIPCE: not placing breakpoint at special offset 0x%zx\n", startOffset)); continue; } if ((i >= 1) && (startOffset == pJitInfo->GetSequenceMap()[i-1].nativeStartOffset)) { LOG((LF_CORDB, LL_INFO10000, - "D::HIPCE: not placing redundant breakpoint at duplicate offset 0x%x\n", startOffset)); + "D::HIPCE: not placing redundant breakpoint at duplicate offset 0x%zx\n", startOffset)); continue; } if (startOffset > relOffset) { LOG((LF_CORDB, LL_INFO10000, - "D::HIPCE: Stopping scan for breakpoint at offset 0x%x\n", startOffset)); + "D::HIPCE: Stopping scan for breakpoint at offset 0x%zx\n", startOffset)); continue; } @@ -11587,8 +11521,8 @@ HRESULT Debugger::GetAndSendInterceptCommand(DebuggerIPCEvent *event) if (!(src & ICorDebugInfo::STACK_EMPTY)) { - LOG((LF_CORDB, LL_INFO10000, "D::HIPCE: not placing E&C breakpoint at offset " - "0x%x b/c not STACK_EMPTY:it's 0x%x\n", startOffset, src)); + LOG((LF_CORDB, LL_INFO10000, "D::HIPCE: not placing EnC breakpoint at offset " + "0x%zx b/c not STACK_EMPTY:it's 0x%x\n", startOffset, src)); continue; } @@ -11599,7 +11533,7 @@ HRESULT Debugger::GetAndSendInterceptCommand(DebuggerIPCEvent *event) #endif // FEATURE_EH_FUNCLETS ) { - LOG((LF_CORDB, LL_INFO10000, "D::HIPCE: updating breakpoint at native offset 0x%x\n", + LOG((LF_CORDB, LL_INFO10000, "D::HIPCE: updating breakpoint at native offset 0x%zx\n", startOffset)); foundOffset = startOffset; #if defined(FEATURE_EH_FUNCLETS) @@ -12214,7 +12148,7 @@ HRESULT Debugger::SendReleaseBuffer(DebuggerRCThread* rcThread, void *pBuffer) } CONTRACTL_END; - LOG((LF_CORDB,LL_INFO10000, "D::SRB for buffer 0x%x\n", pBuffer)); + LOG((LF_CORDB,LL_INFO10000, "D::SRB: Buffer %p\n", pBuffer)); // This is a synchronous event (reply required) DebuggerIPCEvent* event = rcThread->GetIPCEventReceiveBuffer(); @@ -12248,7 +12182,7 @@ HRESULT Debugger::ReleaseRemoteBuffer(void *pBuffer, bool removeFromBlobList) } CONTRACTL_END; - LOG((LF_CORDB, LL_EVERYTHING, "D::RRB: Releasing RS-alloc'd buffer 0x%x\n", pBuffer)); + LOG((LF_CORDB, LL_EVERYTHING, "D::RRB: Releasing RS-alloc'd buffer %p\n", pBuffer)); // Remove the buffer from the blob list if necessary. if (removeFromBlobList) @@ -12684,7 +12618,7 @@ EnCSequencePointHelper::EnCSequencePointHelper(DebuggerJitInfo *pJitInfo) if (DbgIsSpecialILOffset(pJitInfo->GetSequenceMap()[i].ilOffset)) { LOG((LF_ENC, LL_INFO10000, - "D::UF: not placing E&C breakpoint at special offset 0x%x (IL: 0x%x)\n", + "D::UF: not placing EnC breakpoint at special offset 0x%zx (IL: 0x%x)\n", offset, m_pJitInfo->GetSequenceMap()[i].ilOffset)); continue; } @@ -12693,8 +12627,7 @@ EnCSequencePointHelper::EnCSequencePointHelper(DebuggerJitInfo *pJitInfo) if (i >=1 && offset == pJitInfo->GetSequenceMap()[i-1].nativeStartOffset) { LOG((LF_ENC, LL_INFO10000, - "D::UF: not placing redundant E&C " - "breakpoint at duplicate offset 0x%x (IL: 0x%x)\n", + "D::UF: not placing redundant EnC breakpoint at duplicate offset 0x%zx (IL: 0x%x)\n", offset, m_pJitInfo->GetSequenceMap()[i].ilOffset)); continue; } @@ -12705,19 +12638,17 @@ EnCSequencePointHelper::EnCSequencePointHelper(DebuggerJitInfo *pJitInfo) if (!(pJitInfo->GetSequenceMap()[i].source & ICorDebugInfo::STACK_EMPTY)) { LOG((LF_ENC, LL_INFO10000, - "D::UF: not placing E&C breakpoint at offset " - "0x%x (IL: 0x%x) b/c not STACK_EMPTY:it's 0x%x\n", offset, - m_pJitInfo->GetSequenceMap()[i].ilOffset, pJitInfo->GetSequenceMap()[i].source)); + "D::UF: not placing EnC breakpoint at offset 0x%zx (IL: 0x%x) b/c not STACK_EMPTY:it's 0x%x\n", + offset, m_pJitInfo->GetSequenceMap()[i].ilOffset, pJitInfo->GetSequenceMap()[i].source)); continue; } // So far this sequence point looks good, so store it's native offset so we can get // EH information about it from the EE. LOG((LF_ENC, LL_INFO10000, - "D::UF: possibly placing E&C breakpoint at offset " - "0x%x (IL: 0x%x)\n", offset, m_pJitInfo->GetSequenceMap()[i].ilOffset)); + "D::UF: possibly placing EnC breakpoint at offset 0x%zx (IL: 0x%x)\n", + offset, m_pJitInfo->GetSequenceMap()[i].ilOffset)); m_pOffsetToHandlerInfo[i].offset = m_pJitInfo->GetSequenceMap()[i].nativeStartOffset; - } // Ask the EE to fill in the isInFilterOrHandler bit for the native offsets we're interested in @@ -12729,15 +12660,11 @@ EnCSequencePointHelper::~EnCSequencePointHelper() { CONTRACTL { - THROWS; + NOTHROW; GC_NOTRIGGER; } CONTRACTL_END; - - if (m_pOffsetToHandlerInfo) - { - delete[] m_pOffsetToHandlerInfo; - } + delete[] m_pOffsetToHandlerInfo; } // @@ -12772,7 +12699,7 @@ BOOL EnCSequencePointHelper::ShouldSetRemapBreakpoint(unsigned int offsetIndex) if (m_pOffsetToHandlerInfo[offsetIndex].isInFilterOrHandler) { LOG((LF_ENC, LL_INFO10000, - "D::UF: not placing E&C breakpoint in filter/handler at offset 0x%x\n", + "D::UF: not placing EnC breakpoint in filter/handler at offset 0x%zx\n", m_pOffsetToHandlerInfo[offsetIndex].offset)); return FALSE; } @@ -12799,8 +12726,8 @@ HRESULT Debugger::UpdateFunction(MethodDesc* pMD, SIZE_T encVersion) } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO10000, "D::UF: updating " - "%s::%s to version %d\n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, encVersion)); + LOG((LF_CORDB, LL_INFO10000, "D::UF: updating %s::%s to encVersion %zx\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, encVersion)); // tell the RS that this function has been updated so that it can create new CorDBFunction Module *pModule = g_pEEInterface->MethodDescGetModule(pMD); @@ -12828,11 +12755,12 @@ HRESULT Debugger::UpdateFunction(MethodDesc* pMD, SIZE_T encVersion) // So this call will get the most recent old function. DebuggerJitInfo *pJitInfo = GetLatestJitInfoFromMethodDesc(pMD); - if (pJitInfo == NULL ) + // We only place the patches if we have jit info for this + // function, i.e., its already been jitted. Otherwise, the EE will + // pickup the new method on the next JIT anyway. + if (pJitInfo == NULL) { - LOG((LF_CORDB,LL_INFO10000,"Unable to get DJI by recently " - "D::UF: JITted version number (it hasn't been jitted yet)," - "which is fine\n")); + LOG((LF_CORDB,LL_INFO10000,"D::UF: JITted version number (it hasn't been jitted yet), which is fine\n")); return S_OK; } @@ -12849,14 +12777,11 @@ HRESULT Debugger::UpdateFunction(MethodDesc* pMD, SIZE_T encVersion) LOG((LF_CORDB,LL_INFO10000,"D::UF: Applying breakpoints\n")); - // We only place the patches if we have jit info for this - // function, i.e., its already been jitted. Otherwise, the EE will - // pickup the new method on the next JIT anyway. - EnCSequencePointHelper sequencePointHelper(pJitInfo); // For each offset in the IL->Native map, set a new EnC breakpoint on the // ones that we know could be remap points. + PTR_DebuggerILToNativeMap seqMap = pJitInfo->GetSequenceMap(); for (unsigned int i = 0; i < pJitInfo->GetSequenceMapCount(); i++) { // Skip if this isn't a valid remap point (eg. is in an exception handler) @@ -12865,11 +12790,9 @@ HRESULT Debugger::UpdateFunction(MethodDesc* pMD, SIZE_T encVersion) continue; } - SIZE_T offset = pJitInfo->GetSequenceMap()[i].nativeStartOffset; - - LOG((LF_CORDB, LL_INFO10000, - "D::UF: placing E&C breakpoint at native offset 0x%x\n", - offset)); + SIZE_T offset = seqMap[i].ilOffset; + LOG((LF_CORDB, LL_INFO10000, "D::UF: placing EnC breakpoint at offset 0x%x (IL: 0x%x)\n", + seqMap[i].nativeStartOffset, seqMap[i].ilOffset)); DebuggerEnCBreakpoint *bp; @@ -12984,7 +12907,7 @@ HRESULT Debugger::AddField(FieldDesc* pFD, SIZE_T encVersion) CONTRACTL_END; LOG((LF_CORDB, LL_INFO10000, "D::AFld: adding " - "%8.8d::%8.8d to version %d\n", pFD->GetApproxEnclosingMethodTable()->GetCl(), pFD->GetMemberDef(), encVersion)); + "TypeDef: 0x%08x FieldDef: 0x%08x to version %zx\n", pFD->GetApproxEnclosingMethodTable()->GetCl(), pFD->GetMemberDef(), encVersion)); // tell the RS that this field has been added so that it can update it's structures SendEnCUpdateEvent( DB_IPCE_ENC_ADD_FIELD, @@ -13013,29 +12936,21 @@ HRESULT Debugger::RemapComplete(MethodDesc* pMD, TADDR addr, SIZE_T nativeOffset { THROWS; GC_TRIGGERS_FROM_GETJITINFO; + PRECONDITION(pMD != NULL); + PRECONDITION(addr != NULL); } CONTRACTL_END; - _ASSERTE(pMD != NULL); - _ASSERTE(addr != NULL); - - LOG((LF_CORDB, LL_INFO10000, "D::RC: installed remap complete patch for " - "%s::%s to version %d\n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); - - DebuggerMethodInfo *dmi = GetOrCreateMethodInfo(pMD->GetModule(), pMD->GetMemberDef()); - - if (dmi == NULL) - { - return E_OUTOFMEMORY; - } - DebuggerJitInfo *pJitInfo = GetJitInfo(pMD, (const BYTE *) addr); - if (pJitInfo == NULL) { _ASSERTE(!"Debugger doesn't handle OOM"); return E_OUTOFMEMORY; } + + LOG((LF_CORDB, LL_INFO10000, "D::RC: installed remap complete patch for %s::%s to encVersion %zx\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, pJitInfo->m_encVersion)); + _ASSERTE(pJitInfo->m_addrOfCode + nativeOffset == addr); DebuggerEnCBreakpoint *bp; @@ -13049,6 +12964,7 @@ HRESULT Debugger::RemapComplete(MethodDesc* pMD, TADDR addr, SIZE_T nativeOffset (AppDomain *)pMD->GetModule()->GetDomain()); if (bp == NULL) { + _ASSERTE(!"Debugger doesn't handle OOM"); return E_OUTOFMEMORY; } @@ -13083,10 +12999,8 @@ HRESULT Debugger::MapILInfoToCurrentNative(MethodDesc *pMD, _ASSERTE(HasLazyData()); // only used for EnC, should have already inited. - - LOG((LF_CORDB, LL_INFO1000000, "D::MILITCN: %s::%s ilOff:0x%x, " - ", natFnx:0x%x dji:0x%x\n", pMD->m_pszDebugClassName, - pMD->m_pszDebugMethodName, ilOffset, nativeFnxStart)); + LOG((LF_CORDB, LL_INFO1000000, "D::MILITCN: %s::%s ilOff:0x%zx, natFnx:%p\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, ilOffset, nativeFnxStart)); *nativeOffset = 0; DebuggerJitInfo *djiTo = GetJitInfo( pMD, (const BYTE *)nativeFnxStart); diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 55aa6c6df7e27a..a116c802e1ae35 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -689,7 +689,7 @@ class DebuggerRCThread _ASSERTE(m_pDCB != NULL); // In case this turns into a continuation event GetRCThreadSendBuffer()->next = NULL; - LOG((LF_CORDB,LL_EVERYTHING, "GIPCESBuffer: got event 0x%x\n", GetRCThreadSendBuffer())); + LOG((LF_CORDB,LL_EVERYTHING, "GIPCESBuffer: got event %p\n", GetRCThreadSendBuffer())); return GetRCThreadSendBuffer(); } @@ -1250,7 +1250,7 @@ class CodeRegionInfo MethodDesc * md = NULL, PTR_CORDB_ADDRESS_TYPE addr = PTR_NULL); - // Fills in the CodeRegoinInfo fields from the start address. + // Fills in the CodeRegionInfo fields from the start address. void InitializeFromStartAddress(PCODE addr) { CONTRACTL @@ -1436,6 +1436,27 @@ class DebuggerJitInfo #endif public: + void LogInstance() + { +#ifdef LOGGING + const char* encState = "not enabled"; +#ifdef EnC_SUPPORTED + encState = m_encBreakpointsApplied ? "true" : "false"; +#endif //EnC_SUPPORTED + LOG((LF_CORDB, LL_INFO10000, " DJI: %p\n" + " m_jitComplete: %s\n" + " m_encBreakpointsApplied: %s\n" + " m_methodInfo: %p\n" + " m_addrOfCode: %p\n" + " m_sizeOfCode: 0x%zx\n" + " m_lastIL: 0x%x\n" + " m_sequenceMapCount: %u\n" + " m_callsiteMapCount: %u\n", + this, (m_jitComplete ? "true" : "false"), encState, + m_methodInfo, m_addrOfCode, m_sizeOfCode, m_lastIL, m_sequenceMapCount, m_callsiteMapCount)); +#endif //LOGGING + } + unsigned int GetSequenceMapCount() { SUPPORTS_DAC; diff --git a/src/coreclr/debug/ee/functioninfo.cpp b/src/coreclr/debug/ee/functioninfo.cpp index cf94eab8f0458e..5602dc2580681e 100644 --- a/src/coreclr/debug/ee/functioninfo.cpp +++ b/src/coreclr/debug/ee/functioninfo.cpp @@ -383,8 +383,8 @@ DebuggerJitInfo::NativeOffset DebuggerJitInfo::MapILOffsetToNative(DebuggerJitIn { #endif // FEATURE_EH_FUNCLETS PREFIX_ASSUME( map != NULL ); - LOG((LF_CORDB, LL_INFO10000, "DJI::MILOTN: ilOff 0x%x to nat 0x%x exact:0x%x (Entry IL Off:0x%x)\n", - ilOffset.m_ilOffset, map->nativeStartOffset, resultOffset.m_fExact, map->ilOffset)); + LOG((LF_CORDB, LL_INFO10000, "DJI::MILOTN: ilOffset 0x%zx to nat 0x%x exact:%s (Entry IL Off:0x%x)\n", + ilOffset.m_ilOffset, map->nativeStartOffset, (resultOffset.m_fExact ? "true" : "false"), map->ilOffset)); resultOffset.m_nativeOffset = map->nativeStartOffset; @@ -654,7 +654,7 @@ SIZE_T DebuggerJitInfo::MapILOffsetToNativeForSetIP(SIZE_T offsetILTo, int funcl // calls MapILOffsetToNative for the startOffset (putting the // result into start), and the endOffset (putting the result into end). // SIZE_T startOffset: IL offset from beginning of function. -// SIZE_T endOffset: IL offset from beginngin of function, +// SIZE_T endOffset: IL offset from beginning of function, // or zero to indicate that the end of the function should be used. // DebuggerILToNativeMap **start: Contains start & end // native offsets that correspond to startOffset. Set to NULL if @@ -892,13 +892,9 @@ void DebuggerJitInfo::LazyInitBounds() PRECONDITION(!g_pDebugger->HasDebuggerDataLock()); } CONTRACTL_END; - LOG((LF_CORDB, LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%p m_fAttemptInit %s\n", this, m_fAttemptInit == true ? "true": "false")); - // Only attempt lazy-init once if (m_fAttemptInit) - { return; - } EX_TRY { @@ -927,7 +923,8 @@ void DebuggerJitInfo::LazyInitBounds() &cMap, &pMap, &cVars, &pVars); - LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%p GetBoundariesAndVars success=0x%x\n", this, fSuccess)); + LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=%p GetBoundariesAndVars success=%s\n", + this, (fSuccess ? "true" : "false"))); // SetBoundaries uses the CodeVersionManager, need to take it now for lock ordering reasons CodeVersionManager::LockHolder codeVersioningLockHolder; @@ -951,7 +948,7 @@ void DebuggerJitInfo::LazyInitBounds() } EX_CATCH { - LOG((LF_CORDB,LL_WARNING, "DJI::LazyInitBounds: this=0x%x Exception was thrown and caught\n", this)); + LOG((LF_CORDB,LL_WARNING, "DJI::LazyInitBounds: this=%p Exception was thrown and caught\n", this)); // Just catch the exception. The DJI maps may or may-not be initialized, // but they should still be in a consistent state, so we should be ok. } @@ -1016,7 +1013,7 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping * } CONTRACTL_END; - LOG((LF_CORDB,LL_EVERYTHING, "DJI::SetBoundaries: this=0x%p cMap=0x%x pMap=0x%p\n", this, cMap, pMap)); + LOG((LF_CORDB,LL_EVERYTHING, "DJI::sB: this=%p cMap=%u pMap=%p\n", this, cMap, pMap)); _ASSERTE((cMap == 0) == (pMap == NULL)); _ASSERTE(m_sequenceMap == NULL); @@ -1043,7 +1040,7 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping * // like the DebuggerJitInfo's. // m_sequenceMap = (DebuggerILToNativeMap *)new (interopsafe) DebuggerILToNativeMap[cMap]; - LOG((LF_CORDB,LL_EVERYTHING, "DJI::SetBoundaries: this=0x%p m_sequenceMap=0x%x\n", this, m_sequenceMap)); + LOG((LF_CORDB,LL_EVERYTHING, "DJI::sB: this=%p m_sequenceMap=%p\n", this, m_sequenceMap)); _ASSERTE(m_sequenceMap != NULL); // we'll throw on null m_sequenceMapCount = cMap; @@ -1186,42 +1183,46 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping * m_callsiteMap = m_sequenceMap + m_sequenceMapCount; m_callsiteMapCount -= m_sequenceMapCount; - LOG((LF_CORDB, LL_INFO100000, "DJI::SetBoundaries: this=0x%p boundary count is %d (%d callsites)\n", + LOG((LF_CORDB, LL_INFO100000, "DJI::sB: this=%p boundary count is %u (%u callsites)\n", this, m_sequenceMapCount, m_callsiteMapCount)); #ifdef LOGGING - for (unsigned int count = 0; count < m_sequenceMapCount + m_callsiteMapCount; count++) - { - if( m_sequenceMap[count].ilOffset == - (ULONG) ICorDebugInfo::PROLOG ) - LOG((LF_CORDB, LL_INFO1000000, - "D::sB: PROLOG --> 0x%08x -- 0x%08x", - m_sequenceMap[count].nativeStartOffset, - m_sequenceMap[count].nativeEndOffset)); - else if ( m_sequenceMap[count].ilOffset == - (ULONG) ICorDebugInfo::EPILOG ) - LOG((LF_CORDB, LL_INFO1000000, - "D::sB: EPILOG --> 0x%08x -- 0x%08x", - m_sequenceMap[count].nativeStartOffset, - m_sequenceMap[count].nativeEndOffset)); - else if ( m_sequenceMap[count].ilOffset == - (ULONG) ICorDebugInfo::NO_MAPPING ) - LOG((LF_CORDB, LL_INFO1000000, - "D::sB: NO MAP --> 0x%08x -- 0x%08x", - m_sequenceMap[count].nativeStartOffset, - m_sequenceMap[count].nativeEndOffset)); - else - LOG((LF_CORDB, LL_INFO1000000, - "D::sB: 0x%04x (Real:0x%04x) --> 0x%08x -- 0x%08x", - m_sequenceMap[count].ilOffset, - m_methodInfo->TranslateToInstIL(&mapping, - m_sequenceMap[count].ilOffset, - bOriginalToInstrumented), - m_sequenceMap[count].nativeStartOffset, - m_sequenceMap[count].nativeEndOffset)); - - LOG((LF_CORDB, LL_INFO1000000, " Src:0x%x\n", m_sequenceMap[count].source)); + for (unsigned count = 0; count < m_sequenceMapCount + m_callsiteMapCount; count++) + { + const DebuggerILToNativeMap& entry = m_sequenceMap[count]; + switch (entry.ilOffset) + { + case (ULONG) ICorDebugInfo::PROLOG: + LOG((LF_CORDB, LL_INFO1000000, + "DJI::sB: PROLOG --> 0x%08x -- 0x%08x", + entry.nativeStartOffset, + entry.nativeEndOffset)); + break; + case (ULONG) ICorDebugInfo::EPILOG: + LOG((LF_CORDB, LL_INFO1000000, + "DJI::sB: EPILOG --> 0x%08x -- 0x%08x", + entry.nativeStartOffset, + entry.nativeEndOffset)); + break; + case (ULONG) ICorDebugInfo::NO_MAPPING: + LOG((LF_CORDB, LL_INFO1000000, + "DJI::sB: NO MAP --> 0x%08x -- 0x%08x", + entry.nativeStartOffset, + entry.nativeEndOffset)); + break; + default: + LOG((LF_CORDB, LL_INFO1000000, + "DJI::sB: 0x%04x (Real:0x%04x) --> 0x%08x -- 0x%08x", + entry.ilOffset, + m_methodInfo->TranslateToInstIL(&mapping, + entry.ilOffset, + bOriginalToInstrumented), + entry.nativeStartOffset, + entry.nativeEndOffset)); + break; + } + LOG((LF_CORDB, LL_INFO1000000, " Src:0x%x\n", entry.source)); } #endif //LOGGING } @@ -1246,17 +1247,18 @@ void DebuggerJitInfo::Init(TADDR newAddress) this->InitFuncletAddress(); #endif // FEATURE_EH_FUNCLETS - LOG((LF_CORDB,LL_INFO10000,"De::JITCo:Got DJI 0x%p(V %d)," - "Hot section from 0x%p to 0x%p " - "Cold section from 0x%p to 0x%p " - "varCount=%d seqCount=%d\n", + LOG((LF_CORDB,LL_INFO10000,"De::JITCo:Got DJI %p (encVersion: %zx)," + "Hot section from %p to %p " + "Cold section from %p to %p " + "Code from %p to %p " + "varCount=%u seqCount=%u\n", this, this->m_encVersion, this->m_codeRegionInfo.getAddrOfHotCode(), this->m_codeRegionInfo.getAddrOfHotCode() + this->m_codeRegionInfo.getSizeOfHotCode(), this->m_codeRegionInfo.getAddrOfColdCode(), this->m_codeRegionInfo.getAddrOfColdCode() + this->m_codeRegionInfo.getSizeOfColdCode(), - (ULONG)this->m_addrOfCode, - (ULONG)this->m_addrOfCode+(ULONG)this->m_sizeOfCode, + this->m_addrOfCode, + this->m_addrOfCode+(ULONG)this->m_sizeOfCode, this->GetVarNativeInfoCount(), this->GetSequenceMapCount())); @@ -1717,7 +1719,7 @@ DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(NativeCodeVersion n // We've now added a new DJI into the table and released the lock. Thus any other thread // can come and use our DJI. Good thing we inited the DJI _before_ adding it to the table. - LOG((LF_CORDB,LL_INFO10000,"DMI:CAAJI: new head of dji list:0x%p\n", m_latestJitInfo)); + LOG((LF_CORDB,LL_INFO10000,"DMI:CAAJI: new head of dji list: %p\n", m_latestJitInfo)); return dji; } @@ -1983,7 +1985,7 @@ void DebuggerMethodInfo::IterateAllDJIs(AppDomain * pAppDomain, Module * pLoader _ASSERTE(pEnum != NULL); _ASSERTE(pAppDomain != NULL || pMethodDescFilter != NULL); - // Esnure we have DJIs for everything. + // Ensure we have DJIs for everything. CreateDJIsForNativeBlobs(pAppDomain, pLoaderModuleFilter, pMethodDescFilter); pEnum->m_pCurrent = m_latestJitInfo; @@ -2076,7 +2078,7 @@ void DebuggerMethodInfo::CreateDJIsForMethodDesc(MethodDesc * pMethodDesc) } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD pMethodDesc:0x%p\n", pMethodDesc)); + LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD pMethodDesc:%p\n", pMethodDesc)); // The debugger doesn't track Lightweight-codegen methods b/c they have no metadata. if (pMethodDesc->IsDynamicMethod()) @@ -2099,17 +2101,17 @@ void DebuggerMethodInfo::CreateDJIsForMethodDesc(MethodDesc * pMethodDesc) // Some versions may not be compiled yet - skip those for now // if they compile later the JitCompiled callback will add a DJI to our cache at that time PCODE codeAddr = itr->GetNativeCode(); - LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD (%d) Native code for DJI - 0x%p\n", ++count, codeAddr)); + LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD (%d) Native code for DJI - %p\n", ++count, codeAddr)); if (codeAddr) { // The DJI may already be populated in the cache, if so CreateInitAndAdd is // a no-op and that is fine. BOOL unusedDjiWasCreated; CreateInitAndAddJitInfo(*itr, codeAddr, &unusedDjiWasCreated); - LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD Was DJI created? 0x%d\n", unusedDjiWasCreated)); + LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD Was DJI created? %s\n", (unusedDjiWasCreated ? "true" : "false"))); } } - LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD NativeCodeVersion total %d for md=0x%p\n", count, pMethodDesc)); + LOG((LF_CORDB, LL_INFO10000, "DMI::CDJIFMD NativeCodeVersion total %d for md=%p\n", count, pMethodDesc)); } #else // We just ask for the DJI to ensure that it's lazily created. @@ -2179,8 +2181,8 @@ HRESULT DebuggerMethodInfoTable::AddMethodInfo(Module *pModule, } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO1000, "DMIT::AMI Adding dmi:0x%x Mod:0x%x tok:" - "0x%x nVer:0x%x\n", mi, pModule, token, mi->GetCurrentEnCVersion())); + LOG((LF_CORDB, LL_INFO1000, "DMIT::AMI: Adding dmi:%p Mod:%p tok:0x%08x nVer:0x%zx\n", + mi, pModule, token, mi->GetCurrentEnCVersion())); _ASSERTE(mi != NULL); @@ -2197,18 +2199,18 @@ HRESULT DebuggerMethodInfoTable::AddMethodInfo(Module *pModule, DebuggerMethodInfoEntry *dmie = (DebuggerMethodInfoEntry *) Add(HASH(&dmik)); - if (dmie != NULL) + if (dmie == NULL) { - dmie->key.pModule = pModule; - dmie->key.token = token; - dmie->mi = mi; - - LOG((LF_CORDB, LL_INFO1000, "DMIT::AJI: mod:0x%x tok:0%x ", - pModule, token)); - return S_OK; + ThrowOutOfMemory(); + return E_OUTOFMEMORY; } - ThrowOutOfMemory(); + dmie->key.pModule = pModule; + dmie->key.token = token; + dmie->mi = mi; + + LOG((LF_CORDB, LL_INFO1000, "DMIT::AMI: mod:%p tok:0x%08x\n", + pModule, token)); return S_OK; } @@ -2227,8 +2229,8 @@ HRESULT DebuggerMethodInfoTable::OverwriteMethodInfo(Module *pModule, } CONTRACTL_END; - LOG((LF_CORDB, LL_INFO1000, "DMIT::OJI: dmi:0x%x mod:0x%x tok:0x%x\n", mi, - pModule, token)); + LOG((LF_CORDB, LL_INFO1000, "DMIT::OMI: dmi:%p mod:%p tok:0x%08x\n", + mi, pModule, token)); _ASSERTE(g_pDebugger->HasDebuggerDataLock()); @@ -2240,14 +2242,13 @@ HRESULT DebuggerMethodInfoTable::OverwriteMethodInfo(Module *pModule, = (DebuggerMethodInfoEntry *) Find(HASH(&dmik), KEY(&dmik)); if (entry != NULL) { - if ( (fOnlyIfNull && - entry->mi == NULL) || - !fOnlyIfNull) + if ( (fOnlyIfNull && entry->mi == NULL) + || !fOnlyIfNull) { entry->mi = mi; - LOG((LF_CORDB, LL_INFO1000, "DMIT::OJI: mod:0x%x tok:0x%x remap" - "nVer:0x%x\n", pModule, token, entry->nVersionLastRemapped)); + LOG((LF_CORDB, LL_INFO1000, "DMIT::OMI: mod:%p tok:0x%08x remap nVer:0x%zx\n", + pModule, token, entry->nVersionLastRemapped)); return S_OK; } } @@ -2380,7 +2381,7 @@ DebuggerMethodInfo *DebuggerMethodInfoTable::GetMethodInfo(Module *pModule, mdMe } else { - LOG((LF_CORDB, LL_INFO1000, "DMI::GMI: for methodDef 0x%x, got 0x%p prev:0x%p\n", + LOG((LF_CORDB, LL_INFO1000, "DMI::GMI: for methodDef 0x%x, DMI=%p prev DMI=%p\n", token, entry->mi, (entry->mi?entry->mi->m_prevMethodInfo:0))); return entry->mi; } diff --git a/src/coreclr/debug/ee/rcthread.cpp b/src/coreclr/debug/ee/rcthread.cpp index e7aa9f2b067ce4..b20c46559f734f 100644 --- a/src/coreclr/debug/ee/rcthread.cpp +++ b/src/coreclr/debug/ee/rcthread.cpp @@ -1595,7 +1595,7 @@ bool DebuggerRCThread::IsRCThreadReady() // leaving the threadid still non-0. So check the actual thread object // and make sure it's still around. int ret = WaitForSingleObject(m_thread, 0); - LOG((LF_CORDB, LL_EVERYTHING, "DRCT::IsReady - wait(0x%p)=%d, GetLastError() = %d\n", m_thread, ret, GetLastError())); + LOG((LF_CORDB, LL_EVERYTHING, "DRCT::IsReady - wait(%p)=0x%x, GetLastError() = 0x%x\n", m_thread, ret, GetLastError())); if (ret != WAIT_TIMEOUT) { diff --git a/src/coreclr/debug/inc/dbgtargetcontext.h b/src/coreclr/debug/inc/dbgtargetcontext.h index 745e0f6a363cf6..e23aaa7c2333bd 100644 --- a/src/coreclr/debug/inc/dbgtargetcontext.h +++ b/src/coreclr/debug/inc/dbgtargetcontext.h @@ -555,26 +555,25 @@ static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equ #define DT_RISCV64_MAX_BREAKPOINTS 8 #define DT_RISCV64_MAX_WATCHPOINTS 2 -typedef DECLSPEC_ALIGN(16) struct { +typedef struct DECLSPEC_ALIGN(16) { // // Control flags. // /* +0x000 */ DWORD ContextFlags; - /* +0x004 */ DWORD Fcsr; // // Integer registers // - DWORD64 ZR; - DWORD64 RA; - DWORD64 SP; - DWORD64 GP; - DWORD64 TP; + DWORD64 R0; + DWORD64 Ra; + DWORD64 Sp; + DWORD64 Gp; + DWORD64 Tp; DWORD64 T0; DWORD64 T1; DWORD64 T2; - DWORD64 FP; + DWORD64 Fp; DWORD64 S1; DWORD64 A0; DWORD64 A1; @@ -598,12 +597,13 @@ typedef DECLSPEC_ALIGN(16) struct { DWORD64 T4; DWORD64 T5; DWORD64 T6; - DWORD64 PC; + DWORD64 Pc; // // Floating Point Registers // ULONGLONG F[32]; + DWORD Fcsr; } DT_CONTEXT; static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size"); diff --git a/src/coreclr/debug/inc/riscv64/primitives.h b/src/coreclr/debug/inc/riscv64/primitives.h index 0ce355aec5950c..39c505b8f28738 100644 --- a/src/coreclr/debug/inc/riscv64/primitives.h +++ b/src/coreclr/debug/inc/riscv64/primitives.h @@ -87,31 +87,31 @@ constexpr CorDebugRegister g_JITToCorDbgReg[] = inline void CORDbgSetIP(DT_CONTEXT *context, LPVOID ip) { LIMITED_METHOD_CONTRACT; - context->PC = (DWORD64)ip; + context->Pc = (DWORD64)ip; } inline LPVOID CORDbgGetSP(const DT_CONTEXT * context) { LIMITED_METHOD_CONTRACT; - return (LPVOID)(size_t)(context->SP); + return (LPVOID)(size_t)(context->Sp); } inline void CORDbgSetSP(DT_CONTEXT *context, LPVOID esp) { LIMITED_METHOD_CONTRACT; - context->SP = (DWORD64)esp; + context->Sp = (DWORD64)esp; } inline LPVOID CORDbgGetFP(const DT_CONTEXT * context) { LIMITED_METHOD_CONTRACT; - return (LPVOID)(size_t)(context->FP); + return (LPVOID)(size_t)(context->Fp); } inline void CORDbgSetFP(DT_CONTEXT *context, LPVOID fp) { LIMITED_METHOD_CONTRACT; - context->FP = (DWORD64)fp; + context->Fp = (DWORD64)fp; } @@ -121,9 +121,9 @@ inline BOOL CompareControlRegisters(const DT_CONTEXT * pCtx1, const DT_CONTEXT * // TODO-RISCV64: Sort out frame registers - if ((pCtx1->PC == pCtx2->PC) && - (pCtx1->SP == pCtx2->SP) && - (pCtx1->FP == pCtx2->FP)) + if ((pCtx1->Pc == pCtx2->Pc) && + (pCtx1->Sp == pCtx2->Sp) && + (pCtx1->Fp == pCtx2->Fp)) { return TRUE; } @@ -168,7 +168,7 @@ inline LPVOID CORDbgGetIP(DT_CONTEXT *context) { LIMITED_METHOD_CONTRACT; - return (LPVOID)(size_t)(context->PC); + return (LPVOID)(size_t)(context->Pc); } inline void CORDbgSetInstructionExImpl(CORDB_ADDRESS_TYPE* address, diff --git a/src/coreclr/debug/runtimeinfo/CMakeLists.txt b/src/coreclr/debug/runtimeinfo/CMakeLists.txt index b1763b22c1898d..e6d45ada120131 100644 --- a/src/coreclr/debug/runtimeinfo/CMakeLists.txt +++ b/src/coreclr/debug/runtimeinfo/CMakeLists.txt @@ -15,7 +15,7 @@ function(generate_module_index Target ModuleIndexFile) add_custom_command( OUTPUT ${ModuleIndexFile} - COMMAND ${CLR_ENG_NATIVE_DIR}/genmoduleindex${scriptExt} $ ${ModuleIndexFile} + COMMAND ${CLR_ENG_NATIVE_DIR}/genmoduleindex${scriptExt} $ ${ModuleIndexFile} ${CMAKE_READELF} DEPENDS ${Target} COMMENT "Generating ${Target} module index file -> ${ModuleIndexFile}" ) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 8857f6528f90b7..820d49d84ecffb 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -2512,10 +2512,16 @@ int gc_heap::num_regions_freed_in_sweep = 0; int gc_heap::regions_per_gen[max_generation + 1]; +int gc_heap::planned_regions_per_gen[max_generation + 1]; + int gc_heap::sip_maxgen_regions_per_gen[max_generation + 1]; heap_segment* gc_heap::reserved_free_regions_sip[max_generation]; +int gc_heap::new_gen0_regions_in_plns = 0; +int gc_heap::new_regions_in_prr = 0; +int gc_heap::new_regions_in_threading = 0; + size_t gc_heap::end_gen0_region_space = 0; size_t gc_heap::end_gen0_region_committed_space = 0; @@ -11675,7 +11681,7 @@ void gc_heap::set_region_gen_num (heap_segment* region, int gen_num) } inline -void gc_heap::set_region_plan_gen_num (heap_segment* region, int plan_gen_num) +void gc_heap::set_region_plan_gen_num (heap_segment* region, int plan_gen_num, bool replace_p) { int gen_num = heap_segment_gen_num (region); int supposed_plan_gen_num = get_plan_gen_num (gen_num); @@ -11701,6 +11707,17 @@ void gc_heap::set_region_plan_gen_num (heap_segment* region, int plan_gen_num) region->flags &= ~heap_segment_flags_demoted; } + // If replace_p is true, it means we need to move a region from its original planned gen to this new gen. + if (replace_p) + { + int original_plan_gen_num = heap_segment_plan_gen_num (region); + planned_regions_per_gen[original_plan_gen_num]--; + } + + planned_regions_per_gen[plan_gen_num]++; + dprintf (REGIONS_LOG, ("h%d g%d %zx(%zx) -> g%d (total %d region planned in g%d)", + heap_number, heap_segment_gen_num (region), (size_t)region, heap_segment_mem (region), plan_gen_num, planned_regions_per_gen[plan_gen_num], plan_gen_num)); + heap_segment_plan_gen_num (region) = plan_gen_num; uint8_t* region_start = get_region_start (region); @@ -14448,6 +14465,10 @@ gc_heap::init_gc_heap (int h_number) #endif //RECORD_LOH_STATE #ifdef USE_REGIONS + new_gen0_regions_in_plns = 0; + new_regions_in_prr = 0; + new_regions_in_threading = 0; + special_sweep_p = false; #endif //USE_REGIONS @@ -25922,6 +25943,62 @@ size_t gc_heap::get_total_gen_fragmentation (int gen_number) return total_fragmentation; } +#ifdef USE_REGIONS +int gc_heap::get_total_new_gen0_regions_in_plns () +{ + int total_new_gen0_regions_in_plns = 0; + +#ifdef MULTIPLE_HEAPS + for (int hn = 0; hn < gc_heap::n_heaps; hn++) + { + gc_heap* hp = gc_heap::g_heaps[hn]; +#else //MULTIPLE_HEAPS + { + gc_heap* hp = pGenGCHeap; +#endif //MULTIPLE_HEAPS + total_new_gen0_regions_in_plns += hp->new_gen0_regions_in_plns; + } + + return total_new_gen0_regions_in_plns; +} + +int gc_heap::get_total_new_regions_in_prr () +{ + int total_new_regions_in_prr = 0; + +#ifdef MULTIPLE_HEAPS + for (int hn = 0; hn < gc_heap::n_heaps; hn++) + { + gc_heap* hp = gc_heap::g_heaps[hn]; +#else //MULTIPLE_HEAPS + { + gc_heap* hp = pGenGCHeap; +#endif //MULTIPLE_HEAPS + total_new_regions_in_prr += hp->new_regions_in_prr; + } + + return total_new_regions_in_prr; +} + +int gc_heap::get_total_new_regions_in_threading () +{ + int total_new_regions_in_threading = 0; + +#ifdef MULTIPLE_HEAPS + for (int hn = 0; hn < gc_heap::n_heaps; hn++) + { + gc_heap* hp = gc_heap::g_heaps[hn]; +#else //MULTIPLE_HEAPS + { + gc_heap* hp = pGenGCHeap; +#endif //MULTIPLE_HEAPS + total_new_regions_in_threading += hp->new_regions_in_threading; + } + + return total_new_regions_in_threading; +} +#endif //USE_REGIONS + size_t gc_heap::get_total_gen_estimated_reclaim (int gen_number) { size_t total_estimated_reclaim = 0; @@ -28789,23 +28866,34 @@ void gc_heap::skip_pins_in_alloc_region (generation* consing_gen, int plan_gen_n heap_segment_plan_allocated (alloc_region) = generation_allocation_pointer (consing_gen); } -void gc_heap::decide_on_demotion_pin_surv (heap_segment* region) +void gc_heap::decide_on_demotion_pin_surv (heap_segment* region, int* no_pinned_surv_region_count) { int new_gen_num = 0; + int pinned_surv = heap_segment_pinned_survived (region); - if (settings.promotion) + if (pinned_surv == 0) { - // If this region doesn't have much pinned surv left, we demote it; otherwise the region - // will be promoted like normal. - size_t basic_region_size = (size_t)1 << min_segment_size_shr; - if ((int)(((double)heap_segment_pinned_survived (region) * 100.0) / (double)basic_region_size) - >= demotion_pinned_ratio_th) + (*no_pinned_surv_region_count)++; + dprintf (REGIONS_LOG, ("region %Ix will be empty", heap_segment_mem (region))); + } + + // If this region doesn't have much pinned surv left, we demote it; otherwise the region + // will be promoted like normal. + size_t basic_region_size = (size_t)1 << min_segment_size_shr; + int pinned_ratio = (int)(((double)pinned_surv * 100.0) / (double)basic_region_size); + dprintf (REGIONS_LOG, ("h%d g%d region %Ix(%Ix) ps: %d (%d) (%s)", heap_number, + heap_segment_gen_num (region), (size_t)region, heap_segment_mem (region), pinned_surv, pinned_ratio, + ((pinned_ratio >= demotion_pinned_ratio_th) ? "ND" : "D"))); + + if (pinned_ratio >= demotion_pinned_ratio_th) + { + if (settings.promotion) { new_gen_num = get_plan_gen_num (heap_segment_gen_num (region)); } } - set_region_plan_gen_num_sip (region, new_gen_num); + set_region_plan_gen_num (region, new_gen_num); } // If the next plan gen number is different, since different generations cannot share the same @@ -28825,10 +28913,11 @@ void gc_heap::process_last_np_surv_region (generation* consing_gen, assert ((consing_gen_alloc_ptr >= heap_segment_mem (alloc_region)) && (consing_gen_alloc_ptr <= heap_segment_reserved (alloc_region))); - dprintf (REGIONS_LOG, ("h%d next need to plan gen%d, consing alloc region: %p, ptr: %p(consing gen: %d)", - heap_number, next_plan_gen_num, + dprintf (REGIONS_LOG, ("h%d PLN: (%s) plan gen%d->%d, consing alloc region: %p, ptr: %p (%Id) (consing gen: %d)", + heap_number, (settings.promotion ? "promotion" : "no promotion"), current_plan_gen_num, next_plan_gen_num, heap_segment_mem (alloc_region), generation_allocation_pointer (consing_gen), + (generation_allocation_pointer (consing_gen) - heap_segment_mem (alloc_region)), consing_gen->gen_num)); if (current_plan_gen_num != next_plan_gen_num) @@ -28845,7 +28934,7 @@ void gc_heap::process_last_np_surv_region (generation* consing_gen, // skip all the pins in this region since we cannot use it to plan the next gen. skip_pins_in_alloc_region (consing_gen, current_plan_gen_num); - heap_segment* next_region = heap_segment_next (alloc_region); + heap_segment* next_region = heap_segment_next_non_sip (alloc_region); if (!next_region) { @@ -28866,6 +28955,9 @@ void gc_heap::process_last_np_surv_region (generation* consing_gen, { dprintf (REGIONS_LOG, ("h%d getting a new region for gen0 plan start seg to %p", heap_number, heap_segment_mem (next_region))); + + regions_per_gen[0]++; + new_gen0_regions_in_plns++; } else { @@ -28913,8 +29005,8 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c assert (pinned_plug_que_empty_p()); } - dprintf (REGIONS_LOG, ("h%d PRR: plan %d: consing alloc seg: %p, ptr: %p", - heap_number, current_plan_gen_num, + dprintf (REGIONS_LOG, ("h%d PRR: (%s) plan %d: consing alloc seg: %p, ptr: %p", + heap_number, (settings.promotion ? "promotion" : "no promotion"), current_plan_gen_num, heap_segment_mem (generation_allocation_segment (consing_gen)), generation_allocation_pointer (consing_gen))); @@ -28922,8 +29014,83 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c { assert (!settings.promotion); current_plan_gen_num = 0; + + // For the non promotion case we need to take care of the alloc region we are on right + // now if there's already planned allocations in it. We cannot let it go through + // decide_on_demotion_pin_surv which is only concerned with pinned surv. + heap_segment* alloc_region = generation_allocation_segment (consing_gen); + if (generation_allocation_pointer (consing_gen) > heap_segment_mem (alloc_region)) + { + skip_pins_in_alloc_region (consing_gen, current_plan_gen_num); + heap_segment* next_region = heap_segment_next_non_sip (alloc_region); + + if ((next_region == 0) && (heap_segment_gen_num (alloc_region) > 0)) + { + next_region = generation_start_segment (generation_of (heap_segment_gen_num (alloc_region) - 1)); + } + + if (next_region) + { + init_alloc_info (consing_gen, next_region); + } + else + { + assert (pinned_plug_que_empty_p ()); + if (!pinned_plug_que_empty_p ()) + { + dprintf (REGIONS_LOG, ("we still have a pin at %Ix but no more regions!?", pinned_plug (oldest_pin ()))); + GCToOSInterface::DebugBreak (); + } + + // Instead of checking for this condition we just set the alloc region to 0 so it's easier to check + // later. + generation_allocation_segment (consing_gen) = 0; + generation_allocation_pointer (consing_gen) = 0; + generation_allocation_limit (consing_gen) = 0; + } + } } + // What has been planned doesn't change at this point. So at this point we know exactly which generation still doesn't + // have any regions planned and this method is responsible to attempt to plan at least one region in each of those gens. + // So we look at each of the remaining regions (that are non SIP, since SIP regions have already been planned) and decide + // which generation it should be planned in. We used the following rules to decide - + // + // + if the pinned surv of a region is >= demotion_pinned_ratio_th (this will be dynamically tuned based on memory load), + // it will be promoted to its normal planned generation unconditionally. + // + // + if the pinned surv is < demotion_pinned_ratio_th, we will always demote it to gen0. We will record how many regions + // have no survival at all - those will be empty and can be used to plan any non gen0 generation if needed. + // + // Note! We could actually promote a region with non zero pinned survivors to whichever generation we'd like (eg, we could + // promote a gen0 region to gen2). However it means we'd need to set cards on those objects because we will not have a chance + // later. The benefit of doing this is small in general as when we get into this method, it's very rare we don't already + // have planned regions in higher generations. So I don't think it's worth the complexicity for now. We may consider it + // for the future. + // + // + if after we are done walking the remaining regions, we still haven't successfully planned all the needed generations, + // we check to see if we have enough in the regions that will be empty (note that we call set_region_plan_gen_num on + // these regions which means they are planned in gen0. So we need to make sure at least gen0 has 1 region). If so + // thread_final_regions will naturally get one from there so we don't need to call set_region_plan_gen_num to replace the + // plan gen num. + // + // + if we don't have enough in regions that will be empty, we'll need to ask for new regions and if we can't, we fall back + // to the special sweep mode. + // + dprintf (REGIONS_LOG, ("h%d regions in g2: %d, g1: %d, g0: %d, before processing remaining regions", + heap_number, planned_regions_per_gen[2], planned_regions_per_gen[1], planned_regions_per_gen[0])); + + dprintf (REGIONS_LOG, ("h%d g2: surv %Id(p: %Id, %.2f%%), g1: surv %Id(p: %Id, %.2f%%), g0: surv %Id(p: %Id, %.2f%%)", + heap_number, + dd_survived_size (dynamic_data_of (2)), dd_pinned_survived_size (dynamic_data_of (2)), + (dd_survived_size (dynamic_data_of (2)) ? ((double)dd_pinned_survived_size (dynamic_data_of (2)) * 100.0 / (double)dd_survived_size (dynamic_data_of (2))) : 0), + dd_survived_size (dynamic_data_of (1)), dd_pinned_survived_size (dynamic_data_of (1)), + (dd_survived_size (dynamic_data_of (2)) ? ((double)dd_pinned_survived_size (dynamic_data_of (1)) * 100.0 / (double)dd_survived_size (dynamic_data_of (1))) : 0), + dd_survived_size (dynamic_data_of (0)), dd_pinned_survived_size (dynamic_data_of (0)), + (dd_survived_size (dynamic_data_of (2)) ? ((double)dd_pinned_survived_size (dynamic_data_of (0)) * 100.0 / (double)dd_survived_size (dynamic_data_of (0))) : 0))); + + int to_be_empty_regions = 0; + while (!pinned_plug_que_empty_p()) { uint8_t* oldest_plug = pinned_plug (oldest_pin()); @@ -28951,12 +29118,12 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c generation_allocation_pointer (consing_gen), heap_segment_plan_gen_num (nseg), current_plan_gen_num)); - if (!heap_segment_swept_in_plan (nseg)) - { - heap_segment_plan_allocated (nseg) = generation_allocation_pointer (consing_gen); - } - decide_on_demotion_pin_surv (nseg); + assert (!heap_segment_swept_in_plan (nseg)); + + heap_segment_plan_allocated (nseg) = generation_allocation_pointer (consing_gen); + decide_on_demotion_pin_surv (nseg, &to_be_empty_regions); + heap_segment* next_seg = heap_segment_next_non_sip (nseg); if ((next_seg == 0) && (heap_segment_gen_num (nseg) > 0)) @@ -28993,48 +29160,130 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c if (special_sweep_p) { - assert (heap_segment_next_rw (current_region) == 0); + assert ((current_region == 0) || (heap_segment_next_rw (current_region) == 0)); return; } - decide_on_demotion_pin_surv (current_region); + dprintf (REGIONS_LOG, ("after going through the rest of regions - regions in g2: %d, g1: %d, g0: %d, to be empty %d now", + planned_regions_per_gen[2], planned_regions_per_gen[1], planned_regions_per_gen[0], to_be_empty_regions)); + + if (current_region) + { + decide_on_demotion_pin_surv (current_region, &to_be_empty_regions); + + if (!heap_segment_swept_in_plan (current_region)) + { + heap_segment_plan_allocated (current_region) = generation_allocation_pointer (consing_gen); + dprintf (REGIONS_LOG, ("h%d setting alloc seg %p plan alloc to %p", + heap_number, heap_segment_mem (current_region), + heap_segment_plan_allocated (current_region))); + } + + dprintf (REGIONS_LOG, ("before going through the rest of empty regions - regions in g2: %d, g1: %d, g0: %d, to be empty %d now", + planned_regions_per_gen[2], planned_regions_per_gen[1], planned_regions_per_gen[0], to_be_empty_regions)); + + heap_segment* region_no_pins = heap_segment_next (current_region); + int region_no_pins_gen_num = heap_segment_gen_num (current_region); + + do + { + region_no_pins = heap_segment_non_sip (region_no_pins); + + if (region_no_pins) + { + set_region_plan_gen_num (region_no_pins, current_plan_gen_num); + to_be_empty_regions++; + + heap_segment_plan_allocated (region_no_pins) = heap_segment_mem (region_no_pins); + dprintf (REGIONS_LOG, ("h%d setting empty seg %p(no pins) plan gen to 0, plan alloc to %p", + heap_number, heap_segment_mem (region_no_pins), + heap_segment_plan_allocated (region_no_pins))); + + region_no_pins = heap_segment_next (region_no_pins); + } + + if (!region_no_pins) + { + if (region_no_pins_gen_num > 0) + { + region_no_pins_gen_num--; + region_no_pins = generation_start_segment (generation_of (region_no_pins_gen_num)); + } + else + break; + } + } while (region_no_pins); + } - if (!heap_segment_swept_in_plan (current_region)) + if (to_be_empty_regions) { - heap_segment_plan_allocated (current_region) = generation_allocation_pointer (consing_gen); - dprintf (REGIONS_LOG, ("h%d setting alloc seg %p plan alloc to %p", - heap_number, heap_segment_mem (current_region), - heap_segment_plan_allocated (current_region))); + if (planned_regions_per_gen[0] == 0) + { + dprintf (REGIONS_LOG, ("we didn't seem to find any gen to plan gen0 yet we have empty regions?!")); + } + assert (planned_regions_per_gen[0]); } - heap_segment* region_no_pins = heap_segment_next (current_region); - int region_no_pins_gen_num = heap_segment_gen_num (current_region); + int saved_planned_regions_per_gen[max_generation + 1]; + memcpy (saved_planned_regions_per_gen, planned_regions_per_gen, sizeof (saved_planned_regions_per_gen)); - do + // Because all the "to be empty regions" were planned in gen0, we should substract them if we want to repurpose them. + assert (saved_planned_regions_per_gen[0] >= to_be_empty_regions); + saved_planned_regions_per_gen[0] -= to_be_empty_regions; + + int plan_regions_needed = 0; + for (int gen_idx = settings.condemned_generation; gen_idx >= 0; gen_idx--) + { + if (saved_planned_regions_per_gen[gen_idx] == 0) + { + dprintf (REGIONS_LOG, ("g%d has 0 planned regions!!!", gen_idx)); + plan_regions_needed++; + } + } + + dprintf (1, ("we still need %d regions, %d will be empty", plan_regions_needed, to_be_empty_regions)); + if (plan_regions_needed > to_be_empty_regions) { - region_no_pins = heap_segment_non_sip (region_no_pins); + dprintf (REGIONS_LOG, ("h%d %d regions will be empty but we still need %d regions!!", heap_number, to_be_empty_regions, plan_regions_needed)); + + plan_regions_needed -= to_be_empty_regions; + + while (plan_regions_needed && get_new_region (0)) + { + new_regions_in_prr++; + plan_regions_needed--; + } - if (region_no_pins) + if (plan_regions_needed > 0) { - set_region_plan_gen_num (region_no_pins, current_plan_gen_num); - heap_segment_plan_allocated (region_no_pins) = heap_segment_mem (region_no_pins); - dprintf (REGIONS_LOG, ("h%d setting seg %p(no pins) plan gen to 0, plan alloc to %p", - heap_number, heap_segment_mem (region_no_pins), - heap_segment_plan_allocated (region_no_pins))); + dprintf (REGIONS_LOG, ("h%d %d regions short for having at least one region per gen, special sweep on", + heap_number)); + special_sweep_p = true; + } + } + +#ifdef _DEBUG + { + dprintf (REGIONS_LOG, ("regions in g2: %d[%d], g1: %d[%d], g0: %d[%d]", + planned_regions_per_gen[2], regions_per_gen[2], + planned_regions_per_gen[1], regions_per_gen[1], + planned_regions_per_gen[0], regions_per_gen[0])); - region_no_pins = heap_segment_next (region_no_pins); + int total_regions = 0; + int total_planned_regions = 0; + for (int i = max_generation; i >= 0; i--) + { + total_regions += regions_per_gen[i]; + total_planned_regions += planned_regions_per_gen[i]; } - else + + if (total_regions != total_planned_regions) { - if (region_no_pins_gen_num > 0) - { - region_no_pins_gen_num--; - region_no_pins = generation_start_segment (generation_of (region_no_pins_gen_num)); - } - else - break; + dprintf (REGIONS_LOG, ("planned %d regions, saw %d total", + total_planned_regions, total_regions)); } - } while (region_no_pins); + } +#endif //_DEBUG } void gc_heap::grow_mark_list_piece() @@ -29461,6 +29710,7 @@ void gc_heap::plan_phase (int condemned_gen_number) #ifdef USE_REGIONS memset (regions_per_gen, 0, sizeof (regions_per_gen)); + memset (planned_regions_per_gen, 0, sizeof (planned_regions_per_gen)); memset (sip_maxgen_regions_per_gen, 0, sizeof (sip_maxgen_regions_per_gen)); memset (reserved_free_regions_sip, 0, sizeof (reserved_free_regions_sip)); int pinned_survived_region = 0; @@ -29579,9 +29829,11 @@ void gc_heap::plan_phase (int condemned_gen_number) { #ifdef USE_REGIONS regions_per_gen[condemned_gen_index1]++; - dprintf (REGIONS_LOG, ("h%d gen%d %p-%p", + dprintf (REGIONS_LOG, ("h%d PS: gen%d %p-%p (%d, surv: %d), %d regions", heap_number, condemned_gen_index1, - heap_segment_mem (seg2), heap_segment_allocated (seg2))); + heap_segment_mem (seg2), heap_segment_allocated (seg2), + (heap_segment_allocated (seg2) - heap_segment_mem (seg2)), + (int)heap_segment_survived (seg2), regions_per_gen[condemned_gen_index1])); #endif //USE_REGIONS heap_segment_plan_allocated (seg2) = @@ -29789,7 +30041,7 @@ void gc_heap::plan_phase (int condemned_gen_number) int saved_active_new_gen_number = active_new_gen_number; BOOL saved_allocate_in_condemned = allocate_in_condemned; - dprintf (REGIONS_LOG, ("h%d switching to look at next gen - current active old %d, new %d, alloc_in_condemned: %d", + dprintf (REGIONS_LOG, ("h%d finished planning gen%d regions into gen%d, alloc_in_condemned: %d", heap_number, active_old_gen_number, active_new_gen_number, allocate_in_condemned)); if (active_old_gen_number <= (settings.promotion ? (max_generation - 1) : max_generation)) @@ -31469,9 +31721,8 @@ uint8_t* gc_heap::allocate_at_end (size_t size) // + decommit end of region if it's not a gen0 region; // + set the region gen_num to the new one; // -// For empty regions, we always return empty regions to free unless it's a gen -// start region. Note that I'm returning gen0 empty regions as well, however, -// returning a region to free does not decommit. +// For empty regions, we always return empty regions to free. Note that I'm returning +// gen0 empty regions as well, however, returning a region to free does not decommit. // // If this is called for a compacting GC, we know we always take the planned generation // on the region (and set the new allocated); else this is called for sweep in which case @@ -31480,7 +31731,7 @@ uint8_t* gc_heap::allocate_at_end (size_t size) // + if we are in the special sweep mode, we don't change the old gen number at all // + if we are not in special sweep we need to promote all regions, including the SIP ones // because we make the assumption that this is the case for sweep for handles. -heap_segment* gc_heap::find_first_valid_region (heap_segment* region, bool compact_p) +heap_segment* gc_heap::find_first_valid_region (heap_segment* region, bool compact_p, int* num_returned_regions) { check_seg_gen_num (generation_allocation_segment (generation_of (max_generation))); @@ -31519,6 +31770,8 @@ heap_segment* gc_heap::find_first_valid_region (heap_segment* region, bool compa heap_segment* region_to_delete = current_region; current_region = heap_segment_next (current_region); return_free_region (region_to_delete); + (*num_returned_regions)++; + dprintf (REGIONS_LOG, (" h%d gen%d return region %p to free, current->%p(%p)", heap_number, gen_num, heap_segment_mem (region_to_delete), current_region, (current_region ? heap_segment_mem (current_region) : 0))); @@ -31587,6 +31840,9 @@ heap_segment* gc_heap::find_first_valid_region (heap_segment* region, bool compa void gc_heap::thread_final_regions (bool compact_p) { + int num_returned_regions = 0; + int num_new_regions = 0; + for (int i = 0; i < max_generation; i++) { if (reserved_free_regions_sip[i]) @@ -31625,7 +31881,7 @@ void gc_heap::thread_final_regions (bool compact_p) heap_segment* current_region = heap_segment_rw (generation_start_segment (generation_of (gen_idx))); dprintf (REGIONS_LOG, ("gen%d start from %p", gen_idx, heap_segment_mem (current_region))); - while ((current_region = find_first_valid_region (current_region, compact_p))) + while ((current_region = find_first_valid_region (current_region, compact_p, &num_returned_regions))) { assert (!compact_p || (heap_segment_plan_gen_num (current_region) == heap_segment_gen_num (current_region))); @@ -31710,6 +31966,7 @@ void gc_heap::thread_final_regions (bool compact_p) { start_region = get_free_region (gen_idx); assert (start_region); + num_new_regions++; thread_start_region (gen, start_region); dprintf (REGIONS_LOG, ("creating new gen%d at %p", gen_idx, heap_segment_mem (start_region))); } @@ -31721,6 +31978,19 @@ void gc_heap::thread_final_regions (bool compact_p) } } + int net_added_regions = num_new_regions - num_returned_regions; + dprintf (REGIONS_LOG, ("TFR: added %d, returned %d, net %d", num_new_regions, num_returned_regions, net_added_regions)); + + // TODO: For sweeping GCs by design we will need to get a new region for gen0 unless we are doing a special sweep. + // This means we need to know when we decided to sweep that we can get a new region (if needed). If we can't, we + // need to turn special sweep on. + if ((settings.compaction || special_sweep_p) && (net_added_regions > 0)) + { + new_regions_in_threading += net_added_regions; + + assert (!"we shouldn't be getting new regions in TFR!"); + } + verify_regions (true, false); } @@ -31918,7 +32188,7 @@ bool gc_heap::should_sweep_in_plan (heap_segment* region) old_card_surv_ratio, sip_surv_ratio_th)); if (old_card_surv_ratio >= sip_old_card_surv_ratio_th) { - set_region_plan_gen_num (region, max_generation); + set_region_plan_gen_num (region, max_generation, true); sip_maxgen_regions_per_gen[gen_num]++; sip_p = true; } @@ -31944,7 +32214,7 @@ bool gc_heap::should_sweep_in_plan (heap_segment* region) { // If we cannot get another region, simply revert our decision. sip_maxgen_regions_per_gen[gen_num]--; - set_region_plan_gen_num (region, new_gen_num); + set_region_plan_gen_num (region, new_gen_num, true); } } } @@ -41028,7 +41298,7 @@ ptrdiff_t gc_heap::estimate_gen_growth (int gen_number) ptrdiff_t budget_gen = new_allocation_gen - usable_free_space - reserved_not_in_use; - dprintf(1, ("h%2d gen %d budget %zd allocated: %zd, FL: %zd, reserved_not_in_use %zd budget_gen %zd", + dprintf (REGIONS_LOG, ("h%2d gen %d budget %zd allocated: %zd, FL: %zd, reserved_not_in_use %zd budget_gen %zd", heap_number, gen_number, new_allocation_gen, allocated_gen, free_list_space_gen, reserved_not_in_use, budget_gen)); #else //USE_REGIONS @@ -43946,7 +44216,51 @@ void gc_heap::descr_generations (const char* msg) if (heap_number == 0) { - dprintf (1, ("total heap size: %zd, commit size: %zd", get_total_heap_size(), get_total_committed_size())); +#ifdef USE_REGIONS + size_t alloc_size = get_total_heap_size () / 1024 / 1024; + size_t commit_size = get_total_committed_size () / 1024 / 1024; + size_t frag_size = get_total_fragmentation () / 1024 / 1024; + int total_new_gen0_regions_in_plns = get_total_new_gen0_regions_in_plns (); + int total_new_regions_in_prr = get_total_new_regions_in_prr (); + int total_new_regions_in_threading = get_total_new_regions_in_threading (); + uint64_t elapsed_time_so_far = GetHighPrecisionTimeStamp () - process_start_time; + + size_t idx = VolatileLoadWithoutBarrier (&settings.gc_index); + + dprintf (REGIONS_LOG, ("[%s] GC#%5Id [%s] heap %Idmb (F: %Idmb %d%%) commit size: %Idmb, %0.3f min, %d,%d new in plan, %d in threading", + msg, idx, (settings.promotion ? "PM" : "NPM"), alloc_size, frag_size, + (int)((double)frag_size * 100.0 / (double)alloc_size), + commit_size, + (double)elapsed_time_so_far / (double)1000000 / (double)60, + total_new_gen0_regions_in_plns, total_new_regions_in_prr, total_new_regions_in_threading)); + + size_t total_gen_size_mb[loh_generation + 1] = { 0, 0, 0, 0 }; + size_t total_gen_fragmentation_mb[loh_generation + 1] = { 0, 0, 0, 0 }; + for (int i = 0; i < (loh_generation + 1); i++) + { + total_gen_size_mb[i] = get_total_generation_size (i) / 1024 / 1024; + total_gen_fragmentation_mb[i] = get_total_gen_fragmentation (i) / 1024 / 1024; + } + + int bgcs = VolatileLoadWithoutBarrier (¤t_bgc_state); + dprintf (REGIONS_LOG, ("[%s] GC#%Id (bgcs: %d, %s) g0: %Idmb (f: %Idmb %d%%), g1: %Idmb (f: %Idmb %d%%), g2: %Idmb (f: %Idmb %d%%), g3: %Idmb (f: %Idmb %d%%)", + msg, idx, bgcs, str_bgc_state[bgcs], + total_gen_size_mb[0], total_gen_fragmentation_mb[0], (total_gen_size_mb[0] ? (int)((double)total_gen_fragmentation_mb[0] * 100.0 / (double)total_gen_size_mb[0]) : 0), + total_gen_size_mb[1], total_gen_fragmentation_mb[1], (total_gen_size_mb[1] ? (int)((double)total_gen_fragmentation_mb[1] * 100.0 / (double)total_gen_size_mb[1]) : 0), + total_gen_size_mb[2], total_gen_fragmentation_mb[2], (total_gen_size_mb[2] ? (int)((double)total_gen_fragmentation_mb[2] * 100.0 / (double)total_gen_size_mb[2]) : 0), + total_gen_size_mb[3], total_gen_fragmentation_mb[3], (total_gen_size_mb[3] ? (int)((double)total_gen_fragmentation_mb[3] * 100.0 / (double)total_gen_size_mb[3]) : 0))); + + // print every 20 GCs so it's easy to see if we are making progress. + if ((idx % 20) == 0) + { + dprintf (1, ("[%5s] GC#%5Id total heap size: %Idmb (F: %Idmb %d%%) commit size: %Idmb, %0.3f min, %d,%d new in plan, %d in threading\n", + msg, idx, alloc_size, frag_size, + (int)((double)frag_size * 100.0 / (double)alloc_size), + commit_size, + (double)elapsed_time_so_far / (double)1000000 / (double)60, + total_new_gen0_regions_in_plns, total_new_regions_in_prr, total_new_regions_in_threading)); + } +#endif //USE_REGIONS } for (int curr_gen_number = total_generation_count - 1; curr_gen_number >= 0; curr_gen_number--) @@ -43977,7 +44291,7 @@ void gc_heap::descr_generations (const char* msg) generation* gen = generation_of (curr_gen_number); heap_segment* seg = heap_segment_rw (generation_start_segment (gen)); #ifdef USE_REGIONS - dprintf (1, ("g%d: start seg: %p alloc seg: %p, tail region: %p", + dprintf (GTC_LOG, ("g%d: start seg: %p alloc seg: %p, tail region: %p", curr_gen_number, heap_segment_mem (seg), heap_segment_mem (generation_allocation_segment (gen)), @@ -45804,8 +46118,16 @@ unsigned int GCHeap::WhichGeneration (Object* object) #ifdef FEATURE_BASICFREEZE if (!((o < g_gc_highest_address) && (o >= g_gc_lowest_address))) { - return max_generation; + return INT32_MAX; } +#ifndef USE_REGIONS + if (GCHeap::IsInFrozenSegment (object)) + { + // in case if the object belongs to an in-range frozen segment + // For regions those are never in-range. + return INT32_MAX; + } +#endif #endif //FEATURE_BASICFREEZE gc_heap* hp = gc_heap::heap_of (o); unsigned int g = hp->object_gennum (o); @@ -48657,6 +48979,9 @@ CFinalize::UpdatePromotedGenerations (int gen, BOOL gen_0_empty_p) int new_gen = g_theGCHeap->WhichGeneration (*po); if (new_gen != i) { + // We never promote objects to a non-GC heap + assert (new_gen <= max_generation); + dprintf (3, ("Moving object %p->%p from gen %d to gen %d", po, *po, i, new_gen)); if (new_gen > i) diff --git a/src/coreclr/gc/gcimpl.h b/src/coreclr/gc/gcimpl.h index b82f17a78f9597..4a4c92cb50ede1 100644 --- a/src/coreclr/gc/gcimpl.h +++ b/src/coreclr/gc/gcimpl.h @@ -150,7 +150,8 @@ class GCHeap : public IGCHeapInternal //Unregister an object for finalization void SetFinalizationRun (Object* obj); - //returns the generation number of an object (not valid during relocation) + // returns the generation number of an object (not valid during relocation) or + // INT32_MAX if the object belongs to a non-GC heap. unsigned WhichGeneration (Object* object); // returns TRUE is the object is ephemeral bool IsEphemeral (Object* object); diff --git a/src/coreclr/gc/gcinterface.h b/src/coreclr/gc/gcinterface.h index 86fa8470fbcb95..a6a3177acb090d 100644 --- a/src/coreclr/gc/gcinterface.h +++ b/src/coreclr/gc/gcinterface.h @@ -722,6 +722,7 @@ class IGCHeap { // Returns the generation in which obj is found. Also used by the VM // in some places, in particular syncblk code. + // Returns INT32_MAX if obj belongs to a non-GC heap. virtual unsigned WhichGeneration(Object* obj) PURE_VIRTUAL // Returns the number of GCs that have transpired in the given generation @@ -991,7 +992,7 @@ void updateGCShadow(Object** ptr, Object* val); #define GC_CALL_INTERIOR 0x1 #define GC_CALL_PINNED 0x2 -// keep in sync with GC_ALLOC_FLAGS in GC.cs +// keep in sync with GC_ALLOC_FLAGS in GC.CoreCLR.cs enum GC_ALLOC_FLAGS { GC_ALLOC_NO_FLAGS = 0, diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 08bb071df19dbf..53342f741cb13a 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -535,15 +535,17 @@ enum memory_type static const char * const str_bgc_state[] = { "not_in_process", + "bgc_initialized", + "reset_ww", "mark_handles", "mark_stack", "revisit_soh", - "revisit_loh", + "revisit_uoh", "overflow_soh", - "overflow_loh", + "overflow_uoh", "final_marking", "sweep_soh", - "sweep_loh", + "sweep_uoh", "plan_phase" }; #endif // defined(TRACE_GC) && defined(BACKGROUND_GC) @@ -1587,12 +1589,12 @@ class gc_heap PER_HEAP_ISOLATED_METHOD void set_region_gen_num (heap_segment* region, int gen_num); PER_HEAP_ISOLATED_METHOD int get_region_plan_gen_num (uint8_t* obj); PER_HEAP_ISOLATED_METHOD bool is_region_demoted (uint8_t* obj); - PER_HEAP_METHOD void set_region_plan_gen_num (heap_segment* region, int plan_gen_num); + PER_HEAP_METHOD void set_region_plan_gen_num (heap_segment* region, int plan_gen_num, bool replace_p = false); PER_HEAP_METHOD void set_region_plan_gen_num_sip (heap_segment* region, int plan_gen_num); PER_HEAP_METHOD void set_region_sweep_in_plan (heap_segment* region); PER_HEAP_METHOD void clear_region_sweep_in_plan (heap_segment* region); PER_HEAP_METHOD void clear_region_demoted (heap_segment* region); - PER_HEAP_METHOD void decide_on_demotion_pin_surv (heap_segment* region); + PER_HEAP_METHOD void decide_on_demotion_pin_surv (heap_segment* region, int* no_pinned_surv_region_count); PER_HEAP_METHOD void skip_pins_in_alloc_region (generation* consing_gen, int plan_gen_num); PER_HEAP_METHOD void process_last_np_surv_region (generation* consing_gen, int current_plan_gen_num, @@ -1613,7 +1615,7 @@ class gc_heap PER_HEAP_METHOD bool decide_on_compaction_space(); PER_HEAP_METHOD bool try_get_new_free_region(); PER_HEAP_METHOD bool init_table_for_region (int gen_number, heap_segment* region); - PER_HEAP_METHOD heap_segment* find_first_valid_region (heap_segment* region, bool compact_p); + PER_HEAP_METHOD heap_segment* find_first_valid_region (heap_segment* region, bool compact_p, int* num_returned_regions); PER_HEAP_METHOD void thread_final_regions (bool compact_p); PER_HEAP_METHOD void thread_start_region (generation* gen, heap_segment* region); PER_HEAP_METHOD heap_segment* get_new_region (int gen_number, size_t size = 0); @@ -2978,6 +2980,13 @@ class gc_heap PER_HEAP_ISOLATED_METHOD size_t get_total_committed_size(); PER_HEAP_ISOLATED_METHOD size_t get_total_fragmentation(); PER_HEAP_ISOLATED_METHOD size_t get_total_gen_fragmentation (int gen_number); + +#ifdef USE_REGIONS + PER_HEAP_ISOLATED_METHOD int get_total_new_gen0_regions_in_plns (); + PER_HEAP_ISOLATED_METHOD int get_total_new_regions_in_prr (); + PER_HEAP_ISOLATED_METHOD int get_total_new_regions_in_threading (); +#endif //USE_REGIONS + PER_HEAP_ISOLATED_METHOD size_t get_total_gen_estimated_reclaim (int gen_number); PER_HEAP_ISOLATED_METHOD size_t get_total_gen_size (int gen_number); PER_HEAP_ISOLATED_METHOD void get_memory_info (uint32_t* memory_load, @@ -3405,13 +3414,23 @@ class gc_heap #endif //BACKGROUND_GC #ifdef USE_REGIONS -// This is the number of regions we would free up if we sweep. -// It's used in the decision for compaction so we calculate it in plan. + // This is the number of regions we would free up if we sweep. + // It's used in the decision for compaction so we calculate it in plan. PER_HEAP_FIELD_SINGLE_GC int num_regions_freed_in_sweep; PER_HEAP_FIELD_SINGLE_GC int sip_maxgen_regions_per_gen[max_generation + 1]; PER_HEAP_FIELD_SINGLE_GC heap_segment* reserved_free_regions_sip[max_generation]; + // Used to keep track of the total regions in each condemned generation. For SIP regions we need + // to know if we've made all regions in a condemned gen into a max_generation region; if so we + // would want to revert our decision so we leave at least one region in that generation. Otherwise + // this is used in dprintf's. + PER_HEAP_FIELD_SINGLE_GC int regions_per_gen[max_generation + 1]; + + // Used to keep track of how many regions we have planned to see if any generation + // doens't have a region yet and act accordingly. + PER_HEAP_FIELD_SINGLE_GC int planned_regions_per_gen[max_generation + 1]; + // After plan we calculate this as the planned end gen0 space; // but if we end up sweeping, we recalculate it at the end of // sweep. @@ -3795,8 +3814,12 @@ class gc_heap #endif //BACKGROUND_GC #ifdef USE_REGIONS - // Used in a single GC. - PER_HEAP_FIELD_DIAG_ONLY int regions_per_gen[max_generation + 1]; + // Used to keep track of the new regions we get in process_last_np_surv_region (plns) + PER_HEAP_FIELD_DIAG_ONLY int new_gen0_regions_in_plns; + // Used to keep track of the new regions we get in process_remaining_regions (prr) + PER_HEAP_FIELD_DIAG_ONLY int new_regions_in_prr; + // Used to keep track of the new regions we get in thread_final_regions + PER_HEAP_FIELD_DIAG_ONLY int new_regions_in_threading; #ifdef STRESS_REGIONS // TODO: could consider dynamically grow this. diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 237ecc53a9104e..853d985df3a330 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -757,44 +757,46 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableHWIntrinsic, W("EnableHWIntrinsic"), 1 #endif // defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) #if defined(TARGET_AMD64) || defined(TARGET_X86) -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAES, W("EnableAES"), 1, "Allows AES+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX, W("EnableAVX"), 1, "Allows AVX+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX2, W("EnableAVX2"), 1, "Allows AVX2+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512BW, W("EnableAVX512BW"), 1, "Allows AVX512BW+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512BW_VL, W("EnableAVX512BW_VL"), 1, "Allows AVX512BW_VL+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512CD, W("EnableAVX512CD"), 1, "Allows AVX512CD+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512CD_VL, W("EnableAVX512CD_VL"), 1, "Allows AVX512CD_VL+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512DQ, W("EnableAVX512DQ"), 1, "Allows AVX512DQ+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512DQ_VL, W("EnableAVX512DQ_VL"), 1, "Allows AVX512DQ_VL+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512F, W("EnableAVX512F"), 1, "Allows AVX512F+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512F_VL, W("EnableAVX512F_VL"), 1, "Allows AVX512F_VL+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVXVNNI, W("EnableAVXVNNI"), 1, "Allows AVX VNNI+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableBMI1, W("EnableBMI1"), 1, "Allows BMI1+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableBMI2, W("EnableBMI2"), 1, "Allows BMI2+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableFMA, W("EnableFMA"), 1, "Allows FMA+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableLZCNT, W("EnableLZCNT"), 1, "Allows LZCNT+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1, "Allows PCLMULQDQ+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableMOVBE, W("EnableMOVBE"), 1, "Allows MOVBE+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnablePOPCNT, W("EnablePOPCNT"), 1, "Allows POPCNT+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE, W("EnableSSE"), 1, "Allows SSE+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE2, W("EnableSSE2"), 1, "Allows SSE2+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE3, W("EnableSSE3"), 1, "Allows SSE3+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE3_4, W("EnableSSE3_4"), 1, "Allows SSE3+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE41, W("EnableSSE41"), 1, "Allows SSE4.1+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE42, W("EnableSSE42"), 1, "Allows SSE4.2+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSSE3, W("EnableSSSE3"), 1, "Allows SSSE3+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableX86Serialize, W("EnableX86Serialize"), 1, "Allows X86Serialize+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAES, W("EnableAES"), 1, "Allows AES+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX, W("EnableAVX"), 1, "Allows AVX+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX2, W("EnableAVX2"), 1, "Allows AVX2+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512BW, W("EnableAVX512BW"), 1, "Allows AVX512BW+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512BW_VL, W("EnableAVX512BW_VL"), 1, "Allows AVX512BW_VL+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512CD, W("EnableAVX512CD"), 1, "Allows AVX512CD+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512CD_VL, W("EnableAVX512CD_VL"), 1, "Allows AVX512CD_VL+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512DQ, W("EnableAVX512DQ"), 1, "Allows AVX512DQ+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512DQ_VL, W("EnableAVX512DQ_VL"), 1, "Allows AVX512DQ_VL+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512F, W("EnableAVX512F"), 1, "Allows AVX512F+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512F_VL, W("EnableAVX512F_VL"), 1, "Allows AVX512F_VL+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512VBMI, W("EnableAVX512VBMI"), 1, "Allows AVX512VBMI+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVX512VBMI_VL, W("EnableAVX512VBMI_VL"), 1, "Allows AVX512VBMI_VL+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAVXVNNI, W("EnableAVXVNNI"), 1, "Allows AVXVNNI+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableBMI1, W("EnableBMI1"), 1, "Allows BMI1+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableBMI2, W("EnableBMI2"), 1, "Allows BMI2+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableFMA, W("EnableFMA"), 1, "Allows FMA+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableLZCNT, W("EnableLZCNT"), 1, "Allows LZCNT+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1, "Allows PCLMULQDQ+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableMOVBE, W("EnableMOVBE"), 1, "Allows MOVBE+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnablePOPCNT, W("EnablePOPCNT"), 1, "Allows POPCNT+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE, W("EnableSSE"), 1, "Allows SSE+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE2, W("EnableSSE2"), 1, "Allows SSE2+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE3, W("EnableSSE3"), 1, "Allows SSE3+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE3_4, W("EnableSSE3_4"), 1, "Allows SSE3+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE41, W("EnableSSE41"), 1, "Allows SSE4.1+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSE42, W("EnableSSE42"), 1, "Allows SSE4.2+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableSSSE3, W("EnableSSSE3"), 1, "Allows SSSE3+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableX86Serialize, W("EnableX86Serialize"), 1, "Allows X86Serialize+ hardware intrinsics to be disabled") #elif defined(TARGET_ARM64) -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64AdvSimd, W("EnableArm64AdvSimd"), 1, "Allows Arm64 AdvSimd+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Aes, W("EnableArm64Aes"), 1, "Allows Arm64 Aes+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Atomics, W("EnableArm64Atomics"), 1, "Allows Arm64 Atomics+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Crc32, W("EnableArm64Crc32"), 1, "Allows Arm64 Crc32+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Dczva, W("EnableArm64Dczva"), 1, "Allows Arm64 Dczva+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Dp, W("EnableArm64Dp"), 1, "Allows Arm64 Dp+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Rdm, W("EnableArm64Rdm"), 1, "Allows Arm64 Rdm+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Sha1, W("EnableArm64Sha1"), 1, "Allows Arm64 Sha1+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Sha256, W("EnableArm64Sha256"), 1, "Allows Arm64 Sha256+ hardware intrinsics to be disabled") -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Rcpc, W("EnableArm64Rcpc"), 1, "Allows Arm64 Rcpc+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64AdvSimd, W("EnableArm64AdvSimd"), 1, "Allows Arm64 AdvSimd+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Aes, W("EnableArm64Aes"), 1, "Allows Arm64 Aes+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Atomics, W("EnableArm64Atomics"), 1, "Allows Arm64 Atomics+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Crc32, W("EnableArm64Crc32"), 1, "Allows Arm64 Crc32+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Dczva, W("EnableArm64Dczva"), 1, "Allows Arm64 Dczva+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Dp, W("EnableArm64Dp"), 1, "Allows Arm64 Dp+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Rdm, W("EnableArm64Rdm"), 1, "Allows Arm64 Rdm+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Sha1, W("EnableArm64Sha1"), 1, "Allows Arm64 Sha1+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Sha256, W("EnableArm64Sha256"), 1, "Allows Arm64 Sha256+ hardware intrinsics to be disabled") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64Rcpc, W("EnableArm64Rcpc"), 1, "Allows Arm64 Rcpc+ hardware intrinsics to be disabled") #endif /// diff --git a/src/coreclr/inc/corerror.xml b/src/coreclr/inc/corerror.xml index f9f604c28ae32c..afeaf4f602a4ad 100644 --- a/src/coreclr/inc/corerror.xml +++ b/src/coreclr/inc/corerror.xml @@ -198,8 +198,8 @@ COR_E_LOADING_REFERENCE_ASSEMBLY - "Reference assemblies cannot not be loaded for execution." - Reference assemblies cannot not be loaded for execution. + "Reference assemblies cannot be loaded for execution." + Reference assemblies cannot be loaded for execution @@ -1182,6 +1182,12 @@ The runtime cannot be suspened since a suspension is already in progress. + + CORPROF_E_NOT_GC_OBJECT + "This object belongs to a non-gc heap." + This object belongs to a non-gc heap + + CORSEC_E_POLICY_EXCEPTION "PolicyException thrown." @@ -1788,8 +1794,8 @@ CORDBG_E_NGEN_NOT_SUPPORTED - "NGEN must be supported to perform the requested operation." - NGEN must be supported to perform the requested operation + "NGEN is not supported." + NGEN is not supported diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 0b50a047b3f66e..93f67680284498 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -404,6 +404,7 @@ enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, + CORINFO_HELP_NEWFAST_MAYBEFROZEN, // allocator for objects that *might* allocate them on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned @@ -412,6 +413,7 @@ enum CorInfoHelpFunc CORINFO_HELP_NEW_MDARR,// multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE,// rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation + CORINFO_HELP_NEWARR_1_MAYBEFROZEN, // allocator for arrays that *might* allocate them on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start @@ -519,7 +521,7 @@ enum CorInfoHelpFunc CORINFO_HELP_SETFIELDDOUBLE, CORINFO_HELP_GETFIELDADDR, - + CORINFO_HELP_GETSTATICFIELDADDR, CORINFO_HELP_GETSTATICFIELDADDR_TLS, // Helper for PE TLS fields // There are a variety of specialized helpers for accessing static fields. The JIT should use @@ -583,8 +585,6 @@ enum CorInfoHelpFunc CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type - CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent - CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time // Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper. @@ -1133,7 +1133,8 @@ struct CORINFO_SIG_INFO CorInfoCallConv getCallConv() { return CorInfoCallConv((callConv & CORINFO_CALLCONV_MASK)); } bool hasThis() { return ((callConv & CORINFO_CALLCONV_HASTHIS) != 0); } bool hasExplicitThis() { return ((callConv & CORINFO_CALLCONV_EXPLICITTHIS) != 0); } - unsigned totalILArgs() { return (numArgs + (hasThis() ? 1 : 0)); } + bool hasImplicitThis() { return ((callConv & (CORINFO_CALLCONV_HASTHIS | CORINFO_CALLCONV_EXPLICITTHIS)) == CORINFO_CALLCONV_HASTHIS); } + unsigned totalILArgs() { return (numArgs + (hasImplicitThis() ? 1 : 0)); } bool isVarArg() { return ((getCallConv() == CORINFO_CALLCONV_VARARG) || (getCallConv() == CORINFO_CALLCONV_NATIVEVARARG)); } bool hasTypeArg() { return ((callConv & CORINFO_CALLCONV_PARAMTYPE) != 0); } }; @@ -2618,12 +2619,6 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE parent // base type ) = 0; - // TRUE if cls1 and cls2 are considered equivalent types. - virtual bool areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2 - ) = 0; - // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. virtual TypeCompareState compareTypesForCast( @@ -3224,7 +3219,7 @@ class ICorDynamicInfo : public ICorStaticInfo ) = 0; //------------------------------------------------------------------------------ - // getReadonlyStaticFieldValue: returns true and the actual field's value if the given + // getStaticFieldContent: returns true and the actual field's value if the given // field represents a statically initialized readonly field of any type. // // Arguments: @@ -3236,7 +3231,7 @@ class ICorDynamicInfo : public ICorStaticInfo // Return Value: // Returns true if field's constant value was available and successfully copied to buffer // - virtual bool getReadonlyStaticFieldValue( + virtual bool getStaticFieldContent( CORINFO_FIELD_HANDLE field, uint8_t *buffer, int bufferSize, @@ -3244,6 +3239,13 @@ class ICorDynamicInfo : public ICorStaticInfo bool ignoreMovableObjects = true ) = 0; + virtual bool getObjectContent( + CORINFO_OBJECT_HANDLE obj, + uint8_t* buffer, + int bufferSize, + int valueOffset + ) = 0; + // If pIsSpeculative is NULL, return the class handle for the value of ref-class typed // static readonly fields, if there is a unique location for the static and the class // is already initialized. diff --git a/src/coreclr/inc/corinfoinstructionset.h b/src/coreclr/inc/corinfoinstructionset.h index 4f489cb93b7247..8462ab33413ef9 100644 --- a/src/coreclr/inc/corinfoinstructionset.h +++ b/src/coreclr/inc/corinfoinstructionset.h @@ -69,33 +69,37 @@ enum CORINFO_InstructionSet InstructionSet_AVX512CD_VL=28, InstructionSet_AVX512DQ=29, InstructionSet_AVX512DQ_VL=30, - InstructionSet_X86Base_X64=31, - InstructionSet_SSE_X64=32, - InstructionSet_SSE2_X64=33, - InstructionSet_SSE3_X64=34, - InstructionSet_SSSE3_X64=35, - InstructionSet_SSE41_X64=36, - InstructionSet_SSE42_X64=37, - InstructionSet_AVX_X64=38, - InstructionSet_AVX2_X64=39, - InstructionSet_AES_X64=40, - InstructionSet_BMI1_X64=41, - InstructionSet_BMI2_X64=42, - InstructionSet_FMA_X64=43, - InstructionSet_LZCNT_X64=44, - InstructionSet_PCLMULQDQ_X64=45, - InstructionSet_POPCNT_X64=46, - InstructionSet_AVXVNNI_X64=47, - InstructionSet_MOVBE_X64=48, - InstructionSet_X86Serialize_X64=49, - InstructionSet_AVX512F_X64=50, - InstructionSet_AVX512F_VL_X64=51, - InstructionSet_AVX512BW_X64=52, - InstructionSet_AVX512BW_VL_X64=53, - InstructionSet_AVX512CD_X64=54, - InstructionSet_AVX512CD_VL_X64=55, - InstructionSet_AVX512DQ_X64=56, - InstructionSet_AVX512DQ_VL_X64=57, + InstructionSet_AVX512VBMI=31, + InstructionSet_AVX512VBMI_VL=32, + InstructionSet_X86Base_X64=33, + InstructionSet_SSE_X64=34, + InstructionSet_SSE2_X64=35, + InstructionSet_SSE3_X64=36, + InstructionSet_SSSE3_X64=37, + InstructionSet_SSE41_X64=38, + InstructionSet_SSE42_X64=39, + InstructionSet_AVX_X64=40, + InstructionSet_AVX2_X64=41, + InstructionSet_AES_X64=42, + InstructionSet_BMI1_X64=43, + InstructionSet_BMI2_X64=44, + InstructionSet_FMA_X64=45, + InstructionSet_LZCNT_X64=46, + InstructionSet_PCLMULQDQ_X64=47, + InstructionSet_POPCNT_X64=48, + InstructionSet_AVXVNNI_X64=49, + InstructionSet_MOVBE_X64=50, + InstructionSet_X86Serialize_X64=51, + InstructionSet_AVX512F_X64=52, + InstructionSet_AVX512F_VL_X64=53, + InstructionSet_AVX512BW_X64=54, + InstructionSet_AVX512BW_VL_X64=55, + InstructionSet_AVX512CD_X64=56, + InstructionSet_AVX512CD_VL_X64=57, + InstructionSet_AVX512DQ_X64=58, + InstructionSet_AVX512DQ_VL_X64=59, + InstructionSet_AVX512VBMI_X64=60, + InstructionSet_AVX512VBMI_VL_X64=61, #endif // TARGET_AMD64 #ifdef TARGET_X86 InstructionSet_X86Base=1, @@ -128,33 +132,37 @@ enum CORINFO_InstructionSet InstructionSet_AVX512CD_VL=28, InstructionSet_AVX512DQ=29, InstructionSet_AVX512DQ_VL=30, - InstructionSet_X86Base_X64=31, - InstructionSet_SSE_X64=32, - InstructionSet_SSE2_X64=33, - InstructionSet_SSE3_X64=34, - InstructionSet_SSSE3_X64=35, - InstructionSet_SSE41_X64=36, - InstructionSet_SSE42_X64=37, - InstructionSet_AVX_X64=38, - InstructionSet_AVX2_X64=39, - InstructionSet_AES_X64=40, - InstructionSet_BMI1_X64=41, - InstructionSet_BMI2_X64=42, - InstructionSet_FMA_X64=43, - InstructionSet_LZCNT_X64=44, - InstructionSet_PCLMULQDQ_X64=45, - InstructionSet_POPCNT_X64=46, - InstructionSet_AVXVNNI_X64=47, - InstructionSet_MOVBE_X64=48, - InstructionSet_X86Serialize_X64=49, - InstructionSet_AVX512F_X64=50, - InstructionSet_AVX512F_VL_X64=51, - InstructionSet_AVX512BW_X64=52, - InstructionSet_AVX512BW_VL_X64=53, - InstructionSet_AVX512CD_X64=54, - InstructionSet_AVX512CD_VL_X64=55, - InstructionSet_AVX512DQ_X64=56, - InstructionSet_AVX512DQ_VL_X64=57, + InstructionSet_AVX512VBMI=31, + InstructionSet_AVX512VBMI_VL=32, + InstructionSet_X86Base_X64=33, + InstructionSet_SSE_X64=34, + InstructionSet_SSE2_X64=35, + InstructionSet_SSE3_X64=36, + InstructionSet_SSSE3_X64=37, + InstructionSet_SSE41_X64=38, + InstructionSet_SSE42_X64=39, + InstructionSet_AVX_X64=40, + InstructionSet_AVX2_X64=41, + InstructionSet_AES_X64=42, + InstructionSet_BMI1_X64=43, + InstructionSet_BMI2_X64=44, + InstructionSet_FMA_X64=45, + InstructionSet_LZCNT_X64=46, + InstructionSet_PCLMULQDQ_X64=47, + InstructionSet_POPCNT_X64=48, + InstructionSet_AVXVNNI_X64=49, + InstructionSet_MOVBE_X64=50, + InstructionSet_X86Serialize_X64=51, + InstructionSet_AVX512F_X64=52, + InstructionSet_AVX512F_VL_X64=53, + InstructionSet_AVX512BW_X64=54, + InstructionSet_AVX512BW_VL_X64=55, + InstructionSet_AVX512CD_X64=56, + InstructionSet_AVX512CD_VL_X64=57, + InstructionSet_AVX512DQ_X64=58, + InstructionSet_AVX512DQ_VL_X64=59, + InstructionSet_AVX512VBMI_X64=60, + InstructionSet_AVX512VBMI_VL_X64=61, #endif // TARGET_X86 }; @@ -322,6 +330,10 @@ struct CORINFO_InstructionSetFlags AddInstructionSet(InstructionSet_AVX512DQ_X64); if (HasInstructionSet(InstructionSet_AVX512DQ_VL)) AddInstructionSet(InstructionSet_AVX512DQ_VL_X64); + if (HasInstructionSet(InstructionSet_AVX512VBMI)) + AddInstructionSet(InstructionSet_AVX512VBMI_X64); + if (HasInstructionSet(InstructionSet_AVX512VBMI_VL)) + AddInstructionSet(InstructionSet_AVX512VBMI_VL_X64); #endif // TARGET_AMD64 #ifdef TARGET_X86 #endif // TARGET_X86 @@ -502,6 +514,14 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_AVX512DQ_VL); if (resultflags.HasInstructionSet(InstructionSet_AVX512DQ_VL_X64) && !resultflags.HasInstructionSet(InstructionSet_AVX512DQ_VL)) resultflags.RemoveInstructionSet(InstructionSet_AVX512DQ_VL_X64); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI) && !resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_X64)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_X64) && !resultflags.HasInstructionSet(InstructionSet_AVX512VBMI)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI_X64); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_VL) && !resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_VL_X64)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI_VL); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_VL_X64) && !resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_VL)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI_VL_X64); if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_X86Base)) resultflags.RemoveInstructionSet(InstructionSet_SSE); if (resultflags.HasInstructionSet(InstructionSet_SSE2) && !resultflags.HasInstructionSet(InstructionSet_SSE)) @@ -560,6 +580,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_AVX512DQ); if (resultflags.HasInstructionSet(InstructionSet_AVX512DQ_VL) && !resultflags.HasInstructionSet(InstructionSet_AVX512F_VL)) resultflags.RemoveInstructionSet(InstructionSet_AVX512DQ_VL); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI) && !resultflags.HasInstructionSet(InstructionSet_AVX512BW)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_VL) && !resultflags.HasInstructionSet(InstructionSet_AVX512BW_VL)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI_VL); #endif // TARGET_AMD64 #ifdef TARGET_X86 if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_X86Base)) @@ -620,6 +644,10 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_AVX512DQ); if (resultflags.HasInstructionSet(InstructionSet_AVX512DQ_VL) && !resultflags.HasInstructionSet(InstructionSet_AVX512F_VL)) resultflags.RemoveInstructionSet(InstructionSet_AVX512DQ_VL); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI) && !resultflags.HasInstructionSet(InstructionSet_AVX512BW)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI); + if (resultflags.HasInstructionSet(InstructionSet_AVX512VBMI_VL) && !resultflags.HasInstructionSet(InstructionSet_AVX512BW_VL)) + resultflags.RemoveInstructionSet(InstructionSet_AVX512VBMI_VL); #endif // TARGET_X86 } while (!oldflags.Equals(resultflags)); @@ -794,6 +822,14 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet) return "AVX512DQ_VL"; case InstructionSet_AVX512DQ_VL_X64 : return "AVX512DQ_VL_X64"; + case InstructionSet_AVX512VBMI : + return "AVX512VBMI"; + case InstructionSet_AVX512VBMI_X64 : + return "AVX512VBMI_X64"; + case InstructionSet_AVX512VBMI_VL : + return "AVX512VBMI_VL"; + case InstructionSet_AVX512VBMI_VL_X64 : + return "AVX512VBMI_VL_X64"; #endif // TARGET_AMD64 #ifdef TARGET_X86 case InstructionSet_X86Base : @@ -856,6 +892,10 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet) return "AVX512DQ"; case InstructionSet_AVX512DQ_VL : return "AVX512DQ_VL"; + case InstructionSet_AVX512VBMI : + return "AVX512VBMI"; + case InstructionSet_AVX512VBMI_VL : + return "AVX512VBMI_VL"; #endif // TARGET_X86 default: @@ -915,6 +955,8 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst case READYTORUN_INSTRUCTION_Avx512CD_VL: return InstructionSet_AVX512CD_VL; case READYTORUN_INSTRUCTION_Avx512DQ: return InstructionSet_AVX512DQ; case READYTORUN_INSTRUCTION_Avx512DQ_VL: return InstructionSet_AVX512DQ_VL; + case READYTORUN_INSTRUCTION_Avx512Vbmi: return InstructionSet_AVX512VBMI; + case READYTORUN_INSTRUCTION_Avx512Vbmi_VL: return InstructionSet_AVX512VBMI_VL; #endif // TARGET_AMD64 #ifdef TARGET_X86 case READYTORUN_INSTRUCTION_X86Base: return InstructionSet_X86Base; @@ -944,6 +986,8 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst case READYTORUN_INSTRUCTION_Avx512CD_VL: return InstructionSet_AVX512CD_VL; case READYTORUN_INSTRUCTION_Avx512DQ: return InstructionSet_AVX512DQ; case READYTORUN_INSTRUCTION_Avx512DQ_VL: return InstructionSet_AVX512DQ_VL; + case READYTORUN_INSTRUCTION_Avx512Vbmi: return InstructionSet_AVX512VBMI; + case READYTORUN_INSTRUCTION_Avx512Vbmi_VL: return InstructionSet_AVX512VBMI_VL; #endif // TARGET_X86 default: diff --git a/src/coreclr/inc/corjitflags.h b/src/coreclr/inc/corjitflags.h index c90753bb4d55cd..4d511aa6f74705 100644 --- a/src/coreclr/inc/corjitflags.h +++ b/src/coreclr/inc/corjitflags.h @@ -55,7 +55,7 @@ class CORJIT_FLAGS CORJIT_FLAG_OSR = 13, // Generate alternate method for On Stack Replacement CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT - CORJIT_FLAG_UNUSED8 = 15, + CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators CORJIT_FLAG_UNUSED9 = 16, CORJIT_FLAG_UNUSED10 = 17, diff --git a/src/coreclr/inc/corprof.idl b/src/coreclr/inc/corprof.idl index 2ed249fb184279..1ae14ab4fdbadc 100644 --- a/src/coreclr/inc/corprof.idl +++ b/src/coreclr/inc/corprof.idl @@ -2035,6 +2035,17 @@ typedef struct COR_PRF_GC_GENERATION_RANGE } COR_PRF_GC_GENERATION_RANGE; +/* + * COR_PRF_NONGC_GENERATION_RANGE describes a range of memory in the GetNonGCHeapBounds function. + */ +typedef struct COR_PRF_NONGC_HEAP_RANGE +{ + ObjectID rangeStart; // the start of the range + UINT_PTR rangeLength; // the used length of the range + UINT_PTR rangeLengthReserved; // the amount of memory reserved for the range (including rangeLength) + +} COR_PRF_NONGC_HEAP_RANGE; + /* * COR_PRF_CLAUSE_TYPE defines the various clause codes for the EX clauses @@ -4245,6 +4256,22 @@ interface ICorProfilerInfo13 : ICorProfilerInfo12 [out] ObjectID* pObject); } +[ + object, + uuid(F460E352-D76D-4FE9-835F-F6AF9D6E862D), + pointer_default(unique), + local +] +interface ICorProfilerInfo14 : ICorProfilerInfo13 +{ + HRESULT EnumerateNonGCObjects([out] ICorProfilerObjectEnum** ppEnum); + + HRESULT GetNonGCHeapBounds( + [in] ULONG cObjectRanges, + [out] ULONG *pcObjectRanges, + [out, size_is(cObjectRanges), length_is(*pcObjectRanges)] COR_PRF_NONGC_HEAP_RANGE ranges[]); +} + /* * This interface lets you iterate over methods in the runtime. */ diff --git a/src/coreclr/inc/crosscomp.h b/src/coreclr/inc/crosscomp.h index bc208595be770c..e03eac034b36f8 100644 --- a/src/coreclr/inc/crosscomp.h +++ b/src/coreclr/inc/crosscomp.h @@ -540,7 +540,6 @@ typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT { // /* +0x000 */ DWORD ContextFlags; - /* +0x004 */ DWORD Fcsr; // // Integer registers @@ -584,6 +583,7 @@ typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT { // //TODO-RISCV64: support the SIMD. ULONGLONG F[32]; + DWORD Fcsr; } T_CONTEXT, *PT_CONTEXT; // _IMAGE_RISCV64_RUNTIME_FUNCTION_ENTRY (see ExternalAPIs\Win9CoreSystem\inc\winnt.h) diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index e053b3d2f816f1..cf4c94498c33a1 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -339,10 +339,6 @@ bool canCast( CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent) override; -bool areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) override; - TypeCompareState compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) override; @@ -636,13 +632,19 @@ unsigned getClassDomainID( CORINFO_CLASS_HANDLE cls, void** ppIndirection) override; -bool getReadonlyStaticFieldValue( +bool getStaticFieldContent( CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) override; +bool getObjectContent( + CORINFO_OBJECT_HANDLE obj, + uint8_t* buffer, + int bufferSize, + int valueOffset) override; + CORINFO_CLASS_HANDLE getStaticFieldCurrentClass( CORINFO_FIELD_HANDLE field, bool* pIsSpeculative) override; diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 765668241e3c3f..d539e04c6b168d 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 236d7997-3d71-45f9-b7d7-5241ad89a56f */ - 0x236d7997, - 0x3d71, - 0x45f9, - { 0xb7, 0xd7, 0x52, 0x41, 0xad, 0x89, 0xa5, 0x6f } +constexpr GUID JITEEVersionIdentifier = { /* 4e6355a0-3844-45e2-8cef-082c18217e14 */ + 0x4e6355a0, + 0x3844, + 0x45e2, + {0x8c, 0xef, 0x8, 0x2c, 0x18, 0x21, 0x7e, 0x14} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 7193c124d602e7..1d498c3589347b 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -70,6 +70,7 @@ // Allocating a new object JITHELPER(CORINFO_HELP_NEWFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY) + JITHELPER(CORINFO_HELP_NEWFAST_MAYBEFROZEN, JIT_NewMaybeFrozen,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY) JITHELPER(CORINFO_HELP_NEWSFAST_FINALIZE, NULL, CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8, JIT_New, CORINFO_HELP_SIG_REG_ONLY) @@ -78,6 +79,7 @@ JITHELPER(CORINFO_HELP_NEW_MDARR, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_NEW_MDARR_RARE, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_NEWARR_1_DIRECT, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) + JITHELPER(CORINFO_HELP_NEWARR_1_MAYBEFROZEN, JIT_NewArr1MaybeFrozen,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_ALIGN8, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) @@ -173,7 +175,7 @@ JITHELPER(CORINFO_HELP_SETFIELDDOUBLE, JIT_SetFieldDouble,CORINFO_HELP_SIG_8_STACK) JITHELPER(CORINFO_HELP_GETFIELDADDR, JIT_GetFieldAddr,CORINFO_HELP_SIG_REG_ONLY) - + JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR, JIT_GetStaticFieldAddr,CORINFO_HELP_SIG_REG_ONLY) JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB) JITHELPER(CORINFO_HELP_GETGENERICS_GCSTATIC_BASE, JIT_GetGenericsGCStaticBase,CORINFO_HELP_SIG_REG_ONLY) @@ -252,8 +254,6 @@ JITHELPER(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, JIT_GetRuntimeType, CORINFO_HELP_SIG_REG_ONLY) JITHELPER(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, JIT_GetRuntimeType_MaybeNull, CORINFO_HELP_SIG_REG_ONLY) - JITHELPER(CORINFO_HELP_ARE_TYPES_EQUIVALENT, NULL, CORINFO_HELP_SIG_REG_ONLY) - JITHELPER(CORINFO_HELP_VIRTUAL_FUNC_PTR, JIT_VirtualFunctionPointer, CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_READYTORUN_NEW, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB) diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index 4754e0a294fe8f..e138058b3666a1 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -18,7 +18,7 @@ // src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs // src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h #define READYTORUN_MAJOR_VERSION 0x0009 -#define READYTORUN_MINOR_VERSION 0x0000 +#define READYTORUN_MINOR_VERSION 0x0001 #define MINIMUM_READYTORUN_MAJOR_VERSION 0x009 @@ -30,6 +30,7 @@ // R2R 6.0 is not backward compatible with 5.x or earlier. // R2R Version 8.0 Changes the alignment of the Int128 type // R2R Version 9.0 adds support for the Vector512 type +// R2R Version 9.1 adds new helpers to allocate objects on frozen segments struct READYTORUN_CORE_HEADER { @@ -335,6 +336,8 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, + READYTORUN_HELPER_NewMaybeFrozenArray = 0x6A, + READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index b9d904b9c41935..8691f9b9cb8c0c 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -55,6 +55,8 @@ HELPER(READYTORUN_HELPER_GenericNonGcTlsBase, CORINFO_HELP_GETGENERICS_NON HELPER(READYTORUN_HELPER_VirtualFuncPtr, CORINFO_HELP_VIRTUAL_FUNC_PTR, ) HELPER(READYTORUN_HELPER_IsInstanceOfException, CORINFO_HELP_ISINSTANCEOF_EXCEPTION, ) +HELPER(READYTORUN_HELPER_NewMaybeFrozenArray, CORINFO_HELP_NEWARR_1_MAYBEFROZEN, ) +HELPER(READYTORUN_HELPER_NewMaybeFrozenObject, CORINFO_HELP_NEWFAST_MAYBEFROZEN, ) HELPER(READYTORUN_HELPER_LMul, CORINFO_HELP_LMUL, ) HELPER(READYTORUN_HELPER_LMulOfv, CORINFO_HELP_LMUL_OVF, ) diff --git a/src/coreclr/inc/readytoruninstructionset.h b/src/coreclr/inc/readytoruninstructionset.h index a46f7133c6fdac..faf4a5028cc1c9 100644 --- a/src/coreclr/inc/readytoruninstructionset.h +++ b/src/coreclr/inc/readytoruninstructionset.h @@ -45,6 +45,8 @@ enum ReadyToRunInstructionSet READYTORUN_INSTRUCTION_Avx512CD_VL=34, READYTORUN_INSTRUCTION_Avx512DQ=35, READYTORUN_INSTRUCTION_Avx512DQ_VL=36, + READYTORUN_INSTRUCTION_Avx512Vbmi=37, + READYTORUN_INSTRUCTION_Avx512Vbmi_VL=38, }; diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index db3634b332dc06..c7c6ddb30b9284 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -159,6 +159,7 @@ set( JIT_SOURCES patchpoint.cpp phase.cpp promotion.cpp + promotiondecomposition.cpp rangecheck.cpp rationalize.cpp redundantbranchopts.cpp @@ -210,7 +211,7 @@ set( JIT_ARM_SOURCES lsraarmarch.cpp lsraarm.cpp targetarm.cpp - unwindarm.cpp + unwindarmarch.cpp ) set( JIT_I386_SOURCES @@ -238,7 +239,7 @@ set( JIT_ARM64_SOURCES simd.cpp simdashwintrinsic.cpp targetarm64.cpp - unwindarm.cpp + unwindarmarch.cpp unwindarm64.cpp hwintrinsicarm64.cpp hwintrinsiccodegenarm64.cpp diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index 6a9f0408fb82ad..cb5db87194525c 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -84,7 +84,6 @@ DEF_CLR_API(getBuiltinClass) DEF_CLR_API(getTypeForPrimitiveValueClass) DEF_CLR_API(getTypeForPrimitiveNumericClass) DEF_CLR_API(canCast) -DEF_CLR_API(areTypesEquivalent) DEF_CLR_API(compareTypesForCast) DEF_CLR_API(compareTypesForEquality) DEF_CLR_API(mergeClasses) @@ -159,7 +158,8 @@ DEF_CLR_API(getCallInfo) DEF_CLR_API(canAccessFamily) DEF_CLR_API(isRIDClassDomainID) DEF_CLR_API(getClassDomainID) -DEF_CLR_API(getReadonlyStaticFieldValue) +DEF_CLR_API(getStaticFieldContent) +DEF_CLR_API(getObjectContent) DEF_CLR_API(getStaticFieldCurrentClass) DEF_CLR_API(getVarArgsHandle) DEF_CLR_API(canGetVarArgsHandle) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 1b3aa470acf333..b819fc12fbce13 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -793,16 +793,6 @@ bool WrapICorJitInfo::canCast( return temp; } -bool WrapICorJitInfo::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - API_ENTER(areTypesEquivalent); - bool temp = wrapHnd->areTypesEquivalent(cls1, cls2); - API_LEAVE(areTypesEquivalent); - return temp; -} - TypeCompareState WrapICorJitInfo::compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) @@ -1522,16 +1512,28 @@ unsigned WrapICorJitInfo::getClassDomainID( return temp; } -bool WrapICorJitInfo::getReadonlyStaticFieldValue( +bool WrapICorJitInfo::getStaticFieldContent( CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) { - API_ENTER(getReadonlyStaticFieldValue); - bool temp = wrapHnd->getReadonlyStaticFieldValue(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); - API_LEAVE(getReadonlyStaticFieldValue); + API_ENTER(getStaticFieldContent); + bool temp = wrapHnd->getStaticFieldContent(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); + API_LEAVE(getStaticFieldContent); + return temp; +} + +bool WrapICorJitInfo::getObjectContent( + CORINFO_OBJECT_HANDLE obj, + uint8_t* buffer, + int bufferSize, + int valueOffset) +{ + API_ENTER(getObjectContent); + bool temp = wrapHnd->getObjectContent(obj, buffer, bufferSize, valueOffset); + API_LEAVE(getObjectContent); return temp; } diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index d7369b3adcce26..50e3b1bb5b1705 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -227,15 +227,6 @@ bool IntegralRange::Contains(int64_t value) const break; #endif // defined(FEATURE_HW_INTRINSICS) - case GT_FIELD: - { - if (node->AsField()->IsSpanLength()) - { - return {SymbolicIntegerValue::Zero, UpperBoundForType(rangeType)}; - } - break; - } - default: break; } @@ -3802,8 +3793,8 @@ GenTree* Compiler::optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, Gen return nullptr; } - // Bail out if tree is not side effect free. - if ((tree->gtFlags & GTF_SIDE_EFFECT) != 0) + // Bail out if op1 is not side effect free. Note we'll be bashing it below, unlike op2. + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) { return nullptr; } diff --git a/src/coreclr/jit/block.cpp b/src/coreclr/jit/block.cpp index ce4415d75c611a..10486bc4d06707 100644 --- a/src/coreclr/jit/block.cpp +++ b/src/coreclr/jit/block.cpp @@ -1662,3 +1662,101 @@ void BasicBlock::unmarkLoopAlign(Compiler* compiler DEBUG_ARG(const char* reason JITDUMP("Unmarking LOOP_ALIGN from " FMT_BB ". Reason= %s.\n", bbNum, reason); } } + +//------------------------------------------------------------------------ +// getCalledCount: get the value used to normalized weights for this method +// +// Arguments: +// compiler - Compiler instance +// +// Notes: +// If we don't have profile data then getCalledCount will return BB_UNITY_WEIGHT (100) +// otherwise it returns the number of times that profile data says the method was called. + +// static +weight_t BasicBlock::getCalledCount(Compiler* comp) +{ + // when we don't have profile data then fgCalledCount will be BB_UNITY_WEIGHT (100) + weight_t calledCount = comp->fgCalledCount; + + // If we haven't yet reach the place where we setup fgCalledCount it could still be zero + // so return a reasonable value to use until we set it. + // + if (calledCount == 0) + { + if (comp->fgIsUsingProfileWeights()) + { + // When we use profile data block counts we have exact counts, + // not multiples of BB_UNITY_WEIGHT (100) + calledCount = 1; + } + else + { + calledCount = comp->fgFirstBB->bbWeight; + + if (calledCount == 0) + { + calledCount = BB_UNITY_WEIGHT; + } + } + } + return calledCount; +} + +//------------------------------------------------------------------------ +// getBBWeight: get the normalized weight of this block +// +// Arguments: +// compiler - Compiler instance +// +// Notes: +// with profie data: number of expected executions of this block, given +// one call to the method +// +weight_t BasicBlock::getBBWeight(Compiler* comp) +{ + if (this->bbWeight == BB_ZERO_WEIGHT) + { + return BB_ZERO_WEIGHT; + } + else + { + weight_t calledCount = getCalledCount(comp); + + // Normalize the bbWeights by multiplying by BB_UNITY_WEIGHT and dividing by the calledCount. + // + weight_t fullResult = this->bbWeight * BB_UNITY_WEIGHT / calledCount; + + return fullResult; + } +} + +//------------------------------------------------------------------------ +// bbStackDepthOnEntry: return depth of IL stack at block entry +// +unsigned BasicBlock::bbStackDepthOnEntry() const +{ + return (bbEntryState ? bbEntryState->esStackDepth : 0); +} + +//------------------------------------------------------------------------ +// bbSetStack: update IL stack for block entry +// +// Arguments; +// stack - new stack for block +// +void BasicBlock::bbSetStack(StackEntry* stack) +{ + assert(bbEntryState); + assert(stack); + bbEntryState->esStack = stack; +} + +//------------------------------------------------------------------------ +// bbStackOnEntry: fetch IL stack for block entry +// +StackEntry* BasicBlock::bbStackOnEntry() const +{ + assert(bbEntryState); + return bbEntryState->esStack; +} diff --git a/src/coreclr/jit/block.h b/src/coreclr/jit/block.h index 1b7e8d665a3288..748ac2229e1ac6 100644 --- a/src/coreclr/jit/block.h +++ b/src/coreclr/jit/block.h @@ -1230,7 +1230,7 @@ struct BasicBlock : private LIR::Range #endif // DEBUG unsigned bbStackDepthOnEntry() const; - void bbSetStack(void* stackBuffer); + void bbSetStack(StackEntry* stack); StackEntry* bbStackOnEntry() const; // "bbNum" is one-based (for unknown reasons); it is sometimes useful to have the corresponding diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 6bf8954b525080..9afb6ad0afb24d 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -46,6 +46,9 @@ class CodeGen final : public CodeGenInterface CORINFO_FIELD_HANDLE absBitmaskFlt; CORINFO_FIELD_HANDLE absBitmaskDbl; + // Bit mask used in zeroing the 3rd element of a SIMD12 + CORINFO_FIELD_HANDLE zroSimd12Elm3; + // Bit mask used in U8 -> double conversion to adjust the result. CORINFO_FIELD_HANDLE u8ToDblBitmask; @@ -777,6 +780,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #endif void genSetRegToConst(regNumber targetReg, var_types targetType, GenTree* tree); +#if defined(FEATURE_SIMD) + void genSetRegToConst(regNumber targetReg, var_types targetType, simd_t* val); +#endif void genCodeForTreeNode(GenTree* treeNode); void genCodeForBinary(GenTreeOp* treeNode); @@ -925,6 +931,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genSimdUpperSave(GenTreeIntrinsic* node); void genSimdUpperRestore(GenTreeIntrinsic* node); + void genSimd12UpperClear(regNumber tgtReg); + // TYP_SIMD12 (i.e Vector3 of size 12 bytes) is not a hardware supported size and requires // two reads/writes on 64-bit targets. These routines abstract reading/writing of Vector3 // values through an indirection. Note that Vector3 locals allocated on stack would have @@ -956,6 +964,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr); void genHWIntrinsic_R_R_R_RM( instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTree* op3); + void genHWIntrinsic_R_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, int8_t ival); void genBaseIntrinsic(GenTreeHWIntrinsic* node); void genX86BaseIntrinsic(GenTreeHWIntrinsic* node); void genSSEIntrinsic(GenTreeHWIntrinsic* node); @@ -1237,10 +1246,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX BasicBlock* genCallFinally(BasicBlock* block); #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) // TODO: refactor for LA. - void genCodeForJumpCompare(GenTreeOp* tree); + void genCodeForJumpCompare(GenTreeOpCC* tree); #endif #if defined(TARGET_ARM64) - void genCodeForJumpCompare(GenTreeOp* tree); + void genCodeForJumpCompare(GenTreeOpCC* tree); void genCodeForBfiz(GenTreeOp* tree); void genCodeForCond(GenTreeOp* tree); #endif // TARGET_ARM64 @@ -1532,6 +1541,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void inst_RV_RV_IV(instruction ins, emitAttr size, regNumber reg1, regNumber reg2, unsigned ival); void inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenTree* rmOp, int ival); void inst_RV_RV_TT(instruction ins, emitAttr size, regNumber targetReg, regNumber op1Reg, GenTree* op2, bool isRMW); + void inst_RV_RV_TT_IV( + instruction ins, emitAttr size, regNumber targetReg, regNumber op1Reg, GenTree* op2, int8_t ival, bool isRMW); #endif void inst_set_SV_var(GenTree* tree); diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 15e47ad6c346f6..256b766679545d 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -3369,13 +3369,40 @@ void CodeGen::genCodeForNegNot(GenTree* tree) // The src must be a register. if (tree->OperIs(GT_NEG) && operand->isContained()) { - ins = INS_mneg; - GenTree* op1 = tree->gtGetOp1(); - GenTree* a = op1->gtGetOp1(); - GenTree* b = op1->gtGetOp2(); - genConsumeRegs(op1); - assert(op1->OperGet() == GT_MUL); - GetEmitter()->emitIns_R_R_R(ins, emitActualTypeSize(tree), targetReg, a->GetRegNum(), b->GetRegNum()); + genTreeOps oper = operand->OperGet(); + switch (oper) + { + case GT_MUL: + { + ins = INS_mneg; + GenTree* op1 = tree->gtGetOp1(); + GenTree* a = op1->gtGetOp1(); + GenTree* b = op1->gtGetOp2(); + genConsumeRegs(op1); + GetEmitter()->emitIns_R_R_R(ins, emitActualTypeSize(tree), targetReg, a->GetRegNum(), b->GetRegNum()); + } + break; + + case GT_LSH: + case GT_RSH: + case GT_RSZ: + { + assert(ins == INS_neg || ins == INS_negs); + assert(operand->gtGetOp2()->IsCnsIntOrI()); + assert(operand->gtGetOp2()->isContained()); + + GenTree* op1 = tree->gtGetOp1(); + GenTree* a = op1->gtGetOp1(); + GenTree* b = op1->gtGetOp2(); + genConsumeRegs(op1); + GetEmitter()->emitIns_R_R_I(ins, emitActualTypeSize(tree), targetReg, a->GetRegNum(), + b->AsIntConCommon()->IntegralValue(), ShiftOpToInsOpts(oper)); + } + break; + + default: + unreached(); + } } else { @@ -4534,12 +4561,57 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) } else if (op2->isContained()) { - assert(op2->OperIs(GT_LSH, GT_RSH, GT_RSZ)); - assert(op2->gtGetOp2()->IsCnsIntOrI()); - assert(op2->gtGetOp2()->isContained()); + genTreeOps oper = op2->OperGet(); + switch (oper) + { + case GT_NEG: + assert(ins == INS_cmp); + + ins = INS_cmn; + oper = op2->gtGetOp1()->OperGet(); + if (op2->gtGetOp1()->isContained()) + { + switch (oper) + { + case GT_LSH: + case GT_RSH: + case GT_RSZ: + { + GenTree* shiftOp1 = op2->gtGetOp1()->gtGetOp1(); + GenTree* shiftOp2 = op2->gtGetOp1()->gtGetOp2(); + + assert(shiftOp2->IsCnsIntOrI()); + assert(shiftOp2->isContained()); + + emit->emitIns_R_R_I(ins, cmpSize, op1->GetRegNum(), shiftOp1->GetRegNum(), + shiftOp2->AsIntConCommon()->IntegralValue(), + ShiftOpToInsOpts(oper)); + } + break; + + default: + unreached(); + } + } + else + { + emit->emitIns_R_R(ins, cmpSize, op1->GetRegNum(), op2->gtGetOp1()->GetRegNum()); + } + break; + + case GT_LSH: + case GT_RSH: + case GT_RSZ: + assert(op2->gtGetOp2()->IsCnsIntOrI()); + assert(op2->gtGetOp2()->isContained()); - emit->emitIns_R_R_I(ins, cmpSize, op1->GetRegNum(), op2->gtGetOp1()->GetRegNum(), - op2->gtGetOp2()->AsIntConCommon()->IntegralValue(), ShiftOpToInsOpts(op2->gtOper)); + emit->emitIns_R_R_I(ins, cmpSize, op1->GetRegNum(), op2->gtGetOp1()->GetRegNum(), + op2->gtGetOp2()->AsIntConCommon()->IntegralValue(), ShiftOpToInsOpts(oper)); + break; + + default: + unreached(); + } } else { @@ -4736,9 +4808,9 @@ void CodeGen::genCodeForCinc(GenTreeOp* cinc) } //------------------------------------------------------------------------ -// genCodeForJumpCompare: Generates code for jmpCompare statement. +// genCodeForJumpCompare: Generates code for a GT_JCMP or GT_JTEST statement. // -// A GT_JCMP node is created when a comparison and conditional branch +// A GT_JCMP/GT_JTEST node is created when a comparison and conditional branch // can be executed in a single instruction. // // Arm64 has a few instructions with this behavior. @@ -4759,42 +4831,43 @@ void CodeGen::genCodeForCinc(GenTreeOp* cinc) // This node is responsible for consuming the register, and emitting the // appropriate fused compare/test and branch instruction // -// Two flags guide code generation -// GTF_JCMP_TST -- Set if this is a tbz/tbnz rather than cbz/cbnz -// GTF_JCMP_EQ -- Set if this is cbz/tbz rather than cbnz/tbnz -// // Arguments: -// tree - The GT_JCMP tree node. +// tree - The GT_JCMP/GT_JTEST tree node. // // Return Value: // None // -void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) +void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree) { assert(compiler->compCurBB->bbJumpKind == BBJ_COND); GenTree* op1 = tree->gtGetOp1(); GenTree* op2 = tree->gtGetOp2(); - assert(tree->OperIs(GT_JCMP)); + assert(tree->OperIs(GT_JCMP, GT_JTEST)); assert(!varTypeIsFloating(tree)); assert(!op1->isUsedFromMemory()); assert(!op2->isUsedFromMemory()); assert(op2->IsCnsIntOrI()); assert(op2->isContained()); + GenCondition cc = tree->gtCondition; + + // For ARM64 we only expect equality comparisons. + assert((cc.GetCode() == GenCondition::EQ) || (cc.GetCode() == GenCondition::NE)); + genConsumeOperands(tree); regNumber reg = op1->GetRegNum(); emitAttr attr = emitActualTypeSize(op1->TypeGet()); - if (tree->gtFlags & GTF_JCMP_TST) + if (tree->OperIs(GT_JTEST)) { ssize_t compareImm = op2->AsIntCon()->IconValue(); assert(isPow2(((size_t)compareImm))); - instruction ins = (tree->gtFlags & GTF_JCMP_EQ) ? INS_tbz : INS_tbnz; + instruction ins = (cc.GetCode() == GenCondition::EQ) ? INS_tbz : INS_tbnz; int imm = genLog2((size_t)compareImm); GetEmitter()->emitIns_J_R_I(ins, attr, compiler->compCurBB->bbJumpDest, reg, imm); @@ -4803,7 +4876,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) { assert(op2->IsIntegralConst(0)); - instruction ins = (tree->gtFlags & GTF_JCMP_EQ) ? INS_cbz : INS_cbnz; + instruction ins = (cc.GetCode() == GenCondition::EQ) ? INS_cbz : INS_cbnz; GetEmitter()->emitIns_J_R(ins, attr, compiler->compCurBB->bbJumpDest, reg); } diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index aa440f70ff8cc1..b3fc4bb6cf9c18 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -369,7 +369,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) break; case GT_JCMP: - genCodeForJumpCompare(treeNode->AsOp()); + case GT_JTEST: + genCodeForJumpCompare(treeNode->AsOpCC()); break; case GT_CCMP: diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 0133175b5df32f..c0aa4c78f726bf 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -85,6 +85,7 @@ CodeGen::CodeGen(Compiler* theCompiler) : CodeGenInterface(theCompiler) negBitmaskDbl = nullptr; absBitmaskFlt = nullptr; absBitmaskDbl = nullptr; + zroSimd12Elm3 = nullptr; u8ToDblBitmask = nullptr; #endif // defined(TARGET_XARCH) @@ -4474,7 +4475,7 @@ void CodeGen::genZeroInitFltRegs(const regMaskTP& initFltRegs, const regMaskTP& } #elif defined(TARGET_XARCH) // XORPS is the fastest and smallest way to initialize a XMM register to zero. - inst_RV_RV(INS_xorps, reg, reg, TYP_DOUBLE); + GetEmitter()->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, reg, reg, reg); dblInitReg = reg; #elif defined(TARGET_ARM64) // We will just zero out the entire vector register. This sets it to a double/float zero value @@ -4514,7 +4515,7 @@ void CodeGen::genZeroInitFltRegs(const regMaskTP& initFltRegs, const regMaskTP& } #elif defined(TARGET_XARCH) // XORPS is the fastest and smallest way to initialize a XMM register to zero. - inst_RV_RV(INS_xorps, reg, reg, TYP_DOUBLE); + GetEmitter()->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, reg, reg, reg); fltInitReg = reg; #elif defined(TARGET_ARM64) // We will just zero out the entire vector register. This sets it to a double/float zero value @@ -5969,6 +5970,7 @@ void CodeGen::genFnProlog() genEstablishFramePointer(compiler->codeGen->genSPtoFPdelta(), reportUnwindData); } #endif // TARGET_AMD64 + compiler->unwindEndProlog(); //------------------------------------------------------------------------- // @@ -6296,7 +6298,6 @@ void CodeGen::genFnProlog() #endif // defined(DEBUG) && defined(TARGET_XARCH) GetEmitter()->emitEndProlog(); - compiler->unwindEndProlog(); } #ifdef _PREFAST_ #pragma warning(pop) diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index 87f16974bcfcc6..f74699caf7e6bd 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -2580,183 +2580,168 @@ void CodeGen::genCodeForDivMod(GenTreeOp* tree) assert(varTypeIsFloating(tree->gtOp1)); assert(varTypeIsFloating(tree->gtOp2)); assert(tree->gtOper == GT_DIV); - // genCodeForBinary(tree); + instruction ins = genGetInsForOper(tree); emit->emitIns_R_R_R(ins, emitActualTypeSize(targetType), tree->GetRegNum(), tree->gtOp1->GetRegNum(), tree->gtOp2->GetRegNum()); } - else // an integer divide operation + else // an integer divide operation. { - GenTree* divisorOp = tree->gtGetOp2(); + GenTree* divisorOp = tree->gtGetOp2(); + regNumber divisorReg = divisorOp->GetRegNum(); + // divisorOp can be immed or reg + assert(!tree->gtOp1->isContained() && !tree->gtOp1->isContainedIntOrIImmed()); assert(!divisorOp->isContained() || divisorOp->isContainedIntOrIImmed()); - if (divisorOp->IsIntegralConst(0) || divisorOp->GetRegNum() == REG_R0) - { - // We unconditionally throw a divide by zero exception - genJumpToThrowHlpBlk(EJ_jmp, SCK_DIV_BY_ZERO); - } - else // the divisor is not the constant zero - { - GenTree* src1 = tree->gtOp1; - unsigned TypeSize = genTypeSize(genActualType(tree->TypeGet())); - emitAttr size = EA_ATTR(TypeSize); + ExceptionSetFlags exSetFlags = tree->OperExceptions(compiler); - assert(TypeSize >= genTypeSize(genActualType(src1->TypeGet())) && - TypeSize >= genTypeSize(genActualType(divisorOp->TypeGet()))); - - // ssize_t intConstValue = divisorOp->AsIntCon()->gtIconVal; - regNumber Reg1 = src1->GetRegNum(); - regNumber divisorReg = divisorOp->GetRegNum(); - instruction ins; - - // Check divisorOp first as we can always allow it to be a contained immediate - if (divisorOp->isContainedIntOrIImmed()) - { - ssize_t intConst = (int)(divisorOp->AsIntCon()->gtIconVal); - divisorReg = REG_R21; - emit->emitIns_I_la(EA_PTRSIZE, REG_R21, intConst); - } - // Only for commutative operations do we check src1 and allow it to be a contained immediate - else if (tree->OperIsCommutative()) + if ((exSetFlags & ExceptionSetFlags::DivideByZeroException) != ExceptionSetFlags::None) + { + if (divisorOp->IsIntegralConst(0) || (divisorReg == REG_R0)) { - // src1 can be immed or reg - assert(!src1->isContained() || src1->isContainedIntOrIImmed()); + // We unconditionally throw a divide by zero exception + genJumpToThrowHlpBlk(EJ_jmp, SCK_DIV_BY_ZERO); - // Check src1 and allow it to be a contained immediate - if (src1->isContainedIntOrIImmed()) - { - assert(!divisorOp->isContainedIntOrIImmed()); - ssize_t intConst = (int)(src1->AsIntCon()->gtIconVal); - Reg1 = REG_R21; - emit->emitIns_I_la(EA_PTRSIZE, REG_R21, intConst); - } + // We still need to call genProduceReg + genProduceReg(tree); + + return; } else { - // src1 can only be a reg - assert(!src1->isContained()); + assert(emitter::isGeneralRegister(divisorReg)); + + // Check if the divisor is zero throw a DivideByZeroException + genJumpToThrowHlpBlk_la(SCK_DIV_BY_ZERO, INS_beq, divisorReg); } + } + + GenTree* src1 = tree->gtOp1; + emitAttr size = EA_ATTR(genTypeSize(genActualType(tree->TypeGet()))); + + assert(!divisorOp->IsIntegralConst(0)); - // Generate the require runtime checks for GT_DIV or GT_UDIV - if (tree->gtOper == GT_DIV || tree->gtOper == GT_MOD) + regNumber Reg1 = src1->GetRegNum(); + instruction ins; + + // Check divisorOp first as we can always allow it to be a contained immediate + if (divisorOp->isContainedIntOrIImmed()) + { + ssize_t intConst = (int)(divisorOp->AsIntCon()->gtIconVal); + divisorReg = emitter::isGeneralRegister(divisorReg) ? divisorReg : REG_R21; + emit->emitIns_I_la(EA_PTRSIZE, divisorReg, intConst); + } + else + { + // src1 can only be a reg + assert(!src1->isContained()); + assert(emitter::isGeneralRegister(Reg1)); + assert(emitter::isGeneralRegister(divisorReg)); + } + + // check (MinInt / -1) => ArithmeticException + if (tree->gtOper == GT_DIV || tree->gtOper == GT_MOD) + { + if ((exSetFlags & ExceptionSetFlags::ArithmeticException) != ExceptionSetFlags::None) { - // Two possible exceptions: - // (AnyVal / 0) => DivideByZeroException - // (MinInt / -1) => ArithmeticException - // - bool checkDividend = true; + // Check if the divisor is not -1 branch to 'sdivLabel' + emit->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SCRATCH, REG_R0, -1); + BasicBlock* sdivLabel = genCreateTempLabel(); // can optimize for loongarch64. + emit->emitIns_J_cond_la(INS_bne, sdivLabel, REG_SCRATCH, divisorReg); + + // If control flow continues past here the 'divisorReg' is known to be -1 + regNumber dividendReg = tree->gtGetOp1()->GetRegNum(); - // Do we have an immediate for the 'divisorOp'? + // At this point the divisor is known to be -1 + // + // Whether dividendReg is MinInt or not // - if (divisorOp->IsCnsIntOrI()) + if (size == EA_4BYTE) { - ssize_t intConstValue = divisorOp->AsIntCon()->gtIconVal; - // assert(intConstValue != 0); // already checked above by IsIntegralConst(0) - if (intConstValue != -1) - { - checkDividend = false; // We statically know that the dividend is not -1 - } + // MinInt=0x80000000 + emit->emitIns_R_R_I(INS_slli_w, EA_4BYTE, REG_SCRATCH, REG_SCRATCH, 31); } - else // insert check for division by zero + else { - // Check if the divisor is zero throw a DivideByZeroException - genJumpToThrowHlpBlk_la(SCK_DIV_BY_ZERO, INS_beq, divisorReg); + assert(size == EA_8BYTE); + // MinInt=0x8000000000000000 + emit->emitIns_R_R_I(INS_slli_d, EA_8BYTE, REG_SCRATCH, REG_SCRATCH, 63); } + genJumpToThrowHlpBlk_la(SCK_ARITH_EXCPN, INS_beq, REG_SCRATCH, nullptr, dividendReg); + genDefineTempLabel(sdivLabel); + } - if (checkDividend) + // Generate the sdiv instruction + if (size == EA_4BYTE) + { + if (tree->OperGet() == GT_DIV) { - // Check if the divisor is not -1 branch to 'sdivLabel' - emit->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_R21, REG_R0, -1); - BasicBlock* sdivLabel = genCreateTempLabel(); // can optimize for loongarch64. - emit->emitIns_J_cond_la(INS_bne, sdivLabel, REG_R21, divisorReg); - - // If control flow continues past here the 'divisorReg' is known to be -1 - regNumber dividendReg = tree->gtGetOp1()->GetRegNum(); - // At this point the divisor is known to be -1 - // - // Whether dividendReg is MinInt or not - // - - emit->emitIns_J_cond_la(INS_beq, sdivLabel, dividendReg, REG_R0); - - emit->emitIns_R_R_R(size == EA_4BYTE ? INS_add_w : INS_add_d, size, REG_R21, dividendReg, - dividendReg); - genJumpToThrowHlpBlk_la(SCK_ARITH_EXCPN, INS_beq, REG_R21); - genDefineTempLabel(sdivLabel); + ins = INS_div_w; } - - // Generate the sdiv instruction - if (size == EA_4BYTE) + else { - if (tree->OperGet() == GT_DIV) - { - ins = INS_div_w; - } - else - { - ins = INS_mod_w; - } + ins = INS_mod_w; + } + } + else + { + if (tree->OperGet() == GT_DIV) + { + ins = INS_div_d; } else { - if (tree->OperGet() == GT_DIV) - { - ins = INS_div_d; - } - else - { - ins = INS_mod_d; - } + ins = INS_mod_d; } - - emit->emitIns_R_R_R(ins, size, tree->GetRegNum(), Reg1, divisorReg); } - else // if (tree->gtOper == GT_UDIV) GT_UMOD + + emit->emitIns_R_R_R(ins, size, tree->GetRegNum(), Reg1, divisorReg); + } + else // if (tree->gtOper == GT_UDIV) GT_UMOD + { + // Only one possible exception + // (AnyVal / 0) => DivideByZeroException + // + // Note that division by the constant 0 was already checked for above by the + // op2->IsIntegralConst(0) check + // + + if (!divisorOp->IsCnsIntOrI()) { - // Only one possible exception - // (AnyVal / 0) => DivideByZeroException - // - // Note that division by the constant 0 was already checked for above by the - // op2->IsIntegralConst(0) check + // divisorOp is not a constant, so it could be zero // + genJumpToThrowHlpBlk_la(SCK_DIV_BY_ZERO, INS_beq, divisorReg); + } - if (!divisorOp->IsCnsIntOrI()) + if (size == EA_4BYTE) + { + if (tree->OperGet() == GT_UDIV) { - // divisorOp is not a constant, so it could be zero - // - genJumpToThrowHlpBlk_la(SCK_DIV_BY_ZERO, INS_beq, divisorReg); + ins = INS_div_wu; } - - if (size == EA_4BYTE) + else { - if (tree->OperGet() == GT_UDIV) - { - ins = INS_div_wu; - } - else - { - ins = INS_mod_wu; - } + ins = INS_mod_wu; + } - // TODO-LOONGARCH64: here is just for signed-extension ? - emit->emitIns_R_R_I(INS_slli_w, EA_4BYTE, Reg1, Reg1, 0); - emit->emitIns_R_R_I(INS_slli_w, EA_4BYTE, divisorReg, divisorReg, 0); + // TODO-LOONGARCH64: here is just for signed-extension ? + emit->emitIns_R_R_I(INS_slli_w, EA_4BYTE, Reg1, Reg1, 0); + emit->emitIns_R_R_I(INS_slli_w, EA_4BYTE, divisorReg, divisorReg, 0); + } + else + { + if (tree->OperGet() == GT_UDIV) + { + ins = INS_div_du; } else { - if (tree->OperGet() == GT_UDIV) - { - ins = INS_div_du; - } - else - { - ins = INS_mod_du; - } + ins = INS_mod_du; } - - emit->emitIns_R_R_R(ins, size, tree->GetRegNum(), Reg1, divisorReg); } + + emit->emitIns_R_R_R(ins, size, tree->GetRegNum(), Reg1, divisorReg); } } genProduceReg(tree); @@ -4326,7 +4311,7 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) // genCodeForJumpCompare: Generates code for jmpCompare statement. // // A GT_JCMP node is created for an integer-comparison's conditional branch. -void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) +void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree) { assert(compiler->compCurBB->bbJumpKind == BBJ_COND); @@ -4352,10 +4337,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) instruction ins = INS_invalid; int regs = 0; - int cond = ((int)tree->gtFlags >> 25) & 0xf; // GenCondition::Code. - assert((((int)tree->gtFlags >> 25) & GenCondition::Float) == 0); - - bool IsUnsigned = (cond & GenCondition::Unsigned) != 0; + GenCondition cond = tree->gtCondition; emitAttr cmpSize = EA_ATTR(genTypeSize(op1Type)); regNumber regOp1 = op1->GetRegNum(); @@ -4369,7 +4351,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) switch (cmpSize) { case EA_4BYTE: - if (IsUnsigned) + if (cond.IsUnsigned()) { imm = static_cast(imm); @@ -4386,7 +4368,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) case EA_8BYTE: break; case EA_1BYTE: - if (IsUnsigned) + if (cond.IsUnsigned()) { imm = static_cast(imm); } @@ -4403,7 +4385,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) regs = (int)REG_RA << 5; } - switch (cond) + switch (cond.GetCode()) { case GenCondition::EQ: regs |= ((int)regOp1); @@ -4416,22 +4398,22 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) case GenCondition::UGE: case GenCondition::SGE: regs |= ((int)regOp1); - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; case GenCondition::UGT: case GenCondition::SGT: regs = imm ? ((((int)regOp1) << 5) | (int)REG_RA) : (((int)regOp1) << 5); - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULT: case GenCondition::SLT: regs |= ((int)regOp1); - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULE: case GenCondition::SLE: regs = imm ? ((((int)regOp1) << 5) | (int)REG_RA) : (((int)regOp1) << 5); - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; default: NO_WAY("unexpected condition type"); @@ -4448,7 +4430,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) assert(regOp1 != tmpRegOp2); assert(regOp2 != tmpRegOp2); - if (IsUnsigned) + if (cond.IsUnsigned()) { emit->emitIns_R_R_I_I(INS_bstrpick_d, EA_8BYTE, tmpRegOp1, regOp1, 31, 0); emit->emitIns_R_R_I_I(INS_bstrpick_d, EA_8BYTE, tmpRegOp2, regOp2, 31, 0); @@ -4463,7 +4445,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) regOp2 = tmpRegOp2; } - switch (cond) + switch (cond.GetCode()) { case GenCondition::EQ: regs = (((int)regOp1) << 5) | (int)regOp2; @@ -4476,22 +4458,22 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) case GenCondition::UGE: case GenCondition::SGE: regs = ((int)regOp1 | ((int)regOp2 << 5)); - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; case GenCondition::UGT: case GenCondition::SGT: regs = (((int)regOp1) << 5) | (int)regOp2; - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULT: case GenCondition::SLT: regs = ((int)regOp1 | ((int)regOp2 << 5)); - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULE: case GenCondition::SLE: regs = (((int)regOp1) << 5) | (int)regOp2; - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; default: NO_WAY("unexpected condition type-regs"); @@ -5085,12 +5067,15 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) assert((tgtBlock->bbTgtStkDepth * sizeof(int) == genStackLevel) || isFramePointerUsed()); #endif // !FEATURE_FIXED_OUT_ARGS - emit->emitIns_J(INS_bcnez, tgtBlock, (int)1 /* cc */); + GenTreeCC* jcc = treeNode->AsCC(); + assert(jcc->gtCondition.Is(GenCondition::EQ, GenCondition::NE)); + instruction ins = jcc->gtCondition.Is(GenCondition::EQ) ? INS_bceqz : INS_bcnez; + emit->emitIns_J(ins, tgtBlock, (int)1 /* cc */); } break; case GT_JCMP: - genCodeForJumpCompare(treeNode->AsOp()); + genCodeForJumpCompare(treeNode->AsOpCC()); break; case GT_RETURNTRAP: @@ -8575,7 +8560,7 @@ void CodeGen::genFnPrologCalleeRegArgs() unsigned varNum; unsigned regArgMaskIsInt = 0; - unsigned regArgNum = 0; + int regArgNum = 0; // Process any circular dependencies unsigned regArg[MAX_REG_ARG * 2] = {0}; unsigned regArgInit[MAX_REG_ARG * 2] = {0}; @@ -8925,75 +8910,83 @@ void CodeGen::genFnPrologCalleeRegArgs() assert(genIsValidIntReg((regNumber)regArg[i])); assert(genIsValidIntReg((regNumber)regArgInit[i])); - regArgNum--; - regArgMaskLive &= ~genRegMask((regNumber)regArg[i]); - if ((regArgMaskIsInt & (1 << regArg[i])) != 0) + unsigned tmpRegs[MAX_REG_ARG] = {0}; + + unsigned tmpArg = regArg[i]; + unsigned nextReg = regArgInit[i] - REG_ARG_FIRST; + + assert(tmpArg <= REG_ARG_LAST); + assert(nextReg < MAX_REG_ARG); + assert(nextReg != i); + + regArg[i] = 0; + int count = 0; + + while (regArg[nextReg] != 0) + { + tmpRegs[count] = nextReg; + nextReg = regArgInit[nextReg] - REG_ARG_FIRST; + assert(nextReg < MAX_REG_ARG); + + for (int count2 = 0; count2 < count; count2++) + { + if (nextReg == tmpRegs[count2]) + { + NYI_LOONGARCH64("-----------CodeGen::genFnPrologCalleeRegArgs() error: intRegs!"); + } + } + + count++; + } + + if (nextReg == i) + { + GetEmitter()->emitIns_R_R_I(INS_ori, EA_PTRSIZE, REG_R21, (regNumber)tmpArg, 0); + regArgMaskLive &= ~genRegMask((regNumber)tmpArg); + assert(count > 0); + } + else if (count == 0) { - ins = INS_slli_w; + tmpRegs[0] = i; + regArg[i] = tmpArg; } else { - ins = INS_ori; + count--; } - if (regArgNum == 0) + do { - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], (regNumber)regArg[i], 0); - break; - } - else if (regArgInit[i] > regArg[i]) + tmpArg = tmpRegs[count]; + + instruction ins = (regArgMaskIsInt & (1 << regArg[tmpArg])) != 0 ? INS_slli_w : INS_ori; + GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[tmpArg], + (regNumber)regArg[tmpArg], 0); + + regArgMaskLive &= ~genRegMask((regNumber)regArg[tmpArg]); + regArg[tmpArg] = 0; + count--; + regArgNum--; + assert(regArgNum >= 0); + } while (count >= 0); + + if (nextReg == i) { - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], (regNumber)regArg[i], 0); + instruction ins = (regArgMaskIsInt & (1 << regArg[i])) != 0 ? INS_slli_w : INS_ori; + GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], REG_R21, 0); + regArgNum--; + assert(regArgNum >= 0); } - else + else if (tmpRegs[0] != i) { - assert(i > 0); - assert(regArgNum > 0); + instruction ins = (regArgMaskIsInt & (1 << (i + REG_ARG_FIRST))) != 0 ? INS_slli_w : INS_ori; + GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], + (regNumber)(i + REG_ARG_FIRST), 0); - int j = regArgInit[i] - REG_ARG_FIRST; - assert((j >= 0) && (j < MAX_REG_ARG)); - if (regArg[j] == 0) - { - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], (regNumber)regArg[i], 0); - } - else - { - int k = regArgInit[j] - REG_ARG_FIRST; - assert((k >= 0) && (k < MAX_REG_ARG)); - instruction ins2 = (regArgMaskIsInt & (1 << regArg[j])) != 0 ? INS_slli_w : INS_ori; - if ((regArg[k] == 0) || (k > i)) - { - GetEmitter()->emitIns_R_R_I(ins2, EA_PTRSIZE, (regNumber)regArgInit[j], - (regNumber)regArg[j], 0); - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], (regNumber)regArg[i], - 0); - regArgNum--; - regArgMaskLive &= ~genRegMask((regNumber)regArg[j]); - if (regArgNum == 0) - { - break; - } - } - else if (k == i) - { - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, REG_R21, (regNumber)regArg[i], 0); - GetEmitter()->emitIns_R_R_I(ins2, EA_PTRSIZE, (regNumber)regArgInit[j], - (regNumber)regArg[j], 0); - GetEmitter()->emitIns_R_R_I(INS_ori, EA_PTRSIZE, (regNumber)regArgInit[i], REG_R21, 0); - regArgNum--; - regArgMaskLive &= ~genRegMask((regNumber)regArg[j]); - regArg[j] = 0; - if (regArgNum == 0) - { - break; - } - } - else - { - NYI_LOONGARCH64("-----------CodeGen::genFnPrologCalleeRegArgs() error!--"); - } - } + regArgMaskLive &= ~genRegMask((regNumber)(i + REG_ARG_FIRST)); + regArgNum--; } + assert(regArgNum >= 0); } } diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 8f9a25ac848814..ea37d8b96ec2bd 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -1278,7 +1278,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre { // A faster/smaller way to generate 0.0 // We will just zero out the entire vector register for both float and double - emit->emitIns_R_R(INS_fmv_d_x, EA_8BYTE, targetReg, REG_R0); + emit->emitIns_R_R(size == EA_4BYTE ? INS_fmv_w_x : INS_fmv_d_x, size, targetReg, REG_R0); } else { @@ -1589,11 +1589,7 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* lclNode) } else // store into register (i.e move into register) { - if (dataReg != targetReg) - { - // Assign into targetReg when dataReg (from op1) is not the same register - inst_Mov(targetType, targetReg, dataReg, true, emitActualTypeSize(targetType)); - } + inst_Mov(targetType, targetReg, dataReg, true); genProduceReg(lclNode); } } @@ -1994,17 +1990,19 @@ void CodeGen::genCodeForNegNot(GenTree* tree) emitAttr attr = emitActualTypeSize(tree); if (tree->OperIs(GT_NEG)) { - if (attr == EA_4BYTE) + if (varTypeIsFloating(targetType)) { - GetEmitter()->emitIns_R_R_R(INS_subw, attr, targetReg, REG_R0, operandReg); + GetEmitter()->emitIns_R_R_R(targetType == TYP_DOUBLE ? INS_fsgnjn_d : INS_fsgnjn_s, attr, targetReg, + operandReg, operandReg); } else { - GetEmitter()->emitIns_R_R_R(INS_sub, attr, targetReg, REG_R0, operandReg); + GetEmitter()->emitIns_R_R_R(attr == EA_4BYTE ? INS_subw : INS_sub, attr, targetReg, REG_R0, operandReg); } } else if (tree->OperIs(GT_NOT)) { + assert(!varTypeIsFloating(targetType)); GetEmitter()->emitIns_R_R_I(INS_xori, attr, targetReg, operandReg, -1); } @@ -2109,6 +2107,7 @@ void CodeGen::genCodeForDivMod(GenTreeOp* tree) // (AnyVal / 0) => DivideByZeroException // (MinInt / -1) => ArithmeticException // + bool checkDividend = true; // Do we have an immediate for the 'divisorOp'? @@ -3298,7 +3297,32 @@ void CodeGen::genFloatToIntCast(GenTree* treeNode) // void CodeGen::genCkfinite(GenTree* treeNode) { - NYI_RISCV64("genCkfinite-----unimplemented/unused on RISCV64 yet----"); + assert(treeNode->OperGet() == GT_CKFINITE); + + GenTree* op1 = treeNode->AsOp()->gtOp1; + var_types targetType = treeNode->TypeGet(); + int expMask = 0x381; // 0b1110000001; + + emitter* emit = GetEmitter(); + emitAttr attr = emitActualTypeSize(treeNode); + + // Extract exponent into a register. + regNumber intReg = treeNode->GetSingleTempReg(); + regNumber fpReg = genConsumeReg(op1); + + emit->emitIns_R_R(attr == EA_4BYTE ? INS_fclass_s : INS_fclass_d, attr, intReg, fpReg); + // Mask of exponent with all 1's and check if the exponent is all 1's + emit->emitIns_R_R_I(INS_andi, EA_PTRSIZE, intReg, intReg, expMask); + // If exponent is all 1's, throw ArithmeticException + genJumpToThrowHlpBlk_la(SCK_ARITH_EXCPN, INS_bne, intReg); + + // if it is a finite value copy it to targetReg + if (treeNode->GetRegNum() != fpReg) + { + inst_Mov(targetType, treeNode->GetRegNum(), fpReg, /* canSkip */ true); + } + + genProduceReg(treeNode); } //------------------------------------------------------------------------ @@ -3327,7 +3351,88 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) if (varTypeIsFloating(op1Type)) { assert(tree->OperIs(GT_LT, GT_LE, GT_EQ, GT_NE, GT_GT, GT_GE)); - NYI_RISCV64("genCodeForCompare-----unimplemented on RISCV64 yet----"); + bool IsUnordered = (tree->gtFlags & GTF_RELOP_NAN_UN) != 0; + regNumber regOp1 = op1->GetRegNum(); + regNumber regOp2 = op2->GetRegNum(); + + if (IsUnordered) + { + BasicBlock* skipLabel = nullptr; + if (tree->OperIs(GT_LT)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp2, regOp1); + } + else if (tree->OperIs(GT_LE)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp2, regOp1); + } + else if (tree->OperIs(GT_EQ)) + { + skipLabel = genCreateTempLabel(); + emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, targetReg, regOp1); + emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, rsGetRsvdReg(), regOp2); + emit->emitIns_R_R_R(INS_or, EA_8BYTE, rsGetRsvdReg(), targetReg, rsGetRsvdReg()); + emit->emitIns_R_R_I(INS_andi, EA_8BYTE, rsGetRsvdReg(), rsGetRsvdReg(), 0x300); + emit->emitIns_R_R_I(INS_addi, EA_8BYTE, targetReg, REG_R0, 1); + emit->emitIns_J(INS_bnez, skipLabel, rsGetRsvdReg()); + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_feq_s : INS_feq_d, cmpSize, targetReg, regOp1, regOp2); + genDefineTempLabel(skipLabel); + } + else if (tree->OperIs(GT_NE)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_feq_s : INS_feq_d, cmpSize, targetReg, regOp1, regOp2); + } + else if (tree->OperIs(GT_GT)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp1, regOp2); + } + else if (tree->OperIs(GT_GE)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp1, regOp2); + } + if (skipLabel == nullptr) + { + emit->emitIns_R_R_R(INS_sub, EA_8BYTE, targetReg, REG_R0, targetReg); + emit->emitIns_R_R_I(INS_addi, EA_8BYTE, targetReg, targetReg, 1); + } + } + else + { + if (tree->OperIs(GT_LT)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp1, regOp2); + } + else if (tree->OperIs(GT_LE)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp1, regOp2); + } + else if (tree->OperIs(GT_EQ)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_feq_s : INS_feq_d, cmpSize, targetReg, regOp1, regOp2); + } + else if (tree->OperIs(GT_NE)) + { + emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, targetReg, regOp1); + emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, rsGetRsvdReg(), regOp2); + emit->emitIns_R_R_R(INS_or, EA_8BYTE, rsGetRsvdReg(), targetReg, rsGetRsvdReg()); + emit->emitIns_R_R_I(INS_andi, EA_8BYTE, rsGetRsvdReg(), rsGetRsvdReg(), 0x300); + emit->emitIns_R_R_I(INS_addi, EA_8BYTE, targetReg, REG_R0, 0); + BasicBlock* skipLabel = genCreateTempLabel(); + emit->emitIns_J(INS_bnez, skipLabel, rsGetRsvdReg()); + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_feq_s : INS_feq_d, cmpSize, targetReg, regOp1, regOp2); + emit->emitIns_R_R_R(INS_sub, EA_8BYTE, targetReg, REG_R0, targetReg); + emit->emitIns_R_R_I(INS_addi, EA_8BYTE, targetReg, targetReg, 1); + genDefineTempLabel(skipLabel); + } + else if (tree->OperIs(GT_GT)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp2, regOp1); + } + else if (tree->OperIs(GT_GE)) + { + emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp2, regOp1); + } + } } else { @@ -3567,11 +3672,12 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) // Return Value: // None // -void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) +void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree) { assert(compiler->compCurBB->bbJumpKind == BBJ_COND); assert(tree->OperIs(GT_JCMP)); + assert(!varTypeIsFloating(tree)); assert(tree->TypeGet() == TYP_VOID); assert(tree->GetRegNum() == REG_NA); @@ -3591,17 +3697,12 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) instruction ins = INS_invalid; int regs = 0; - int cond = ((int)tree->gtFlags >> 25) & 0xf; // GenCondition::Code. - assert((((int)tree->gtFlags >> 25) & GenCondition::Float) == 0); - bool IsUnsigned = (cond & GenCondition::Unsigned) != 0; - emitAttr cmpSize = EA_ATTR(genTypeSize(op1Type)); - regNumber regOp1 = op1->GetRegNum(); + GenCondition cond = tree->gtCondition; - if (varTypeIsFloating(op1Type)) - { - NYI_RISCV64("genCodeForJumpCompare floating-----unimplemented on RISCV64 yet----"); - } - else if (op2->isContainedIntOrIImmed()) + emitAttr cmpSize = EA_ATTR(genTypeSize(op1Type)); + regNumber regOp1 = op1->GetRegNum(); + + if (op2->isContainedIntOrIImmed()) { ssize_t imm = op2->AsIntCon()->gtIconVal; if (imm) @@ -3610,7 +3711,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) switch (cmpSize) { case EA_4BYTE: - if (IsUnsigned) + if (cond.IsUnsigned()) { imm = static_cast(imm); @@ -3635,7 +3736,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) regs = (int)REG_RA << 5; } - switch (cond) + switch (cond.GetCode()) { case GenCondition::EQ: regs |= ((int)regOp1); @@ -3648,22 +3749,22 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) case GenCondition::UGE: case GenCondition::SGE: regs |= ((int)regOp1); - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; case GenCondition::UGT: case GenCondition::SGT: regs = imm ? ((((int)regOp1) << 5) | (int)REG_RA) : (((int)regOp1) << 5); - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULT: case GenCondition::SLT: regs |= ((int)regOp1); - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULE: case GenCondition::SLE: regs = imm ? ((((int)regOp1) << 5) | (int)REG_RA) : (((int)regOp1) << 5); - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; default: NO_WAY("unexpected condition type"); @@ -3680,7 +3781,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) assert(regOp1 != tmpRegOp2); assert(regOp2 != tmpRegOp2); - if (IsUnsigned) + if (cond.IsUnsigned()) { emit->emitIns_R_R_I(INS_slli, EA_8BYTE, tmpRegOp1, regOp1, 32); emit->emitIns_R_R_I(INS_srli, EA_8BYTE, tmpRegOp1, tmpRegOp1, 32); @@ -3697,7 +3798,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) regOp2 = tmpRegOp2; } - switch (cond) + switch (cond.GetCode()) { case GenCondition::EQ: regs = (((int)regOp1) << 5) | (int)regOp2; @@ -3710,22 +3811,22 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree) case GenCondition::UGE: case GenCondition::SGE: regs = ((int)regOp1 | ((int)regOp2 << 5)); - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; case GenCondition::UGT: case GenCondition::SGT: regs = (((int)regOp1) << 5) | (int)regOp2; - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULT: case GenCondition::SLT: regs = ((int)regOp1 | ((int)regOp2 << 5)); - ins = IsUnsigned ? INS_bltu : INS_blt; + ins = cond.IsUnsigned() ? INS_bltu : INS_blt; break; case GenCondition::ULE: case GenCondition::SLE: regs = (((int)regOp1) << 5) | (int)regOp2; - ins = IsUnsigned ? INS_bgeu : INS_bge; + ins = cond.IsUnsigned() ? INS_bgeu : INS_bge; break; default: NO_WAY("unexpected condition type-regs"); @@ -4167,7 +4268,21 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) void CodeGen::genStackPointerConstantAdjustment(ssize_t spDelta, regNumber regTmp) { - NYI_RISCV64("genStackPointerAdjustment-----unimplemented/unused on RISCV64 yet----"); + assert(spDelta < 0); + + // We assert that the SP change is less than one page. If it's greater, you should have called a + // function that does a probe, which will in turn call this function. + assert((target_size_t)(-spDelta) <= compiler->eeGetPageSize()); + + if (emitter::isValidSimm12(spDelta)) + { + GetEmitter()->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, spDelta); + } + else + { + GetEmitter()->emitIns_I_la(EA_PTRSIZE, regTmp, spDelta); + GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, regTmp); + } } //------------------------------------------------------------------------ @@ -4185,7 +4300,8 @@ void CodeGen::genStackPointerConstantAdjustment(ssize_t spDelta, regNumber regTm // void CodeGen::genStackPointerConstantAdjustmentWithProbe(ssize_t spDelta, regNumber regTmp) { - NYI_RISCV64("genStackPointerConstantAdjustmentWithProbe-----unimplemented/unused on RISCV64 yet----"); + GetEmitter()->emitIns_R_R_I(INS_lw, EA_4BYTE, regTmp, REG_SP, 0); + genStackPointerConstantAdjustment(spDelta, regTmp); } //------------------------------------------------------------------------ @@ -4202,8 +4318,35 @@ void CodeGen::genStackPointerConstantAdjustmentWithProbe(ssize_t spDelta, regNum // target_ssize_t CodeGen::genStackPointerConstantAdjustmentLoopWithProbe(ssize_t spDelta, regNumber regTmp) { - NYI_RISCV64("genStackPointerConstantAdjustmentLoopWithProbe-----unimplemented/unused on RISCV64 yet----"); - return 0; + assert(spDelta < 0); + + const target_size_t pageSize = compiler->eeGetPageSize(); + + ssize_t spRemainingDelta = spDelta; + do + { + ssize_t spOneDelta = -(ssize_t)min((target_size_t)-spRemainingDelta, pageSize); + genStackPointerConstantAdjustmentWithProbe(spOneDelta, regTmp); + spRemainingDelta -= spOneDelta; + } while (spRemainingDelta < 0); + + // What offset from the final SP was the last probe? This depends on the fact that + // genStackPointerConstantAdjustmentWithProbe() probes first, then does "SUB SP". + target_size_t lastTouchDelta = (target_size_t)(-spDelta) % pageSize; + if ((lastTouchDelta == 0) || (lastTouchDelta + STACK_PROBE_BOUNDARY_THRESHOLD_BYTES > pageSize)) + { + // We haven't probed almost a complete page. If lastTouchDelta==0, then spDelta was an exact + // multiple of pageSize, which means we last probed exactly one page back. Otherwise, we probed + // the page, but very far from the end. If the next action on the stack might subtract from SP + // first, before touching the current SP, then we do one more probe at the very bottom. This can + // happen on x86, for example, when we copy an argument to the stack using a "SUB ESP; REP MOV" + // strategy. + + GetEmitter()->emitIns_R_R_I(INS_lw, EA_4BYTE, regTmp, REG_SP, 0); + lastTouchDelta = 0; + } + + return lastTouchDelta; } //------------------------------------------------------------------------ @@ -4421,7 +4564,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) break; case GT_JCMP: - genCodeForJumpCompare(treeNode->AsOp()); + genCodeForJumpCompare(treeNode->AsOpCC()); break; case GT_RETURNTRAP: @@ -4829,9 +4972,9 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) addrNode = source->AsOp()->gtOp1; - // addrNode can either be a GT_LCL_ADDR or an address expression + // addrNode can either be a GT_LCL_ADDR<0> or an address expression // - if (addrNode->OperGet() == GT_LCL_ADDR) + if (addrNode->IsLclVarAddr()) { // We have a GT_BLK(GT_LCL_ADDR<0>) // @@ -5022,7 +5165,200 @@ void CodeGen::genPutArgReg(GenTreeOp* tree) // void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) { - NYI_RISCV64("genPutArgSplit-----unimplemented/unused on RISCV64 yet----"); + assert(treeNode->OperIs(GT_PUTARG_SPLIT)); + + GenTree* source = treeNode->gtOp1; + emitter* emit = GetEmitter(); + unsigned varNumOut = compiler->lvaOutgoingArgSpaceVar; + unsigned argOffsetMax = compiler->lvaOutgoingArgSpaceSize; + + if (source->OperGet() == GT_FIELD_LIST) + { + // Evaluate each of the GT_FIELD_LIST items into their register + // and store their register into the outgoing argument area + unsigned regIndex = 0; + unsigned firstOnStackOffs = UINT_MAX; + + for (GenTreeFieldList::Use& use : source->AsFieldList()->Uses()) + { + GenTree* nextArgNode = use.GetNode(); + regNumber fieldReg = nextArgNode->GetRegNum(); + genConsumeReg(nextArgNode); + + if (regIndex >= treeNode->gtNumRegs) + { + if (firstOnStackOffs == UINT_MAX) + { + firstOnStackOffs = use.GetOffset(); + } + var_types type = nextArgNode->TypeGet(); + emitAttr attr = emitTypeSize(type); + + unsigned offset = treeNode->getArgOffset() + use.GetOffset() - firstOnStackOffs; + // We can't write beyond the outgoing arg area + assert(offset + EA_SIZE_IN_BYTES(attr) <= argOffsetMax); + + // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing + // argument area + emit->emitIns_S_R(ins_Store(type), attr, fieldReg, varNumOut, offset); + } + else + { + var_types type = treeNode->GetRegType(regIndex); + regNumber argReg = treeNode->GetRegNumByIdx(regIndex); + + // If child node is not already in the register we need, move it + if (argReg != fieldReg) + { + inst_RV_RV(ins_Copy(type), argReg, fieldReg, type); + } + regIndex++; + } + } + } + else + { + var_types targetType = source->TypeGet(); + assert(source->OperGet() == GT_BLK); + assert(varTypeIsStruct(targetType)); + + regNumber baseReg = treeNode->ExtractTempReg(); + regNumber addrReg = REG_NA; + + GenTreeLclVarCommon* varNode = nullptr; + GenTree* addrNode = nullptr; + + addrNode = source->AsOp()->gtOp1; + + // addrNode can either be a GT_LCL_ADDR<0> or an address expression + // + if (addrNode->IsLclVarAddr()) + { + // We have a GT_BLK(GT_LCL_ADDR<0>) + // + // We will treat this case the same as above + // (i.e if we just had this GT_LCL_VAR directly as the source) + // so update 'source' to point this GT_LCL_ADDR node + // and continue to the codegen for the LCL_VAR node below + // + varNode = addrNode->AsLclVarCommon(); + addrNode = nullptr; + } + + // Either varNode or addrNOde must have been setup above, + // the xor ensures that only one of the two is setup, not both + assert((varNode != nullptr) ^ (addrNode != nullptr)); + + // This is the varNum for our load operations, + // only used when we have a struct with a LclVar source + unsigned srcVarNum = BAD_VAR_NUM; + + if (varNode != nullptr) + { + assert(varNode->isContained()); + srcVarNum = varNode->GetLclNum(); + LclVarDsc* varDsc = compiler->lvaGetDesc(srcVarNum); + + // This struct also must live in the stack frame. + // And it can't live in a register. + assert(varDsc->lvOnFrame && !varDsc->lvRegister); + } + else // addrNode is used + { + addrReg = genConsumeReg(addrNode); + + // If addrReg equal to baseReg, we use the last target register as alternative baseReg. + // Because the candidate mask for the internal baseReg does not include any of the target register, + // we can ensure that baseReg, addrReg, and the last target register are not all same. + assert(baseReg != addrReg); + } + + ClassLayout* layout = source->AsBlk()->GetLayout(); + + // Put on stack first + unsigned structOffset = treeNode->gtNumRegs * TARGET_POINTER_SIZE; + unsigned remainingSize = layout->GetSize() - structOffset; + unsigned argOffsetOut = treeNode->getArgOffset(); + + assert((remainingSize > 0) && (roundUp(remainingSize, TARGET_POINTER_SIZE) == treeNode->GetStackByteSize())); + while (remainingSize > 0) + { + var_types type; + if (remainingSize >= TARGET_POINTER_SIZE) + { + type = layout->GetGCPtrType(structOffset / TARGET_POINTER_SIZE); + } + else if (remainingSize >= 4) + { + type = TYP_INT; + } + else if (remainingSize >= 2) + { + type = TYP_USHORT; + } + else + { + assert(remainingSize == 1); + type = TYP_UBYTE; + } + + emitAttr attr = emitActualTypeSize(type); + unsigned moveSize = genTypeSize(type); + + instruction loadIns = ins_Load(type); + if (varNode != nullptr) + { + // Load from our local source + emit->emitIns_R_S(loadIns, attr, baseReg, srcVarNum, structOffset); + } + else + { + // check for case of destroying the addrRegister while we still need it + assert(baseReg != addrReg); + + // Load from our address expression source + emit->emitIns_R_R_I(loadIns, attr, baseReg, addrReg, structOffset); + } + + // Emit the instruction to store the register into the outgoing argument area + emit->emitIns_S_R(ins_Store(type), attr, baseReg, varNumOut, argOffsetOut); + argOffsetOut += moveSize; + assert(argOffsetOut <= argOffsetMax); + + remainingSize -= moveSize; + structOffset += moveSize; + } + + // We set up the registers in order, so that we assign the last target register `baseReg` is no longer in use, + // in case we had to reuse the last target register for it. + structOffset = 0; + for (unsigned idx = 0; idx < treeNode->gtNumRegs; idx++) + { + regNumber targetReg = treeNode->GetRegNumByIdx(idx); + var_types type = treeNode->GetRegType(idx); + + if (varNode != nullptr) + { + // Load from our local source + emit->emitIns_R_S(ins_Load(type), emitTypeSize(type), targetReg, srcVarNum, structOffset); + } + else + { + // check for case of destroying the addrRegister while we still need it + if (targetReg == addrReg && idx != treeNode->gtNumRegs - 1) + { + assert(targetReg != baseReg); + emit->emitIns_R_R_I(INS_ori, emitActualTypeSize(type), baseReg, addrReg, 0); + addrReg = baseReg; + } + + // Load from our address expression source + emit->emitIns_R_R_I(ins_Load(type), emitTypeSize(type), targetReg, addrReg, structOffset); + } + structOffset += TARGET_POINTER_SIZE; + } + } + genProduceReg(treeNode); } //------------------------------------------------------------------------ @@ -5164,12 +5500,12 @@ void CodeGen::genCodeForShift(GenTree* tree) GetEmitter()->emitIns_R_R_R(INS_sub, size, rsGetRsvdReg(), rsGetRsvdReg(), shiftBy->GetRegNum()); if (size == EA_8BYTE) { - GetEmitter()->emitIns_R_R_R(INS_srl, size, tree->GetRegNum(), operand->GetRegNum(), shiftRight); + GetEmitter()->emitIns_R_R_R(INS_srl, size, REG_RA, operand->GetRegNum(), shiftRight); GetEmitter()->emitIns_R_R_R(INS_sll, size, rsGetRsvdReg(), operand->GetRegNum(), shiftLeft); } else { - GetEmitter()->emitIns_R_R_R(INS_srlw, size, tree->GetRegNum(), operand->GetRegNum(), shiftRight); + GetEmitter()->emitIns_R_R_R(INS_srlw, size, REG_RA, operand->GetRegNum(), shiftRight); GetEmitter()->emitIns_R_R_R(INS_sllw, size, rsGetRsvdReg(), operand->GetRegNum(), shiftLeft); } } @@ -5184,16 +5520,16 @@ void CodeGen::genCodeForShift(GenTree* tree) unsigned shiftLeft = tree->OperIs(GT_ROR) ? immWidth - shiftByImm : shiftByImm; if ((shiftByImm >= 32 && shiftByImm < 64) || size == EA_8BYTE) { - GetEmitter()->emitIns_R_R_I(INS_srli, size, tree->GetRegNum(), operand->GetRegNum(), shiftRight); + GetEmitter()->emitIns_R_R_I(INS_srli, size, REG_RA, operand->GetRegNum(), shiftRight); GetEmitter()->emitIns_R_R_I(INS_slli, size, rsGetRsvdReg(), operand->GetRegNum(), shiftLeft); } else { - GetEmitter()->emitIns_R_R_I(INS_srliw, size, tree->GetRegNum(), operand->GetRegNum(), shiftRight); + GetEmitter()->emitIns_R_R_I(INS_srliw, size, REG_RA, operand->GetRegNum(), shiftRight); GetEmitter()->emitIns_R_R_I(INS_slliw, size, rsGetRsvdReg(), operand->GetRegNum(), shiftLeft); } } - GetEmitter()->emitIns_R_R_R(INS_or, size, tree->GetRegNum(), tree->GetRegNum(), rsGetRsvdReg()); + GetEmitter()->emitIns_R_R_R(INS_or, size, tree->GetRegNum(), REG_RA, rsGetRsvdReg()); } else { @@ -6108,7 +6444,154 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // Therefore the codegen of GT_JMP is to ensure that the callee arguments are correctly setup. void CodeGen::genJmpMethod(GenTree* jmp) { - NYI_RISCV64("genJmpMethod-----unimplemented on RISCV64 yet----"); + assert(jmp->OperGet() == GT_JMP); + assert(compiler->compJmpOpUsed); + + // If no arguments, nothing to do + if (compiler->info.compArgsCount == 0) + { + return; + } + + // Make sure register arguments are in their initial registers + // and stack arguments are put back as well. + unsigned varNum; + LclVarDsc* varDsc; + + // First move any en-registered stack arguments back to the stack. + // At the same time any reg arg not in correct reg is moved back to its stack location. + // + // We are not strictly required to spill reg args that are not in the desired reg for a jmp call + // But that would require us to deal with circularity while moving values around. Spilling + // to stack makes the implementation simple, which is not a bad trade off given Jmp calls + // are not frequent. + for (varNum = 0; varNum < compiler->info.compArgsCount; varNum++) + { + varDsc = compiler->lvaGetDesc(varNum); + + if (varDsc->lvPromoted) + { + noway_assert(varDsc->lvFieldCnt == 1); // We only handle one field here + + unsigned fieldVarNum = varDsc->lvFieldLclStart; + varDsc = compiler->lvaGetDesc(fieldVarNum); + } + noway_assert(varDsc->lvIsParam); + + if (varDsc->lvIsRegArg && (varDsc->GetRegNum() != REG_STK)) + { + // Skip reg args which are already in its right register for jmp call. + // If not, we will spill such args to their stack locations. + // + // If we need to generate a tail call profiler hook, then spill all + // arg regs to free them up for the callback. + if (!compiler->compIsProfilerHookNeeded() && (varDsc->GetRegNum() == varDsc->GetArgReg())) + continue; + } + else if (varDsc->GetRegNum() == REG_STK) + { + // Skip args which are currently living in stack. + continue; + } + + // If we came here it means either a reg argument not in the right register or + // a stack argument currently living in a register. In either case the following + // assert should hold. + assert(varDsc->GetRegNum() != REG_STK); + assert(varDsc->IsEnregisterableLcl()); + var_types storeType = varDsc->GetStackSlotHomeType(); + emitAttr storeSize = emitActualTypeSize(storeType); + + GetEmitter()->emitIns_S_R(ins_Store(storeType), storeSize, varDsc->GetRegNum(), varNum, 0); + + // Update lvRegNum life and GC info to indicate lvRegNum is dead and varDsc stack slot is going live. + // Note that we cannot modify varDsc->GetRegNum() here because another basic block may not be expecting it. + // Therefore manually update life of varDsc->GetRegNum(). + regMaskTP tempMask = genRegMask(varDsc->GetRegNum()); + regSet.RemoveMaskVars(tempMask); + gcInfo.gcMarkRegSetNpt(tempMask); + if (compiler->lvaIsGCTracked(varDsc)) + { + VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varNum); + } + } + +#ifdef PROFILING_SUPPORTED + // At this point all arg regs are free. + // Emit tail call profiler callback. + genProfilingLeaveCallback(CORINFO_HELP_PROF_FCN_TAILCALL); +#endif + + // Next move any un-enregistered register arguments back to their register. + for (varNum = 0; varNum < compiler->info.compArgsCount; varNum++) + { + varDsc = compiler->lvaGetDesc(varNum); + if (varDsc->lvPromoted) + { + noway_assert(varDsc->lvFieldCnt == 1); // We only handle one field here + + unsigned fieldVarNum = varDsc->lvFieldLclStart; + varDsc = compiler->lvaGetDesc(fieldVarNum); + } + noway_assert(varDsc->lvIsParam); + + // Skip if arg not passed in a register. + if (!varDsc->lvIsRegArg) + continue; + + // Register argument + noway_assert(isRegParamType(genActualType(varDsc->TypeGet()))); + + // Is register argument already in the right register? + // If not load it from its stack location. + regNumber argReg = varDsc->GetArgReg(); // incoming arg register + regNumber argRegNext = REG_NA; + + if (varDsc->GetRegNum() != argReg) + { + var_types loadType = TYP_UNDEF; + + if (varTypeIsStruct(varDsc)) + { + // Must be <= 16 bytes or else it wouldn't be passed in registers, except for HFA, + // which can be bigger (and is handled above). + noway_assert(EA_SIZE_IN_BYTES(varDsc->lvSize()) <= 16); + loadType = varDsc->GetLayout()->GetGCPtrType(0); + } + else + { + loadType = compiler->mangleVarArgsType(genActualType(varDsc->TypeGet())); + } + emitAttr loadSize = emitActualTypeSize(loadType); + GetEmitter()->emitIns_R_S(ins_Load(loadType), loadSize, argReg, varNum, 0); + + // Update argReg life and GC Info to indicate varDsc stack slot is dead and argReg is going live. + // Note that we cannot modify varDsc->GetRegNum() here because another basic block may not be + // expecting it. Therefore manually update life of argReg. Note that GT_JMP marks the end of + // the basic block and after which reg life and gc info will be recomputed for the new block + // in genCodeForBBList(). + regSet.AddMaskVars(genRegMask(argReg)); + gcInfo.gcMarkRegPtrVal(argReg, loadType); + + if (compiler->lvaIsMultiregStruct(varDsc, compiler->info.compIsVarArgs)) + { + // Restore the second register. + argRegNext = genRegArgNext(argReg); + + loadType = varDsc->GetLayout()->GetGCPtrType(1); + loadSize = emitActualTypeSize(loadType); + GetEmitter()->emitIns_R_S(ins_Load(loadType), loadSize, argRegNext, varNum, TARGET_POINTER_SIZE); + + regSet.AddMaskVars(genRegMask(argRegNext)); + gcInfo.gcMarkRegPtrVal(argRegNext, loadType); + } + + if (compiler->lvaIsGCTracked(varDsc)) + { + VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex); + } + } + } } //------------------------------------------------------------------------ @@ -6328,8 +6811,8 @@ void CodeGen::genFloatToFloatCast(GenTree* treeNode) if (srcType != dstType) { - instruction ins = (srcType == TYP_FLOAT) ? INS_fcvt_d_w // convert Single to Double - : INS_fcvt_w_d; // convert Double to Single + instruction ins = (srcType == TYP_FLOAT) ? INS_fcvt_d_s // convert Single to Double + : INS_fcvt_s_d; // convert Double to Single GetEmitter()->emitIns_R_R(ins, emitActualTypeSize(treeNode), treeNode->GetRegNum(), op1->GetRegNum()); } @@ -6736,7 +7219,21 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind) // void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FCN_LEAVE*/) { - NYI_RISCV64("genProfilingLeaveCallback-----unimplemented/unused on RISCV64 yet----"); + assert((helper == CORINFO_HELP_PROF_FCN_LEAVE) || (helper == CORINFO_HELP_PROF_FCN_TAILCALL)); + + // Only hook if profiler says it's okay. + if (!compiler->compIsProfilerHookNeeded()) + { + return; + } + + compiler->info.compProfilerCallback = true; + + // Need to save on to the stack level, since the helper call will pop the argument + unsigned saveStackLvl2 = genStackLevel; + + /* Restore the stack level */ + SetStackLevel(saveStackLvl2); } /*----------------------------------------------------------------------------- @@ -7498,6 +7995,29 @@ void CodeGen::genFnPrologCalleeRegArgs() } } + if (regArgNum > 0) + { + for (int i = MAX_REG_ARG - 1; i >= 0; i--) + { + if (regArg[i] > 0 && (regArgInit[i] <= REG_S1 || regArgInit[i] > REG_A7)) + { + instruction ins; + if ((regArgMaskIsInt & (1 << regArg[i])) != 0) + { + ins = INS_slliw; + } + else + { + ins = INS_ori; + } + GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], (regNumber)regArg[i], 0); + regArgMaskLive &= ~genRegMask((regNumber)regArg[i]); + regArg[i] = 0; + regArgNum -= 1; + } + } + } + if (regArgNum > 0) { instruction ins; @@ -7524,7 +8044,7 @@ void CodeGen::genFnPrologCalleeRegArgs() GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], (regNumber)regArg[i], 0); break; } - else if (regArgInit[i] > regArg[i] || (regArgInit[i] >= REG_T0 && regArgInit[i] <= REG_S1)) + else if (regArgInit[i] > regArg[i]) { GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, (regNumber)regArgInit[i], (regNumber)regArg[i], 0); } @@ -7552,10 +8072,6 @@ void CodeGen::genFnPrologCalleeRegArgs() 0); regArgNum--; regArgMaskLive &= ~genRegMask((regNumber)regArg[j]); - if (regArgNum == 0) - { - break; - } } else if (k == i) { @@ -7567,15 +8083,16 @@ void CodeGen::genFnPrologCalleeRegArgs() regArgNum--; regArgMaskLive &= ~genRegMask((regNumber)regArg[j]); regArg[j] = 0; - if (regArgNum == 0) - { - break; - } } else { NYI_RISCV64("-----------CodeGen::genFnPrologCalleeRegArgs() error!--"); } + + if (regArgNum == 0) + { + break; + } } } } diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index b70fa4eae56c25..1988aa632cf35b 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -417,6 +417,123 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regSet.verifyRegUsed(reg); } +#if defined(FEATURE_SIMD) +//---------------------------------------------------------------------------------- +// genSetRegToConst: generate code to set target SIMD register to a given constant value +// +// Arguments: +// targetReg - target SIMD register +// targetType - target's type +// simd_t - constant data (its width depends on type) +// +void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, simd_t* val) +{ + emitter* emit = GetEmitter(); + emitAttr attr = emitTypeSize(targetType); + + switch (targetType) + { + case TYP_SIMD8: + { + simd8_t val8 = *(simd8_t*)val; + if (val8.IsAllBitsSet()) + { + emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, EA_16BYTE, targetReg, targetReg, targetReg); + } + else if (val8.IsZero()) + { + emit->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, targetReg, targetReg, targetReg); + } + else + { + CORINFO_FIELD_HANDLE hnd = emit->emitSimd8Const(val8); + emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); + } + break; + } + case TYP_SIMD12: + { + simd12_t val12 = *(simd12_t*)val; + if (val12.IsAllBitsSet()) + { + emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, EA_16BYTE, targetReg, targetReg, targetReg); + } + else if (val12.IsZero()) + { + emit->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, targetReg, targetReg, targetReg); + } + else + { + simd16_t val16 = {}; + memcpy(&val16, &val12, sizeof(val12)); + CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(val16); + emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); + } + break; + } + case TYP_SIMD16: + { + simd16_t val16 = *(simd16_t*)val; + if (val16.IsAllBitsSet()) + { + emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, attr, targetReg, targetReg, targetReg); + } + else if (val16.IsZero()) + { + emit->emitIns_SIMD_R_R_R(INS_xorps, attr, targetReg, targetReg, targetReg); + } + else + { + CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(val16); + emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); + } + break; + } + case TYP_SIMD32: + { + simd32_t val32 = *(simd32_t*)val; + if (val32.IsAllBitsSet() && compiler->compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, attr, targetReg, targetReg, targetReg); + } + else if (val32.IsZero()) + { + emit->emitIns_SIMD_R_R_R(INS_xorps, attr, targetReg, targetReg, targetReg); + } + else + { + CORINFO_FIELD_HANDLE hnd = emit->emitSimd32Const(val32); + emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); + } + break; + } + case TYP_SIMD64: + { + simd64_t val64 = *(simd64_t*)val; + if (val64.IsAllBitsSet() && compiler->compOpportunisticallyDependsOn(InstructionSet_AVX512F)) + { + emit->emitIns_SIMD_R_R_R_I(INS_vpternlogd, attr, targetReg, targetReg, targetReg, + static_cast(0xFF)); + } + else if (val64.IsZero()) + { + emit->emitIns_SIMD_R_R_R(INS_xorps, attr, targetReg, targetReg, targetReg); + } + else + { + CORINFO_FIELD_HANDLE hnd = emit->emitSimd64Const(val64); + emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); + } + break; + } + default: + { + unreached(); + } + } +} +#endif // FEATURE_SIMD + /*********************************************************************************** * * Generate code to set a register 'targetReg' of type 'targetType' to the constant @@ -465,12 +582,12 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre if (tree->IsFloatPositiveZero()) { // A faster/smaller way to generate Zero - emit->emitIns_R_R(INS_xorps, size, targetReg, targetReg); + emit->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, targetReg, targetReg, targetReg); } else if (tree->IsFloatAllBitsSet()) { // A faster/smaller way to generate AllBitsSet - emit->emitIns_R_R(INS_pcmpeqd, size, targetReg, targetReg); + emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, EA_16BYTE, targetReg, targetReg, targetReg); } else { @@ -484,151 +601,12 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre case GT_CNS_VEC: { - GenTreeVecCon* vecCon = tree->AsVecCon(); - - emitter* emit = GetEmitter(); - emitAttr attr = emitTypeSize(targetType); - - if (vecCon->IsAllBitsSet()) - { - switch (attr) - { - case EA_8BYTE: - case EA_16BYTE: - { - emit->emitIns_R_R(INS_pcmpeqd, attr, targetReg, targetReg); - return; - } #if defined(FEATURE_SIMD) - case EA_32BYTE: - { - if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX2)) - { - emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, attr, targetReg, targetReg, targetReg); - return; - } - break; - } - - case EA_64BYTE: - { - assert(compiler->compOpportunisticallyDependsOn(InstructionSet_AVX512F)); - emit->emitIns_SIMD_R_R_R_I(INS_vpternlogd, attr, targetReg, targetReg, targetReg, - static_cast(0xFF)); - return; - } -#endif // FEATURE_SIMD - - default: - { - unreached(); - } - } - } - - if (vecCon->IsZero()) - { - bool isSupported; - - switch (attr) - { - case EA_32BYTE: - { - isSupported = compiler->compOpportunisticallyDependsOn(InstructionSet_AVX); - break; - } - - case EA_64BYTE: - { - isSupported = compiler->compOpportunisticallyDependsOn(InstructionSet_AVX512F); - break; - } - - case EA_8BYTE: - case EA_16BYTE: - { - assert((attr == EA_8BYTE) || (attr == EA_16BYTE)); - isSupported = true; - break; - } - - default: - { - unreached(); - } - } - - if (isSupported) - { -#if defined(FEATURE_SIMD) - emit->emitIns_SIMD_R_R_R(INS_xorps, attr, targetReg, targetReg, targetReg); + GenTreeVecCon* vecCon = tree->AsVecCon(); + genSetRegToConst(vecCon->GetRegNum(), targetType, &vecCon->gtSimdVal); #else - emit->emitIns_R_R(INS_xorps, attr, targetReg, targetReg); -#endif // FEATURE_SIMD - break; - } - } - - switch (tree->TypeGet()) - { -#if defined(FEATURE_SIMD) - case TYP_SIMD8: - { - simd8_t constValue; - memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd8_t)); - - CORINFO_FIELD_HANDLE hnd = emit->emitSimd8Const(constValue); - emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); - break; - } - - case TYP_SIMD12: - { - simd16_t constValue = {}; - memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd12_t)); - - CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(constValue); - emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); - break; - } - - case TYP_SIMD16: - { - simd16_t constValue; - memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd16_t)); - - CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(constValue); - emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); - break; - } - - case TYP_SIMD32: - { - simd32_t constValue; - memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd32_t)); - - CORINFO_FIELD_HANDLE hnd = emit->emitSimd32Const(constValue); - emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); - break; - } - - case TYP_SIMD64: - { - simd64_t constValue; - memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd64_t)); - - CORINFO_FIELD_HANDLE hnd = emit->emitSimd64Const(constValue); - emit->emitIns_R_C(ins_Load(targetType), attr, targetReg, hnd, 0); - break; - } -#endif // FEATURE_SIMD - - default: - { - unreached(); - } - } - + unreached(); +#endif break; } @@ -1250,37 +1228,46 @@ void CodeGen::genSIMDSplitReturn(GenTree* src, ReturnTypeDesc* retTypeDesc) #ifdef TARGET_AMD64 assert(src->TypeIs(TYP_SIMD16)); assert(srcIsFloatReg == dstIsFloatReg); - if (opReg != reg0 && opReg != reg1) - { - // Operand reg is different from return regs. - // Copy opReg to reg0 and let it to be handled by one of the - // two cases below. - inst_Mov(TYP_SIMD16, reg0, opReg, /* canSkip */ false); - opReg = reg0; - } - - if (opReg == reg0) - { - assert(opReg != reg1); - // reg1 = opReg. - inst_Mov(TYP_SIMD16, reg1, opReg, /* canSkip */ false); - } - else - { - assert(opReg == reg1); - // reg0 = opReg. - inst_Mov(TYP_SIMD16, reg0, opReg, /* canSkip */ false); - } - // reg0 - already has required 8-byte in bit position [63:0]. - // swap upper and lower 8-bytes of reg1 so that desired 8-byte is in bit position [63:0]. - inst_RV_RV_IV(INS_shufpd, EA_16BYTE, reg1, reg1, 0x01); + assert(reg0 != reg1); + // We can have one of three scenarios here. + // + // First, all three registers are different: + // opReg = xmm0 + // reg1 = xmm1 + // reg2 = xmm2 + // We can then generate two instructions: + // movaps xmm1, xmm0 ; reg1[63:00] = opReg[ 63:00] + // movhlps xmm2, xmm0 ; reg2[63:00] = opReg[127:64] + // + // Second we have opReg and reg1 as the same register: + // opReg = xmm0 + // reg1 = xmm0 + // reg2 = xmm2 + // We can then generate one instruction: + // movhlps xmm2, xmm0 ; reg2[63:00] = opReg[127:64] + // + // Third we have opReg and reg2 as the same register: + // opReg = xmm0 + // reg1 = xmm1 + // reg2 = xmm0 + // We can then generate two instructions: + // movaps xmm1, xmm0 ; reg1[63:00] = opReg[ 63:00] + // movhlps xmm0, xmm0 ; reg2[63:00] = opReg[127:64] + + // Move opReg into reg0, if not already there + inst_Mov(TYP_SIMD16, reg0, opReg, /* canSkip */ true); + + // Move upper 64-bits of opReg into reg1 + GetEmitter()->emitIns_SIMD_R_R_R(INS_movhlps, EA_16BYTE, reg1, reg1, opReg); #else // TARGET_X86 assert(src->TypeIs(TYP_SIMD8)); assert(srcIsFloatReg != dstIsFloatReg); assert((reg0 == REG_EAX) && (reg1 == REG_EDX)); + // reg0 = opReg[31:0] inst_Mov(TYP_INT, reg0, opReg, /* canSkip */ false); + // reg1 = opRef[61:32] if (compiler->compOpportunisticallyDependsOn(InstructionSet_SSE41)) { @@ -1288,8 +1275,10 @@ void CodeGen::genSIMDSplitReturn(GenTree* src, ReturnTypeDesc* retTypeDesc) } else { + bool isRMW = !compiler->canUseVexEncoding(); int8_t shuffleMask = 1; // we only need [61:32]->[31:0], the rest is not read. - inst_RV_TT_IV(INS_pshufd, EA_8BYTE, opReg, src, shuffleMask); + + inst_RV_RV_TT_IV(INS_pshufd, EA_8BYTE, opReg, opReg, src, shuffleMask, isRMW); inst_Mov(TYP_INT, reg1, opReg, /* canSkip */ false); } #endif // TARGET_X86 @@ -2192,36 +2181,28 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode) // This is a case where the two 8-bytes that comprise the operand are in // two different xmm registers and need to be assembled into a single // xmm register. - if (targetReg != reg0 && targetReg != reg1) - { - // targetReg = reg0; - // targetReg[127:64] = reg1[127:64] - inst_Mov(TYP_DOUBLE, targetReg, reg0, /* canSkip */ false); - inst_RV_RV_IV(INS_shufpd, EA_16BYTE, targetReg, reg1, 0x00); - } - else if (targetReg == reg0) + + if (targetReg != reg1) { - // (elided) targetReg = reg0 - // targetReg[127:64] = reg1[127:64] - inst_RV_RV_IV(INS_shufpd, EA_16BYTE, targetReg, reg1, 0x00); + GetEmitter()->emitIns_SIMD_R_R_R(INS_movlhps, EA_16BYTE, targetReg, reg0, reg1); } else { - assert(targetReg == reg1); // We need two shuffles to achieve this // First: - // targetReg[63:0] = targetReg[63:0] + // targetReg[ 63:00] = reg1[63:0] // targetReg[127:64] = reg0[63:0] // // Second: - // targetReg[63:0] = targetReg[127:64] - // targetReg[127:64] = targetReg[63:0] + // targetReg[ 63:00] = targetReg[127:64] + // targetReg[127:64] = targetReg[ 63:00] // // Essentially copy low 8-bytes from reg0 to high 8-bytes of targetReg // and next swap low and high 8-bytes of targetReg to have them // rearranged in the right order. - inst_RV_RV_IV(INS_shufpd, EA_16BYTE, targetReg, reg0, 0x00); - inst_RV_RV_IV(INS_shufpd, EA_16BYTE, targetReg, targetReg, 0x01); + + GetEmitter()->emitIns_SIMD_R_R_R(INS_movlhps, EA_16BYTE, targetReg, reg1, reg0); + GetEmitter()->emitIns_SIMD_R_R_R_I(INS_shufpd, EA_16BYTE, targetReg, targetReg, reg1, 0x01); } genProduceReg(lclNode); #elif defined(TARGET_X86) @@ -3135,17 +3116,8 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) // INITBLK zeroes a struct that contains GC pointers and can be observed by // other threads (i.e. when dstAddr is not an address of a local). // For example, this can happen when initializing a struct field of an object. - const bool canUse16BytesSimdMov = !node->IsOnHeapAndContainsReferences(); - -#ifdef TARGET_AMD64 - // On Amd64 the JIT will not use SIMD stores for such structs and instead - // will always allocate a GP register for src node. - const bool willUseSimdMov = canUse16BytesSimdMov && (size >= XMM_REGSIZE_BYTES); -#else - // On X86 the JIT will use movq for structs that are larger than 16 bytes - // since it is more beneficial than using two mov-s from a GP register. - const bool willUseSimdMov = (size >= 16); -#endif + const bool canUse16BytesSimdMov = !node->IsOnHeapAndContainsReferences() && compiler->IsBaselineSimdIsaSupported(); + const bool willUseSimdMov = canUse16BytesSimdMov && (size >= XMM_REGSIZE_BYTES); if (!src->isContained()) { @@ -3153,14 +3125,8 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) } else { - // If src is contained then it must be 0. - assert(src->IsIntegralConst(0)); assert(willUseSimdMov); -#ifdef TARGET_AMD64 assert(size >= XMM_REGSIZE_BYTES); -#else - assert(size % 8 == 0); -#endif } emitter* emit = GetEmitter(); @@ -3168,36 +3134,20 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) assert(size <= INT32_MAX); assert(dstOffset < (INT32_MAX - static_cast(size))); +#ifdef FEATURE_SIMD if (willUseSimdMov) { regNumber srcXmmReg = node->GetSingleTempReg(RBM_ALLFLOAT); - - unsigned regSize = (size >= YMM_REGSIZE_BYTES) && compiler->compOpportunisticallyDependsOn(InstructionSet_AVX) - ? YMM_REGSIZE_BYTES - : XMM_REGSIZE_BYTES; - - bool zeroing = false; - if (src->gtSkipReloadOrCopy()->IsIntegralConst(0)) + unsigned regSize = compiler->roundDownSIMDSize(size); + if (size < ZMM_RECOMMENDED_THRESHOLD) { - // If the source is constant 0 then always use xorps, it's faster - // than copying the constant from a GPR to a XMM register. - emit->emitIns_R_R(INS_xorps, EA_ATTR(regSize), srcXmmReg, srcXmmReg); - zeroing = true; - } - else - { - emit->emitIns_Mov(INS_movd, EA_PTRSIZE, srcXmmReg, srcIntReg, /* canSkip */ false); - emit->emitIns_R_R(INS_punpckldq, EA_16BYTE, srcXmmReg, srcXmmReg); -#ifdef TARGET_X86 - // For x86, we need one more to convert it from 8 bytes to 16 bytes. - emit->emitIns_R_R(INS_punpckldq, EA_16BYTE, srcXmmReg, srcXmmReg); -#endif - if (regSize == YMM_REGSIZE_BYTES) - { - // Extend the bytes in the lower lanes to the upper lanes - emit->emitIns_R_R_R_I(INS_vinsertf128, EA_32BYTE, srcXmmReg, srcXmmReg, srcXmmReg, 1); - } + // Involve ZMM only for large data due to possible downclocking. + regSize = min(regSize, YMM_REGSIZE_BYTES); } + var_types loadType = compiler->getSIMDTypeForSize(regSize); + simd_t vecCon; + memset(&vecCon, (uint8_t)src->AsIntCon()->IconValue(), sizeof(simd_t)); + genSetRegToConst(srcXmmReg, loadType, &vecCon); instruction simdMov = simdUnalignedMovIns(); unsigned bytesWritten = 0; @@ -3216,50 +3166,32 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) while (bytesWritten < size) { -#ifdef TARGET_X86 - if (!canUse16BytesSimdMov || (bytesWritten + regSize > size)) - { - simdMov = INS_movq; - regSize = 8; - } -#endif if (bytesWritten + regSize > size) { + // We have a remainder that is smaller than regSize. break; } emitSimdMovs(); dstOffset += regSize; bytesWritten += regSize; - - if (!zeroing && regSize == YMM_REGSIZE_BYTES && size - bytesWritten < YMM_REGSIZE_BYTES) - { - regSize = XMM_REGSIZE_BYTES; - } } size -= bytesWritten; - // Handle the remainder by overlapping with previously processed data (only for zeroing) - if (zeroing && (size > 0) && (size < regSize) && (regSize >= XMM_REGSIZE_BYTES)) + // Handle the remainder by overlapping with previously processed data + if ((size > 0) && (size < regSize) && (regSize >= XMM_REGSIZE_BYTES)) { - if (isPow2(size) && (size <= REGSIZE_BYTES)) - { - // For sizes like 1,2,4 and 8 we delegate handling to normal stores - // because that will be a single instruction that is smaller than SIMD mov - } - else - { - // if reminder is <=16 then switch to XMM - regSize = size <= XMM_REGSIZE_BYTES ? XMM_REGSIZE_BYTES : regSize; + // Get optimal register size to cover the whole remainder (with overlapping) + regSize = compiler->roundUpSIMDSize(size); - // Rewind dstOffset so we can fit a vector for the while remainder - dstOffset -= (regSize - size); - emitSimdMovs(); - size = 0; - } + // Rewind dstOffset so we can fit a vector for the while remainder + dstOffset -= (regSize - size); + emitSimdMovs(); + size = 0; } } +#endif // FEATURE_SIMD assert((srcIntReg != REG_NA) || (size == 0)); @@ -3469,9 +3401,12 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) instruction simdMov = simdUnalignedMovIns(); // Get the largest SIMD register available if the size is large enough - unsigned regSize = (size >= YMM_REGSIZE_BYTES) && compiler->compOpportunisticallyDependsOn(InstructionSet_AVX) - ? YMM_REGSIZE_BYTES - : XMM_REGSIZE_BYTES; + unsigned regSize = compiler->roundDownSIMDSize(size); + if (size < ZMM_RECOMMENDED_THRESHOLD) + { + // Involve ZMM only for large data due to possible downclocking. + regSize = min(regSize, YMM_REGSIZE_BYTES); + } auto emitSimdMovs = [&]() { if (srcLclNum != BAD_VAR_NUM) @@ -3516,8 +3451,8 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) } else { - // if reminder is <=16 then switch to XMM - regSize = size <= XMM_REGSIZE_BYTES ? XMM_REGSIZE_BYTES : regSize; + // Get optimal register size to cover the whole remainder (with overlapping) + regSize = compiler->roundUpSIMDSize(size); // Rewind dstOffset so we can fit a vector for the while remainder srcOffset -= (regSize - size); @@ -4066,12 +4001,7 @@ void CodeGen::genClearStackVec3ArgUpperBits() // Assume that for x64 linux, an argument is fully in registers // or fully on stack. regNumber argReg = varDsc->GetOtherArgReg(); - - // Clear the upper 32 bits by two shift instructions. - // argReg = argReg << 96 - GetEmitter()->emitIns_R_I(INS_pslldq, emitActualTypeSize(TYP_SIMD12), argReg, 12); - // argReg = argReg >> 96 - GetEmitter()->emitIns_R_I(INS_psrldq, emitActualTypeSize(TYP_SIMD12), argReg, 12); + genSimd12UpperClear(argReg); } } } @@ -5632,6 +5562,8 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree) case NI_AVX2_ExtractVector128: case NI_AVX512F_ExtractVector128: case NI_AVX512F_ExtractVector256: + case NI_AVX512DQ_ExtractVector128: + case NI_AVX512DQ_ExtractVector256: { // These intrinsics are "ins reg/mem, xmm, imm8" ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); @@ -5656,18 +5588,47 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree) break; } + case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32WithSaturation: + { + assert(!varTypeIsFloating(baseType)); + FALLTHROUGH; + } + + case NI_AVX512F_ConvertToVector128Byte: + case NI_AVX512F_ConvertToVector128ByteWithSaturation: case NI_AVX512F_ConvertToVector128Int16: - case NI_AVX512F_ConvertToVector128Int32: + case NI_AVX512F_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector128SByteWithSaturation: case NI_AVX512F_ConvertToVector128UInt16: - case NI_AVX512F_ConvertToVector128UInt32: + case NI_AVX512F_ConvertToVector128UInt16WithSaturation: case NI_AVX512F_ConvertToVector256Int16: - case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256Int16WithSaturation: + case NI_AVX512F_ConvertToVector256Int32WithSaturation: case NI_AVX512F_ConvertToVector256UInt16: - case NI_AVX512F_ConvertToVector256UInt32: - case NI_AVX512BW_ConvertToVector128Byte: - case NI_AVX512BW_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector256UInt16WithSaturation: + case NI_AVX512F_ConvertToVector256UInt32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Byte: + case NI_AVX512F_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int16: + case NI_AVX512F_VL_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int32: + case NI_AVX512F_VL_ConvertToVector128Int32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128SByte: + case NI_AVX512F_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128UInt16: + case NI_AVX512F_VL_ConvertToVector128UInt16WithSaturation: case NI_AVX512BW_ConvertToVector256Byte: + case NI_AVX512BW_ConvertToVector256ByteWithSaturation: case NI_AVX512BW_ConvertToVector256SByte: + case NI_AVX512BW_ConvertToVector256SByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128Byte: + case NI_AVX512BW_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128SByte: + case NI_AVX512BW_VL_ConvertToVector128SByteWithSaturation: { // These intrinsics are "ins reg/mem, xmm" ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); @@ -6074,18 +6035,14 @@ void CodeGen::genCall(GenTreeCall* call) inst_Mov(regType, allocatedReg, returnReg, /* canSkip */ true); } -#ifdef FEATURE_SIMD +#if defined(FEATURE_SIMD) // A Vector3 return value is stored in xmm0 and xmm1. // RyuJIT assumes that the upper unused bits of xmm1 are cleared but // the native compiler doesn't guarantee it. if (call->IsUnmanaged() && (returnType == TYP_SIMD12)) { returnReg = retTypeDesc->GetABIReturnReg(1); - // Clear the upper 32 bits by two shift instructions. - // retReg = retReg << 96 - // retReg = retReg >> 96 - GetEmitter()->emitIns_R_I(INS_pslldq, emitActualTypeSize(TYP_SIMD12), returnReg, 12); - GetEmitter()->emitIns_R_I(INS_psrldq, emitActualTypeSize(TYP_SIMD12), returnReg, 12); + genSimd12UpperClear(returnReg); } #endif // FEATURE_SIMD } @@ -7410,7 +7367,12 @@ void CodeGen::genFloatToFloatCast(GenTree* treeNode) else { instruction ins = ins_FloatConv(dstType, srcType, emitTypeSize(dstType)); - GetEmitter()->emitInsBinary(ins, emitTypeSize(dstType), treeNode, op1); + + // integral to floating-point conversions all have RMW semantics if VEX support + // is not available + + bool isRMW = !compiler->canUseVexEncoding(); + inst_RV_RV_TT(ins, emitTypeSize(dstType), targetReg, targetReg, op1, isRMW); } genProduceReg(treeNode); @@ -7499,12 +7461,18 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode) // cvtsi2ss/sd instruction. genConsumeOperands(treeNode->AsOp()); - GetEmitter()->emitIns_R_R(INS_xorps, EA_4BYTE, treeNode->GetRegNum(), treeNode->GetRegNum()); + GetEmitter()->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, treeNode->GetRegNum(), treeNode->GetRegNum(), + treeNode->GetRegNum()); // Note that here we need to specify srcType that will determine // the size of source reg/mem operand and rex.w prefix. instruction ins = ins_FloatConv(dstType, TYP_INT, emitTypeSize(srcType)); - GetEmitter()->emitInsBinary(ins, emitTypeSize(srcType), treeNode, op1); + + // integral to floating-point conversions all have RMW semantics if VEX support + // is not available + + bool isRMW = !compiler->canUseVexEncoding(); + inst_RV_RV_TT(ins, emitTypeSize(srcType), targetReg, targetReg, op1, isRMW); // Handle the case of srcType = TYP_ULONG. SSE2 conversion instruction // will interpret ULONG value as LONG. Hence we need to adjust the @@ -7539,7 +7507,7 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode) *cns = GetEmitter()->emitFltOrDblConst(d, EA_8BYTE); } - GetEmitter()->emitIns_R_C(INS_addsd, EA_8BYTE, treeNode->GetRegNum(), *cns, 0); + GetEmitter()->emitIns_SIMD_R_R_C(INS_addsd, EA_8BYTE, targetReg, targetReg, *cns, 0); genDefineTempLabel(label); } @@ -7702,7 +7670,7 @@ void CodeGen::genCkfinite(GenTree* treeNode) if (targetType == TYP_DOUBLE) { inst_Mov(targetType, targetReg, op1->GetRegNum(), /* canSkip */ true); - inst_RV_RV_IV(INS_shufps, EA_16BYTE, targetReg, targetReg, (int8_t)0xb1); + GetEmitter()->emitIns_SIMD_R_R_R_I(INS_shufps, EA_16BYTE, targetReg, targetReg, targetReg, (int8_t)0xB1); copyToTmpSrcReg = targetReg; } else @@ -7724,7 +7692,7 @@ void CodeGen::genCkfinite(GenTree* treeNode) if ((targetType == TYP_DOUBLE) && (targetReg == op1->GetRegNum())) { // We need to re-shuffle the targetReg to get the correct result. - inst_RV_RV_IV(INS_shufps, EA_16BYTE, targetReg, targetReg, (int8_t)0xb1); + GetEmitter()->emitIns_SIMD_R_R_R_I(INS_shufps, EA_16BYTE, targetReg, targetReg, targetReg, (int8_t)0xB1); } else { @@ -7890,7 +7858,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode) // Abs(f) = f & 0x7fffffff x4 (packed) // Abs(d) = d & 0x7fffffffffffffff x2 (packed) ins = INS_andps; - mask = treeNode->TypeIs(TYP_FLOAT) ? 0x7fffffff7fffffffUL : 0x7fffffffffffffffUL; + mask = treeNode->TypeIs(TYP_FLOAT) ? 0x7FFFFFFF7FFFFFFFUL : 0x7FFFFFFFFFFFFFFFUL; maskFld = treeNode->TypeIs(TYP_FLOAT) ? &absBitmaskFlt : &absBitmaskDbl; } else @@ -7900,11 +7868,19 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode) if (*maskFld == nullptr) { - UINT64 maskPack[] = {mask, mask}; - *maskFld = GetEmitter()->emitBlkConst(&maskPack, 16, 16, treeNode->TypeGet()); + simd16_t constValue; + + constValue.u64[0] = mask; + constValue.u64[1] = mask; + +#if defined(FEATURE_SIMD) + *maskFld = GetEmitter()->emitSimd16Const(constValue); +#else + *maskFld = GetEmitter()->emitBlkConst(&constValue, 16, 16, treeNode->TypeGet()); +#endif } - GetEmitter()->emitIns_SIMD_R_R_C(ins, size, targetReg, operandReg, *maskFld, 0); + GetEmitter()->emitIns_SIMD_R_R_C(ins, EA_16BYTE, targetReg, operandReg, *maskFld, 0); } //----------------------------------------------------------------------------------------- @@ -7947,7 +7923,7 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) regNumber dstReg = treeNode->GetRegNum(); - unsigned ival = 0; + int8_t ival = 0; // v) tree oper is NI_System_Math{F}_Round, _Ceiling, _Floor, or _Truncate switch (treeNode->AsIntrinsic()->gtIntrinsicName) @@ -7974,104 +7950,8 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) unreached(); } - if (srcNode->isContained() || srcNode->isUsedFromSpillTemp()) - { - emitter* emit = GetEmitter(); - - TempDsc* tmpDsc = nullptr; - unsigned varNum = BAD_VAR_NUM; - unsigned offset = (unsigned)-1; - - if (srcNode->isUsedFromSpillTemp()) - { - assert(srcNode->IsRegOptional()); - - tmpDsc = getSpillTempDsc(srcNode); - varNum = tmpDsc->tdTempNum(); - offset = 0; - - regSet.tmpRlsTemp(tmpDsc); - } - else if (srcNode->isIndir()) - { - GenTreeIndir* memIndir = srcNode->AsIndir(); - GenTree* memBase = memIndir->gtOp1; - - switch (memBase->OperGet()) - { - case GT_LCL_ADDR: - { - assert(memBase->isContained()); - varNum = memBase->AsLclFld()->GetLclNum(); - offset = memBase->AsLclFld()->GetLclOffs(); - - // Ensure that all the GenTreeIndir values are set to their defaults. - assert(memBase->GetRegNum() == REG_NA); - assert(!memIndir->HasIndex()); - assert(memIndir->Scale() == 1); - assert(memIndir->Offset() == 0); - - break; - } - - case GT_CLS_VAR_ADDR: - { - emit->emitIns_R_C_I(ins, size, dstReg, memBase->AsClsVar()->gtClsVarHnd, 0, ival); - return; - } - - default: - { - emit->emitIns_R_A_I(ins, size, dstReg, memIndir, ival); - return; - } - } - } - else - { - switch (srcNode->OperGet()) - { - case GT_CNS_DBL: - { - GenTreeDblCon* dblConst = srcNode->AsDblCon(); - CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(dblConst->DconValue(), emitTypeSize(dblConst)); - - emit->emitIns_R_C_I(ins, size, dstReg, hnd, 0, ival); - return; - } - - case GT_LCL_FLD: - varNum = srcNode->AsLclFld()->GetLclNum(); - offset = srcNode->AsLclFld()->GetLclOffs(); - break; - - case GT_LCL_VAR: - { - assert(srcNode->IsRegOptional() || !compiler->lvaGetDesc(srcNode->AsLclVar())->lvIsRegCandidate()); - - varNum = srcNode->AsLclVar()->GetLclNum(); - offset = 0; - break; - } - - default: - unreached(); - break; - } - } - - // Ensure we got a good varNum and offset. - // We also need to check for `tmpDsc != nullptr` since spill temp numbers - // are negative and start with -1, which also happens to be BAD_VAR_NUM. - assert((varNum != BAD_VAR_NUM) || (tmpDsc != nullptr)); - assert(offset != (unsigned)-1); - - emit->emitIns_R_S_I(ins, size, dstReg, varNum, offset, ival); - } - else - { - inst_RV_RV_IV(ins, size, dstReg, srcNode->GetRegNum(), ival); - } + bool isRMW = !compiler->canUseVexEncoding(); + inst_RV_RV_TT_IV(ins, size, dstReg, dstReg, srcNode, ival, isRMW); } //--------------------------------------------------------------------- @@ -8109,7 +7989,11 @@ void CodeGen::genIntrinsic(GenTreeIntrinsic* treeNode) genConsumeOperands(treeNode->AsOp()); const instruction ins = (treeNode->TypeGet() == TYP_FLOAT) ? INS_sqrtss : INS_sqrtsd; - GetEmitter()->emitInsBinary(ins, emitTypeSize(treeNode), treeNode, srcNode); + + regNumber targetReg = treeNode->GetRegNum(); + bool isRMW = !compiler->canUseVexEncoding(); + + inst_RV_RV_TT(ins, emitTypeSize(treeNode), targetReg, targetReg, srcNode, isRMW); break; } @@ -11064,7 +10948,7 @@ void CodeGen::genZeroInitFrameUsingBlockInit(int untrLclHi, int untrLclLo, regNu // movups xmmword ptr [ebp/esp-OFFS], xmm4 // mov qword ptr [ebp/esp-OFFS], rax - emit->emitIns_R_R(INS_xorps, EA_ATTR(XMM_REGSIZE_BYTES), zeroSIMDReg, zeroSIMDReg); + emit->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, zeroSIMDReg, zeroSIMDReg, zeroSIMDReg); int i = 0; for (; i < blkSize; i += XMM_REGSIZE_BYTES) @@ -11088,7 +10972,7 @@ void CodeGen::genZeroInitFrameUsingBlockInit(int untrLclHi, int untrLclLo, regNu // add rax, 48 ; | // jne SHORT -5 instr ; ---+ - emit->emitIns_R_R(INS_xorps, EA_ATTR(XMM_REGSIZE_BYTES), zeroSIMDReg, zeroSIMDReg); + emit->emitIns_SIMD_R_R_R(INS_xorps, EA_16BYTE, zeroSIMDReg, zeroSIMDReg, zeroSIMDReg); // How many extra don't fit into the 3x unroll int extraSimd = (blkSize % (XMM_REGSIZE_BYTES * 3)) / XMM_REGSIZE_BYTES; diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index b7c9a682892412..1bb68bfb975a1b 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -1919,6 +1919,7 @@ void Compiler::compInit(ArenaAllocator* pAlloc, compLocallocUsed = false; compLocallocOptimized = false; compQmarkRationalized = false; + compAssignmentRationalized = false; compQmarkUsed = false; compFloatingPointUsed = false; @@ -1927,8 +1928,10 @@ void Compiler::compInit(ArenaAllocator* pAlloc, compNeedsGSSecurityCookie = false; compGSReorderStackLayout = false; - compGeneratingProlog = false; - compGeneratingEpilog = false; + compGeneratingProlog = false; + compGeneratingEpilog = false; + compGeneratingUnwindProlog = false; + compGeneratingUnwindEpilog = false; compPostImportationCleanupDone = false; compLSRADone = false; @@ -2326,10 +2329,12 @@ void Compiler::compSetProcessor() instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512F_VL); instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512BW); instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512BW_VL); - instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512DQ); - instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512DQ_VL); instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512CD); instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512CD_VL); + instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512DQ); + instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512DQ_VL); + instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512VBMI); + instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512VBMI_VL); #ifdef TARGET_AMD64 instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512F_X64); @@ -2340,6 +2345,8 @@ void Compiler::compSetProcessor() instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512CD_VL_X64); instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512DQ_X64); instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512DQ_VL_X64); + instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512VBMI_X64); + instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512VBMI_VL_X64); #endif // TARGET_AMD64 } #elif defined(TARGET_ARM64) @@ -5026,6 +5033,8 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl optLoopTableValid = false; optLoopsRequirePreHeaders = false; + DoPhase(this, PHASE_RATIONALIZE_ASSIGNMENTS, &Compiler::fgRationalizeAssignments); + #ifdef DEBUG DoPhase(this, PHASE_STRESS_SPLIT_TREE, &Compiler::StressSplitTree); #endif @@ -6093,6 +6102,16 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, { instructionSetFlags.AddInstructionSet(InstructionSet_AVX512DQ_VL); } + + if (JitConfig.EnableAVX512VBMI() != 0) + { + instructionSetFlags.AddInstructionSet(InstructionSet_AVX512VBMI); + } + + if (JitConfig.EnableAVX512VBMI_VL() != 0) + { + instructionSetFlags.AddInstructionSet(InstructionSet_AVX512VBMI_VL); + } #endif // These calls are important and explicitly ordered to ensure that the flags are correct in @@ -9699,17 +9718,6 @@ void cTreeFlags(Compiler* comp, GenTree* tree) case GT_NO_OP: break; - case GT_FIELD: - if (tree->gtFlags & GTF_FLD_VOLATILE) - { - chars += printf("[FLD_VOLATILE]"); - } - if (tree->gtFlags & GTF_FLD_TGT_HEAP) - { - chars += printf("[FLD_TGT_HEAP]"); - } - break; - case GT_INDEX_ADDR: if (tree->gtFlags & GTF_INX_RNGCHK) { @@ -9752,6 +9760,10 @@ void cTreeFlags(Compiler* comp, GenTree* tree) { chars += printf("[IND_NONNULL]"); } + if (tree->gtFlags & GTF_IND_INITCLASS) + { + chars += printf("[IND_INITCLASS]"); + } break; case GT_MUL: @@ -10309,11 +10321,10 @@ var_types Compiler::gtTypeForNullCheck(GenTree* tree) // void Compiler::gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block) { - assert(tree->OperIs(GT_FIELD, GT_IND, GT_BLK)); + assert(tree->OperIs(GT_IND, GT_BLK)); tree->ChangeOper(GT_NULLCHECK); tree->ChangeType(gtTypeForNullCheck(tree)); - assert(fgAddrCouldBeNull(tree->gtGetOp1())); - tree->gtFlags |= GTF_EXCEPT; + tree->SetIndirExceptionFlags(this); block->bbFlags |= BBF_HAS_NULLCHECK; optMethodFlags |= OMF_HAS_NULLCHECK; } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 69ed2898bd5754..5fc4b50e1f66c0 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1063,6 +1063,7 @@ class LclVarDsc unsigned short lvRefCnt(RefCountState state = RCS_NORMAL) const; void incLvRefCnt(unsigned short delta, RefCountState state = RCS_NORMAL); void setLvRefCnt(unsigned short newValue, RefCountState state = RCS_NORMAL); + void incLvRefCntSaturating(unsigned short delta, RefCountState state = RCS_NORMAL); weight_t lvRefCntWtd(RefCountState state = RCS_NORMAL) const; void incLvRefCntWtd(weight_t delta, RefCountState state = RCS_NORMAL); @@ -2509,7 +2510,9 @@ class Compiler GenTree* gtNewOneConNode(var_types type, var_types simdBaseType = TYP_UNDEF); - GenTreeLclVar* gtNewStoreLclVar(unsigned dstLclNum, GenTree* src); + GenTreeLclVar* gtNewStoreLclVarNode(unsigned lclNum, GenTree* data); + + GenTreeLclFld* gtNewStoreLclFldNode(unsigned lclNum, var_types type, unsigned offset, GenTree* data); GenTree* gtNewBlkOpNode(GenTree* dst, GenTree* srcOrFillVal, bool isVolatile = false); @@ -2533,6 +2536,7 @@ class Compiler void* compileTimeHandle); GenTreeLclVar* gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSET offs = BAD_IL_OFFSET)); + GenTreeLclVar* gtNewLclVarNode(unsigned lclNum, var_types type = TYP_UNDEF); GenTreeLclVar* gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSET offs = BAD_IL_OFFSET)); GenTreeLclFld* gtNewLclVarAddrNode(unsigned lclNum, var_types type = TYP_I_IMPL); @@ -2800,12 +2804,12 @@ class Compiler GenTreeLclFld* gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset); GenTreeRetExpr* gtNewInlineCandidateReturnExpr(GenTreeCall* inlineCandidate, var_types type); - GenTreeField* gtNewFieldRef(var_types type, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj = nullptr, DWORD offset = 0); + GenTreeFieldAddr* gtNewFieldAddrNode(var_types type, + CORINFO_FIELD_HANDLE fldHnd, + GenTree* obj = nullptr, + DWORD offset = 0); - GenTreeField* gtNewFieldAddrNode(var_types type, - CORINFO_FIELD_HANDLE fldHnd, - GenTree* obj = nullptr, - DWORD offset = 0); + GenTreeIndir* gtNewFieldIndirNode(var_types type, ClassLayout* layout, GenTreeFieldAddr* addr); GenTreeIndexAddr* gtNewIndexAddr(GenTree* arrayOp, GenTree* indexOp, @@ -2829,10 +2833,18 @@ class Compiler GenTreeMDArr* gtNewMDArrLowerBound(GenTree* arrayOp, unsigned dim, unsigned rank, BasicBlock* block); + void gtInitializeIndirNode(GenTreeIndir* indir, GenTreeFlags indirFlags); + GenTreeBlk* gtNewBlkIndir(ClassLayout* layout, GenTree* addr, GenTreeFlags indirFlags = GTF_EMPTY); GenTreeIndir* gtNewIndir(var_types typ, GenTree* addr, GenTreeFlags indirFlags = GTF_EMPTY); + GenTreeBlk* gtNewStoreBlkNode( + ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY); + + GenTreeStoreInd* gtNewStoreIndNode( + var_types type, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY); + GenTree* gtNewLoadValueNode( var_types type, ClassLayout* layout, GenTree* addr, GenTreeFlags indirFlags = GTF_EMPTY); @@ -2846,6 +2858,14 @@ class Compiler return gtNewLoadValueNode(type, nullptr, addr, indirFlags); } + GenTree* gtNewStoreValueNode( + var_types type, ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY); + + GenTree* gtNewStoreValueNode(ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY) + { + return gtNewStoreValueNode(layout->GetType(), layout, addr, data, indirFlags); + } + GenTree* gtNewNullCheck(GenTree* addr, BasicBlock* basicBlock); var_types gtTypeForNullCheck(GenTree* tree); @@ -2942,6 +2962,7 @@ class Compiler static bool gtHasRef(GenTree* tree, unsigned lclNum); bool gtHasLocalsWithAddrOp(GenTree* tree); + bool gtHasAddressExposedLocals(GenTree* tree); unsigned gtSetCallArgsOrder(CallArgs* args, bool lateArgs, int* callCostEx, int* callCostSz); unsigned gtSetMultiOpOrder(GenTreeMultiOp* multiOp); @@ -2956,6 +2977,9 @@ class Compiler void gtPrepareCost(GenTree* tree); bool gtIsLikelyRegVar(GenTree* tree); + void gtGetLclVarNodeCost(GenTreeLclVar* node, int* pCostEx, int* pCostSz, bool isLikelyRegVar); + void gtGetLclFldNodeCost(GenTreeLclFld* node, int* pCostEx, int* pCostSz); + bool gtGetIndNodeCost(GenTreeIndir* node, int* pCostEx, int* pCostSz); // Returns true iff the secondNode can be swapped with firstNode. bool gtCanSwapOrder(GenTree* firstNode, GenTree* secondNode); @@ -3014,10 +3038,6 @@ class Compiler GenTree* gtFoldBoxNullable(GenTree* tree); GenTree* gtFoldExprCompare(GenTree* tree); GenTree* gtFoldExprConditional(GenTree* tree); - GenTree* gtCreateHandleCompare(genTreeOps oper, - GenTree* op1, - GenTree* op2, - CorInfoInlineTypeCheck typeCheckInliningResult); GenTree* gtFoldExprCall(GenTreeCall* call); GenTree* gtFoldTypeCompare(GenTree* tree); GenTree* gtFoldTypeEqualityCall(bool isEq, GenTree* op1, GenTree* op2); @@ -3858,7 +3878,8 @@ class Compiler GenTree* impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_ACCESS_FLAGS access, CORINFO_FIELD_INFO* pFieldInfo, - var_types lclTyp); + var_types lclTyp, + /* OUT */ bool* pIsHoistable = nullptr); static void impBashVarAddrsToI(GenTree* tree1, GenTree* tree2 = nullptr); @@ -4828,6 +4849,9 @@ class Compiler void fgExpandQmarkStmt(BasicBlock* block, Statement* stmt); void fgExpandQmarkNodes(); + PhaseStatus fgRationalizeAssignments(); + GenTree* fgRationalizeAssignment(GenTreeOp* assignment); + // Do "simple lowering." This functionality is (conceptually) part of "general" // lowering that is distributed between fgMorph and the lowering phase of LSRA. PhaseStatus fgSimpleLowering(); @@ -5300,20 +5324,20 @@ class Compiler void SplitTreesRandomly(); void SplitTreesRemoveCommas(); - template + template PhaseStatus fgExpandHelper(bool skipRarelyRunBlocks); - template - bool fgExpandHelperForBlock(BasicBlock* block); + template + bool fgExpandHelperForBlock(BasicBlock** pBlock); PhaseStatus fgExpandRuntimeLookups(); - bool fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call); + bool fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call); PhaseStatus fgExpandThreadLocalAccess(); - bool fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call); + bool fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call); PhaseStatus fgExpandStaticInit(); - bool fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call); + bool fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call); PhaseStatus fgInsertGCPolls(); BasicBlock* fgCreateGCPoll(GCPollType pollType, BasicBlock* block); @@ -5864,7 +5888,8 @@ class Compiler // small; hence the other fields of MorphAddrContext. struct MorphAddrContext { - size_t m_totalOffset = 0; // Sum of offsets between the top-level indirection and here (current context). + size_t m_totalOffset = 0; // Sum of offsets between the top-level indirection and here (current context). + bool m_used = false; // Whether this context was used to elide a null check. }; #ifdef FEATURE_SIMD @@ -5901,7 +5926,7 @@ class Compiler void fgAssignSetVarDef(GenTree* tree); private: - GenTree* fgMorphField(GenTree* tree, MorphAddrContext* mac); + GenTree* fgMorphFieldAddr(GenTree* tree, MorphAddrContext* mac); GenTree* fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* mac); GenTree* fgMorphExpandTlsFieldAddr(GenTree* tree); bool fgCanFastTailCall(GenTreeCall* call, const char** failReason); @@ -6002,7 +6027,7 @@ class Compiler Statement* fgMorphStmt; unsigned fgBigOffsetMorphingTemps[TYP_COUNT]; - unsigned fgGetFieldMorphingTemp(GenTreeField* type); + unsigned fgGetFieldMorphingTemp(GenTreeFieldAddr* fieldNode); //----------------------- Liveness analysis ------------------------------- @@ -8623,7 +8648,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GenTree* impSIMDPopStack(); void setLclRelatedToSIMDIntrinsic(GenTree* tree); - bool areFieldsContiguous(GenTree* op1, GenTree* op2); + bool areFieldsContiguous(GenTreeIndir* op1, GenTreeIndir* op2); bool areLocalFieldsContiguous(GenTreeLclFld* first, GenTreeLclFld* second); bool areArrayElementsContiguous(GenTree* op1, GenTree* op2); bool areArgumentsContiguous(GenTree* op1, GenTree* op2); @@ -8890,12 +8915,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX { maxRegSize = maxSIMDStructBytes(); #if defined(TARGET_XARCH) - if (type != UnrollKind::Memmove) - { - // TODO-XARCH-AVX512: Consider enabling this for AVX512 where it's beneficial. - // Enabled for Memmove only for now. - maxRegSize = min(maxRegSize, YMM_REGSIZE_BYTES); - } threshold = maxRegSize; #elif defined(TARGET_ARM64) // ldp/stp instructions can load/store two 16-byte vectors at once, e.g.: @@ -8927,7 +8946,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // // | arch | memset | memcpy | // |-------------|--------|--------| - // | x86 avx512 | 512 | 256 | (TODO-XARCH-AVX512: ignored for now) + // | x86 avx512 | 512 | 256 | // | x86 avx | 256 | 128 | // | x86 sse | 128 | 64 | // | arm64 | 256 | 128 | ldp/stp (2x128bit) @@ -9230,6 +9249,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool compLocallocOptimized; // Does the method have an optimized localloc bool compQmarkUsed; // Does the method use GT_QMARK/GT_COLON bool compQmarkRationalized; // Is it allowed to use a GT_QMARK/GT_COLON node. + bool compAssignmentRationalized; // Have the ASG nodes been turned into their store equivalents? bool compHasBackwardJump; // Does the method (or some inlinee) have a lexically backwards jump? bool compHasBackwardJumpInHandler; // Does the method have a lexically backwards jump in a handler? bool compSwitchedToOptimized; // Codegen initially was Tier0 but jit switched to FullOpts @@ -9265,6 +9285,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool compGeneratingProlog; bool compGeneratingEpilog; + bool compGeneratingUnwindProlog; + bool compGeneratingUnwindEpilog; bool compNeedsGSSecurityCookie; // There is an unsafe buffer (or localloc) on the stack. // Insert cookie on frame and code to check the cookie, like VC++ -GS. bool compGSReorderStackLayout; // There is an unsafe buffer on the stack, reorder locals and make local @@ -11074,7 +11096,6 @@ class GenTreeVisitor case GT_PUTARG_STK: case GT_RETURNTRAP: case GT_NOP: - case GT_FIELD: case GT_FIELD_ADDR: case GT_RETURN: case GT_RETFILT: diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 992b1750d131ad..e35d1d0cd666df 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -1230,6 +1230,7 @@ inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate) break; #endif case GT_LCL_FLD: + case GT_STORE_LCL_FLD: AsLclFld()->SetLclOffs(0); AsLclFld()->SetLayout(nullptr); break; @@ -1241,7 +1242,12 @@ inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate) case GT_CALL: new (&AsCall()->gtArgs, jitstd::placement_t()) CallArgs(); break; - +#ifdef DEBUG + case GT_LCL_VAR: + case GT_STORE_LCL_VAR: + AsLclVar()->ResetLclILoffs(); + break; +#endif default: break; } @@ -1285,8 +1291,8 @@ inline GenTreeCast* Compiler::gtNewCastNodeL(var_types typ, GenTree* op1, bool f inline GenTreeIndir* Compiler::gtNewMethodTableLookup(GenTree* object) { - GenTreeIndir* result = gtNewIndir(TYP_I_IMPL, object); - result->gtFlags |= GTF_IND_INVARIANT; + assert(object->TypeIs(TYP_REF)); + GenTreeIndir* result = gtNewIndir(TYP_I_IMPL, object, GTF_IND_INVARIANT); return result; } @@ -3985,7 +3991,6 @@ void GenTree::VisitOperands(TVisitor visitor) // Unary operators with an optional operand case GT_NOP: - case GT_FIELD: case GT_FIELD_ADDR: case GT_RETURN: case GT_RETFILT: @@ -4361,10 +4366,9 @@ inline unsigned short LclVarDsc::lvRefCnt(RefCountState state) const // Notes: // It is currently the caller's responsibility to ensure this increment // will not cause overflow. - +// inline void LclVarDsc::incLvRefCnt(unsigned short delta, RefCountState state) { - #if defined(DEBUG) assert(state != RCS_INVALID); Compiler* compiler = JitTls::GetCompiler(); @@ -4376,6 +4380,25 @@ inline void LclVarDsc::incLvRefCnt(unsigned short delta, RefCountState state) assert(m_lvRefCnt >= oldRefCnt); } +//------------------------------------------------------------------------------ +// incLvRefCntSaturating: increment reference count for this local var (with saturating semantics) +// +// Arguments: +// delta: the amount of the increment +// state: the requestor's expected ref count state; defaults to RCS_NORMAL +// +inline void LclVarDsc::incLvRefCntSaturating(unsigned short delta, RefCountState state) +{ +#if defined(DEBUG) + assert(state != RCS_INVALID); + Compiler* compiler = JitTls::GetCompiler(); + assert(compiler->lvaRefCountState == state); +#endif + + int newRefCnt = m_lvRefCnt + delta; + m_lvRefCnt = static_cast(min(USHRT_MAX, newRefCnt)); +} + //------------------------------------------------------------------------------ // setLvRefCnt: set the reference count for this local var // diff --git a/src/coreclr/jit/compphases.h b/src/coreclr/jit/compphases.h index 460b47f9bca855..40862f14220e83 100644 --- a/src/coreclr/jit/compphases.h +++ b/src/coreclr/jit/compphases.h @@ -91,6 +91,7 @@ CompPhaseNameMacro(PHASE_IF_CONVERSION, "If conversion", CompPhaseNameMacro(PHASE_VN_BASED_DEAD_STORE_REMOVAL,"VN-based dead store removal", false, -1, false) CompPhaseNameMacro(PHASE_OPT_UPDATE_FLOW_GRAPH, "Update flow graph opt pass", false, -1, false) CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS2, "Compute edge weights (2, false)",false, -1, false) +CompPhaseNameMacro(PHASE_RATIONALIZE_ASSIGNMENTS, "Rationalize assignments", false, -1, false) CompPhaseNameMacro(PHASE_STRESS_SPLIT_TREE, "Stress gtSplitTree", false, -1, false) CompPhaseNameMacro(PHASE_EXPAND_RTLOOKUPS, "Expand runtime lookups", false, -1, true) CompPhaseNameMacro(PHASE_EXPAND_STATIC_INIT, "Expand static init", false, -1, true) diff --git a/src/coreclr/jit/decomposelongs.cpp b/src/coreclr/jit/decomposelongs.cpp index c7e16f5e7551e8..e1b36b3f97e02c 100644 --- a/src/coreclr/jit/decomposelongs.cpp +++ b/src/coreclr/jit/decomposelongs.cpp @@ -514,10 +514,8 @@ GenTree* DecomposeLongs::DecomposeStoreLclFld(LIR::Use& use) loStore->gtFlags |= GTF_VAR_USEASG; // Create the store for the upper half of the GT_LONG and insert it after the low store. - GenTreeLclFld* hiStore = m_compiler->gtNewLclFldNode(loStore->GetLclNum(), TYP_INT, loStore->GetLclOffs() + 4); - hiStore->SetOper(GT_STORE_LCL_FLD); - hiStore->gtOp1 = value->gtOp2; - hiStore->gtFlags |= (GTF_VAR_DEF | GTF_VAR_USEASG); + GenTreeLclFld* hiStore = + m_compiler->gtNewStoreLclFldNode(loStore->GetLclNum(), TYP_INT, loStore->GetLclOffs() + 4, value->gtOp2); Range().InsertAfter(loStore, hiStore); diff --git a/src/coreclr/jit/earlyprop.cpp b/src/coreclr/jit/earlyprop.cpp index ab858d96fb8705..f1822a9a1cb891 100644 --- a/src/coreclr/jit/earlyprop.cpp +++ b/src/coreclr/jit/earlyprop.cpp @@ -313,7 +313,7 @@ GenTree* Compiler::optEarlyPropRewriteTree(GenTree* tree, LocalNumberToNullCheck return tree; } - return nullptr; + return folded ? tree : nullptr; } //------------------------------------------------------------------------------------------- diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 97de8d503606c9..91e6276321d4b7 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -3673,6 +3673,33 @@ const BYTE emitter::emitFmtToOps[] = { const unsigned emitter::emitFmtCount = ArrLen(emitFmtToOps); #endif +#if defined(TARGET_XARCH) +//------------------------------------------------------------------------ +// emitGetSchedInfo: Gets the scheduling information for a given insFmt +// +// Arguments: +// insFmt - format for which to query scheduling information +// +// Return Value: +// the scheduling information for insFmt +// +const IS_INFO emitter::emitGetSchedInfo(insFormat insFmt) +{ + static const IS_INFO emitFmtToSchedInfo[] = { +#define IF_DEF(en, op1, op2) static_cast(op1), +#include "emitfmts.h" + }; + + if (insFmt < ArrLen(emitFmtToSchedInfo)) + { + return emitFmtToSchedInfo[insFmt]; + } + + assert(!"Unsupported insFmt"); + return IS_NONE; +} +#endif // TARGET_XARCH + //------------------------------------------------------------------------ // Interleaved GC info dumping. // We'll attempt to line this up with the opcode, which indented differently for diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 33f3570deae2e2..1d49eb69070061 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -607,6 +607,7 @@ class emitter unsigned idNum; size_t idSize; // size of the instruction descriptor unsigned idVarRefOffs; // IL offset for LclVar reference + unsigned idVarRefOffs2; // IL offset for 2nd LclVar reference (in case this is a pair) size_t idMemCookie; // compile time handle (check idFlags) GenTreeFlags idFlags; // for determining type of handle in idMemCookie bool idFinallyCall; // Branch instruction is a call to finally @@ -782,17 +783,18 @@ class emitter unsigned _idNoGC : 1; // Some helpers don't get recorded in GC tables #ifdef TARGET_ARM64 - opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16 - insOpts _idInsOpt : 6; // options for instructions - unsigned _idLclVar : 1; // access a local on stack + opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16 + insOpts _idInsOpt : 6; // options for instructions + unsigned _idLclVar : 1; // access a local on stack + unsigned _idLclVarPair : 1 // carries information for 2 GC lcl vars. #endif #ifdef TARGET_LOONGARCH64 - // TODO-LoongArch64: maybe delete on future. - opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16 - insOpts _idInsOpt : 6; // loongarch options for special: placeholders. e.g emitIns_R_C, also identifying the - // accessing a local on stack. - unsigned _idLclVar : 1; // access a local on stack. + // TODO-LoongArch64: maybe delete on future. + opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16 + insOpts _idInsOpt : 6; // loongarch options for special: placeholders. e.g emitIns_R_C, also identifying the + // accessing a local on stack. + unsigned _idLclVar : 1; // access a local on stack. #endif #ifdef TARGET_RISCV64 @@ -815,7 +817,7 @@ class emitter // x86: 46 bits // amd64: 46 bits // arm: 48 bits - // arm64: 49 bits + // arm64: 50 bits // loongarch64: 46 bits // @@ -827,7 +829,7 @@ class emitter #if defined(TARGET_ARM) #define ID_EXTRA_BITFIELD_BITS (16) #elif defined(TARGET_ARM64) -#define ID_EXTRA_BITFIELD_BITS (17) +#define ID_EXTRA_BITFIELD_BITS (18) #elif defined(TARGET_XARCH) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) #define ID_EXTRA_BITFIELD_BITS (14) #else @@ -867,7 +869,7 @@ class emitter // x86: 52/48 bits // amd64: 53/48 bits // arm: 54/50 bits - // arm64: 56/51 bits + // arm64: 57/52 bits // loongarch64: 53/48 bits CLANG_FORMAT_COMMENT_ANCHOR; @@ -885,7 +887,7 @@ class emitter // x86: 12/16 bits // amd64: 11/16 bits // arm: 10/14 bits - // arm64: 8/13 bits + // arm64: 7/12 bits // loongarch64: 11/16 bits unsigned _idSmallCns : ID_BIT_SMALL_CNS; @@ -1203,6 +1205,7 @@ class emitter idAddr()->_idReg3 = reg; assert(reg == idAddr()->_idReg3); } + regNumber idReg4() const { assert(!idIsSmallDsc()); @@ -1214,27 +1217,130 @@ class emitter idAddr()->_idReg4 = reg; assert(reg == idAddr()->_idReg4); } + + bool idHasReg1() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R1_RD | IS_R1_RW | IS_R1_WR)) != 0; + } + bool idIsReg1Read() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R1_RD | IS_R1_RW)) != 0; + } + bool idIsReg1Write() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R1_RW | IS_R1_WR)) != 0; + } + + bool idHasReg2() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R2_RD | IS_R2_RW | IS_R2_WR)) != 0; + } + bool idIsReg2Read() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R2_RD | IS_R2_RW)) != 0; + } + bool idIsReg2Write() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R2_RW | IS_R2_WR)) != 0; + } + bool idHasReg3() const { - switch (idInsFmt()) - { - case IF_RWR_RRD_RRD: - case IF_RWR_RRD_RRD_CNS: - case IF_RWR_RRD_RRD_RRD: - return true; - default: - return false; - } + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R3_RD | IS_R3_RW | IS_R3_WR)) != 0; + } + bool idIsReg3Read() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R3_RD | IS_R3_RW)) != 0; + } + bool idIsReg3Write() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R3_RW | IS_R3_WR)) != 0; } + bool idHasReg4() const { - switch (idInsFmt()) - { - case IF_RWR_RRD_RRD_RRD: - return true; - default: - return false; - } + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R4_RD | IS_R4_RW | IS_R4_WR)) != 0; + } + bool idIsReg4Read() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R4_RD | IS_R4_RW)) != 0; + } + bool idIsReg4Write() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_R4_RW | IS_R4_WR)) != 0; + } + + bool idHasMemGen() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_GM_RD | IS_GM_RW | IS_GM_WR)) != 0; + } + bool idHasMemGenRead() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_GM_RD | IS_GM_RW)) != 0; + } + bool idHasMemGenWrite() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_GM_RW | IS_GM_WR)) != 0; + } + + bool idHasMemStk() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_SF_RD | IS_SF_RW | IS_SF_WR)) != 0; + } + bool idHasMemStkRead() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_SF_RD | IS_SF_RW)) != 0; + } + bool idHasMemStkWrite() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_SF_RW | IS_SF_WR)) != 0; + } + + bool idHasMemAdr() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_AM_RD | IS_AM_RW | IS_AM_WR)) != 0; + } + bool idHasMemAdrRead() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_AM_RD | IS_AM_RW)) != 0; + } + bool idHasMemAdrWrite() const + { + IS_INFO isInfo = emitGetSchedInfo(idInsFmt()); + return (isInfo & (IS_AM_RW | IS_AM_WR)) != 0; + } + + bool idHasMem() const + { + return idHasMemGen() || idHasMemStk() || idHasMemAdr(); + } + bool idHasMemRead() const + { + return idHasMemGenRead() || idHasMemStkRead() || idHasMemAdrRead(); + } + bool idHasMemWrite() const + { + return idHasMemGenWrite() || idHasMemStkWrite() || idHasMemAdrWrite(); } #endif // defined(TARGET_XARCH) #ifdef TARGET_ARMARCH @@ -1432,6 +1538,16 @@ class emitter { _idLclVar = 1; } +#ifdef TARGET_ARM64 + bool idIsLclVarPair() const + { + return _idLclVarPair != 0; + } + void idSetIsLclVarPair() + { + _idLclVarPair = 1; + } +#endif // TARGET_ARM64 #endif // TARGET_ARMARCH #if defined(TARGET_ARM) @@ -1484,7 +1600,7 @@ class emitter { _idDspReloc = val; } - bool idIsReloc() + bool idIsReloc() const { return idIsDspReloc() || idIsCnsReloc(); } @@ -1536,7 +1652,8 @@ class emitter }; // End of struct instrDesc #if defined(TARGET_XARCH) - insFormat getMemoryOperation(instrDesc* id); + insFormat getMemoryOperation(instrDesc* id) const; + insFormat ExtractMemoryFormat(insFormat insFmt) const; #elif defined(TARGET_ARM64) void getMemoryOperation(instrDesc* id, unsigned* pMemAccessKind, bool* pIsLocalAccess); #endif @@ -1819,6 +1936,22 @@ class emitter #endif // TARGET_XARCH +#ifdef TARGET_ARM64 + struct instrDescLclVarPair : instrDesc // contains 2 gc vars to be tracked + { + instrDescLclVarPair() = delete; + + emitLclVarAddr iiaLclVar2; + }; + + struct instrDescLclVarPairCns : instrDescCns // contains 2 gc vars to be tracked, with large cons + { + instrDescLclVarPairCns() = delete; + + emitLclVarAddr iiaLclVar2; + }; +#endif + struct instrDescCGCA : instrDesc // call with ... { instrDescCGCA() = delete; @@ -1905,11 +2038,12 @@ class emitter ssize_t emitGetInsCIdisp(instrDesc* id); unsigned emitGetInsCIargs(instrDesc* id); - inline static emitAttr emitGetMemOpSize(instrDesc* id); + inline emitAttr emitGetMemOpSize(instrDesc* id) const; // Return the argument count for a direct call "id". int emitGetInsCDinfo(instrDesc* id); + static const IS_INFO emitGetSchedInfo(insFormat f); #endif // TARGET_XARCH cnsval_ssize_t emitGetInsSC(instrDesc* id); @@ -2600,7 +2734,26 @@ class emitter #endif // EMITTER_STATS return (instrDescLbl*)emitAllocAnyInstr(sizeof(instrDescLbl), EA_4BYTE); } -#endif // !TARGET_ARM64 +#endif // TARGET_ARM64 + +#if defined(TARGET_ARM64) + instrDescLclVarPair* emitAllocInstrLclVarPair(emitAttr attr) + { + instrDescLclVarPair* result = (instrDescLclVarPair*)emitAllocAnyInstr(sizeof(instrDescLclVarPair), attr); + result->idSetIsLclVarPair(); + return result; + } + + instrDescLclVarPairCns* emitAllocInstrLclVarPairCns(emitAttr attr, cnsval_size_t cns) + { + instrDescLclVarPairCns* result = + (instrDescLclVarPairCns*)emitAllocAnyInstr(sizeof(instrDescLclVarPairCns), attr); + result->idSetIsLargeCns(); + result->idSetIsLclVarPair(); + result->idcCnsVal = cns; + return result; + } +#endif // TARGET_ARM64 instrDescCns* emitAllocInstrCns(emitAttr attr) { @@ -2686,6 +2839,8 @@ class emitter #if !defined(TARGET_ARM64) instrDescLbl* emitNewInstrLbl(); +#else + instrDesc* emitNewInstrLclVarPair(emitAttr attr, cnsval_ssize_t cns); #endif // !TARGET_ARM64 static const BYTE emitFmtToOps[]; @@ -2694,9 +2849,9 @@ class emitter static const unsigned emitFmtCount; #endif - bool emitIsScnsInsDsc(instrDesc* id); + bool emitIsSmallInsDsc(instrDesc* id) const; - size_t emitSizeOfInsDsc(instrDesc* id); + size_t emitSizeOfInsDsc(instrDesc* id) const; /************************************************************************/ /* The following keeps track of stack-based GC values */ @@ -3079,7 +3234,7 @@ inline void emitter::instrDesc::checkSizes() * fields allocated). */ -inline bool emitter::emitIsScnsInsDsc(instrDesc* id) +inline bool emitter::emitIsSmallInsDsc(instrDesc* id) const { return id->idIsSmallDsc(); } @@ -3249,6 +3404,36 @@ inline emitter::instrDescLbl* emitter::emitNewInstrLbl() { return emitAllocInstrLbl(); } +#else +inline emitter::instrDesc* emitter::emitNewInstrLclVarPair(emitAttr attr, cnsval_ssize_t cns) +{ +#if EMITTER_STATS + emitTotalIDescCnt++; + emitTotalIDescCnsCnt++; +#endif // EMITTER_STATS + + if (instrDesc::fitsInSmallCns(cns)) + { + instrDescLclVarPair* id = emitAllocInstrLclVarPair(attr); + id->idSmallCns(cns); +#if EMITTER_STATS + emitSmallCnsCnt++; + if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) + emitSmallCns[SMALL_CNS_TSZ - 1]++; + else + emitSmallCns[cns - ID_MIN_SMALL_CNS]++; +#endif + return id; + } + else + { + instrDescLclVarPairCns* id = emitAllocInstrLclVarPairCns(attr, cns); +#if EMITTER_STATS + emitLargeCnsCnt++; +#endif + return id; + } +} #endif // !TARGET_ARM64 inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, target_ssize_t dsp) @@ -3329,10 +3514,22 @@ inline size_t emitter::emitGetInstrDescSize(const instrDesc* id) } else if (id->idIsLargeCns()) { +#ifdef TARGET_ARM64 + if (id->idIsLclVarPair()) + { + return sizeof(instrDescLclVarPairCns); + } +#endif return sizeof(instrDescCns); } else { +#ifdef TARGET_ARM64 + if (id->idIsLclVarPair()) + { + return sizeof(instrDescLclVarPair); + } +#endif return sizeof(instrDesc); } } @@ -3456,11 +3653,12 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id) // Arguments: // id - Instruction descriptor // -/* static */ emitAttr emitter::emitGetMemOpSize(instrDesc* id) +emitAttr emitter::emitGetMemOpSize(instrDesc* id) const { - emitAttr defaultSize = id->idOpSize(); + emitAttr defaultSize = id->idOpSize(); + instruction ins = id->idIns(); - switch (id->idIns()) + switch (ins) { case INS_pextrb: case INS_pinsrb: @@ -3570,9 +3768,6 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id) case INS_cvtdq2pd: case INS_cvtps2pd: - case INS_vpmovdw: - case INS_vpmovqd: - case INS_vpmovwb: { if (defaultSize == 64) { @@ -3589,6 +3784,57 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id) } } + case INS_vpmovdb: + case INS_vpmovdw: + case INS_vpmovqb: + case INS_vpmovqd: + case INS_vpmovqw: + case INS_vpmovwb: + case INS_vpmovsdb: + case INS_vpmovsdw: + case INS_vpmovsqb: + case INS_vpmovsqd: + case INS_vpmovsqw: + case INS_vpmovswb: + case INS_vpmovusdb: + case INS_vpmovusdw: + case INS_vpmovusqb: + case INS_vpmovusqd: + case INS_vpmovusqw: + case INS_vpmovuswb: + { + insTupleType tupleType = insTupleTypeInfo(ins); + unsigned memSize = 0; + + switch (tupleType) + { + case INS_TT_HALF_MEM: + { + memSize = defaultSize / 2; + break; + } + + case INS_TT_QUARTER_MEM: + { + memSize = defaultSize / 4; + break; + } + + case INS_TT_EIGHTH_MEM: + { + memSize = defaultSize / 8; + break; + } + + default: + { + unreached(); + } + } + + return EA_ATTR(memSize); + } + case INS_vbroadcastf128: case INS_vbroadcasti128: case INS_vextractf128: @@ -3613,7 +3859,11 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id) case INS_movddup: { - if (defaultSize == 32) + if (defaultSize == 64) + { + return EA_64BYTE; + } + else if (defaultSize == 32) { return EA_32BYTE; } diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index a82f37421d0dc9..f616dc99a8ab54 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -83,9 +83,9 @@ const emitJumpKind emitReverseJumpKinds[] = { * Return the allocated size (in bytes) of the given instruction descriptor. */ -size_t emitter::emitSizeOfInsDsc(instrDesc* id) +size_t emitter::emitSizeOfInsDsc(instrDesc* id) const { - if (emitIsScnsInsDsc(id)) + if (emitIsSmallInsDsc(id)) return SMALL_IDSC_SIZE; assert((unsigned)id->idInsFmt() < emitFmtCount); @@ -7836,7 +7836,7 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) printf("]"); - if (varx >= 0 && emitComp->opts.varNames) + if ((varx >= 0) && emitComp->opts.varNames && (((IL_OFFSET)offs) != BAD_IL_OFFSET)) { const char* varName = emitComp->compLocalVarName(varx, offs); diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 657f9645de04c4..9338ec680240b0 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -86,9 +86,9 @@ const emitJumpKind emitReverseJumpKinds[] = { * Return the allocated size (in bytes) of the given instruction descriptor. */ -size_t emitter::emitSizeOfInsDsc(instrDesc* id) +size_t emitter::emitSizeOfInsDsc(instrDesc* id) const { - if (emitIsScnsInsDsc(id)) + if (emitIsSmallInsDsc(id)) return SMALL_IDSC_SIZE; assert((unsigned)id->idInsFmt() < emitFmtCount); @@ -128,15 +128,29 @@ size_t emitter::emitSizeOfInsDsc(instrDesc* id) if (id->idIsLargeCns()) { - if (id->idIsLargeDsp()) + if (id->idIsLclVarPair()) + { + return sizeof(instrDescLclVarPairCns); + } + else if (id->idIsLargeDsp()) + { return sizeof(instrDescCnsDsp); + } else + { return sizeof(instrDescCns); + } } else { - if (id->idIsLargeDsp()) + if (id->idIsLclVarPair()) + { + return sizeof(instrDescLclVarPair); + } + else if (id->idIsLargeDsp()) + { return sizeof(instrDescDsp); + } else { #if FEATURE_LOOP_ALIGN @@ -2399,18 +2413,7 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt) /*static*/ unsigned emitter::NaturalScale_helper(emitAttr size) { assert(size == EA_1BYTE || size == EA_2BYTE || size == EA_4BYTE || size == EA_8BYTE || size == EA_16BYTE); - - unsigned result = 0; - unsigned utemp = (unsigned)size; - - // Compute log base 2 of utemp (aka 'size') - while (utemp > 1) - { - result++; - utemp >>= 1; - } - - return result; + return BitOperations::Log2((unsigned)size); } /************************************************************************ @@ -5686,7 +5689,8 @@ void emitter::emitIns_R_R_I( } // Try to optimize a load/store with an alternative instruction. - if (isLdrStr && emitComp->opts.OptimizationEnabled() && OptimizeLdrStr(ins, attr, reg1, reg2, imm, size, fmt)) + if (isLdrStr && emitComp->opts.OptimizationEnabled() && + OptimizeLdrStr(ins, attr, reg1, reg2, imm, size, fmt, false, -1, -1 DEBUG_ARG(false))) { return; } @@ -6493,6 +6497,136 @@ void emitter::emitIns_R_R_R( appendToCurIG(id); } +//----------------------------------------------------------------------------------- +// emitIns_R_R_R_I_LdStPair: Add an instruction storing 2 registers into a memory +// (pointed by reg3) and the offset (immediate). +// +// Arguments: +// ins - The instruction code +// attr - The emit attribute for register 1 +// attr2 - The emit attribute for register 2 +// reg1 - Register 1 +// reg2 - Register 2 +// reg3 - Register 3 +// imm - Immediate offset, prior to scaling by operand size +// varx1 - LclVar number 1 +// varx2 - LclVar number 2 +// offs1 - Memory offset of lclvar number 1 +// offs2 - Memory offset of lclvar number 2 +// +void emitter::emitIns_R_R_R_I_LdStPair(instruction ins, + emitAttr attr, + emitAttr attr2, + regNumber reg1, + regNumber reg2, + regNumber reg3, + ssize_t imm, + int varx1, + int varx2, + int offs1, + int offs2 DEBUG_ARG(unsigned var1RefsOffs) DEBUG_ARG(unsigned var2RefsOffs)) +{ + assert((ins == INS_stp) || (ins == INS_ldp)); + emitAttr size = EA_SIZE(attr); + insFormat fmt = IF_NONE; + unsigned scale = 0; + + // Is the target a vector register? + if (isVectorRegister(reg1)) + { + assert(isValidVectorLSPDatasize(size)); + assert(isVectorRegister(reg2)); + + scale = NaturalScale_helper(size); + assert((scale >= 2) && (scale <= 4)); + } + else + { + assert(isValidGeneralDatasize(size)); + assert(isGeneralRegisterOrZR(reg2)); + scale = (size == EA_8BYTE) ? 3 : 2; + } + + reg3 = encodingSPtoZR(reg3); + + fmt = IF_LS_3C; + ssize_t mask = (1 << scale) - 1; // the mask of low bits that must be zero to encode the immediate + if (imm == 0) + { + fmt = IF_LS_3B; + } + else + { + if ((imm & mask) == 0) + { + imm >>= scale; // The immediate is scaled by the size of the ld/st + } + else + { + // Unlike emitIns_S_S_R_R(), we would never come here when + // (imm & mask) != 0. + unreached(); + } + } + + bool validVar1 = varx1 != -1; + bool validVar2 = varx2 != -1; + + instrDesc* id; + + if (validVar1 && validVar2) + { + id = emitNewInstrLclVarPair(attr, imm); + id->idAddr()->iiaLclVar.initLclVarAddr(varx1, offs1); + id->idSetIsLclVar(); + + emitGetLclVarPairLclVar2(id)->initLclVarAddr(varx2, offs2); + } + else + { + id = emitNewInstrCns(attr, imm); + if (validVar1) + { + id->idAddr()->iiaLclVar.initLclVarAddr(varx1, offs1); + id->idSetIsLclVar(); + } + if (validVar2) + { + id->idAddr()->iiaLclVar.initLclVarAddr(varx2, offs2); + id->idSetIsLclVar(); + } + } + + id->idIns(ins); + id->idInsFmt(fmt); + id->idInsOpt(INS_OPTS_NONE); + + id->idReg1(reg1); + id->idReg2(reg2); + id->idReg3(reg3); + + // Record the attribute for the second register in the pair + if (EA_IS_GCREF(attr2)) + { + id->idGCrefReg2(GCT_GCREF); + } + else if (EA_IS_BYREF(attr2)) + { + id->idGCrefReg2(GCT_BYREF); + } + else + { + id->idGCrefReg2(GCT_NONE); + } + +#ifdef DEBUG + id->idDebugOnlyInfo()->idVarRefOffs = var1RefsOffs; + id->idDebugOnlyInfo()->idVarRefOffs2 = var2RefsOffs; +#endif + dispIns(id); + appendToCurIG(id); +} + /***************************************************************************** * * Add an instruction referencing three registers and a constant. @@ -7610,8 +7744,9 @@ void emitter::emitIns_R_S(instruction ins, emitAttr attr, regNumber reg1, int va disp = base + offs; assert((scale >= 0) && (scale <= 4)); - regNumber reg2 = FPbased ? REG_FPBASE : REG_SPBASE; - reg2 = encodingSPtoZR(reg2); + bool useRegForImm = false; + regNumber reg2 = FPbased ? REG_FPBASE : REG_SPBASE; + reg2 = encodingSPtoZR(reg2); if (ins == INS_lea) { @@ -7639,9 +7774,8 @@ void emitter::emitIns_R_S(instruction ins, emitAttr attr, regNumber reg1, int va } else { - bool useRegForImm = false; - ssize_t mask = (1 << scale) - 1; // the mask of low bits that must be zero to encode the immediate - imm = disp; + ssize_t mask = (1 << scale) - 1; // the mask of low bits that must be zero to encode the immediate + imm = disp; if (imm == 0) { fmt = IF_LS_2A; @@ -7683,7 +7817,7 @@ void emitter::emitIns_R_S(instruction ins, emitAttr attr, regNumber reg1, int va // Try to optimize a load/store with an alternative instruction. if (isLdrStr && emitComp->opts.OptimizationEnabled() && - OptimizeLdrStr(ins, attr, reg1, reg2, imm, size, fmt, true, varx, offs)) + OptimizeLdrStr(ins, attr, reg1, reg2, imm, size, fmt, true, varx, offs DEBUG_ARG(useRegForImm))) { return; } @@ -7917,7 +8051,7 @@ void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber reg1, int va // Try to optimize a store with an alternative instruction. if (isStr && emitComp->opts.OptimizationEnabled() && - OptimizeLdrStr(ins, attr, reg1, reg2, imm, size, fmt, true, varx, offs)) + OptimizeLdrStr(ins, attr, reg1, reg2, imm, size, fmt, true, varx, offs DEBUG_ARG(useRegForImm))) { return; } @@ -11731,31 +11865,81 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) vt = tmpDsc->tdTempType(); } if (vt == TYP_REF || vt == TYP_BYREF) + { emitGCvarDeadUpd(adr + ofs, dst DEBUG_ARG(varNum)); + } } if (emitInsWritesToLclVarStackLocPair(id)) { - unsigned ofs2 = ofs + TARGET_POINTER_SIZE; + int varNum2 = varNum; + int adr2 = adr; + unsigned ofs2 = ofs; + unsigned ofs2Dist; + + if (id->idIsLclVarPair()) + { + bool FPbased2; + + emitLclVarAddr* lclVarAddr2 = emitGetLclVarPairLclVar2(id); + varNum2 = lclVarAddr2->lvaVarNum(); + ofs2 = lclVarAddr2->lvaOffset(); + + // If there are 2 GC vars in this instrDesc, get the 2nd variable + // that should be tracked. + adr2 = emitComp->lvaFrameAddress(varNum2, &FPbased2); + ofs2Dist = EA_SIZE_IN_BYTES(size); +#ifdef DEBUG + assert(FPbased == FPbased2); + if (FPbased) + { + assert(id->idReg3() == REG_FP); + } + else + { + assert(id->idReg3() == REG_SP); + } + assert(varNum2 != -1); +#endif // DEBUG + } + else + { + ofs2Dist = TARGET_POINTER_SIZE; + ofs2 += ofs2Dist; + } + + ofs2 = AlignDown(ofs2, ofs2Dist); + if (id->idGCrefReg2() != GCT_NONE) { - emitGCvarLiveUpd(adr + ofs2, varNum, id->idGCrefReg2(), dst DEBUG_ARG(varNum)); +#ifdef DEBUG + if (id->idGCref() != GCT_NONE) + { + // If 1st register was a gc-var, then make sure the offset + // are correctly set for the 2nd register that is holding + // another gc-var. + assert((adr + ofs + ofs2Dist) == (adr2 + ofs2)); + } +#endif + emitGCvarLiveUpd(adr2 + ofs2, varNum2, id->idGCrefReg2(), dst DEBUG_ARG(varNum2)); } else { // If the type of the local is a gc ref type, update the liveness. var_types vt; - if (varNum >= 0) + if (varNum2 >= 0) { // "Regular" (non-spill-temp) local. - vt = var_types(emitComp->lvaTable[varNum].lvType); + vt = var_types(emitComp->lvaTable[varNum2].lvType); } else { - TempDsc* tmpDsc = codeGen->regSet.tmpFindNum(varNum); + TempDsc* tmpDsc = codeGen->regSet.tmpFindNum(varNum2); vt = tmpDsc->tdTempType(); } if (vt == TYP_REF || vt == TYP_BYREF) - emitGCvarDeadUpd(adr + ofs2, dst DEBUG_ARG(varNum)); + { + emitGCvarDeadUpd(adr2 + ofs2, dst DEBUG_ARG(varNum2)); + } } } } @@ -13742,11 +13926,18 @@ void emitter::emitDispInsHelp( break; } - if (id->idDebugOnlyInfo()->idVarRefOffs) + if (id->idIsLclVar()) { printf("\t// "); emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); + if (id->idIsLclVarPair()) + { + printf(", "); + emitLclVarAddr* iiaLclVar2 = emitGetLclVarPairLclVar2(id); + emitDispFrameRef(iiaLclVar2->lvaVarNum(), iiaLclVar2->lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs2, + asmfm); + } } printf("\n"); @@ -13774,7 +13965,7 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) printf("]"); - if (varx >= 0 && emitComp->opts.varNames) + if ((varx >= 0) && emitComp->opts.varNames && (((IL_OFFSET)offs) != BAD_IL_OFFSET)) { const char* varName = emitComp->compLocalVarName(varx, offs); @@ -16180,6 +16371,71 @@ bool emitter::IsRedundantLdStr( return false; } +//----------------------------------------------------------------------------------- +// OptimizeLdrStr: Try to optimize "ldr" or "str" instruction with an alternative +// instruction. +// +// Arguments: +// ins - The instruction code +// reg1Attr - The emit attribute for register 1 +// reg1 - Register 1 +// reg2 - Register 2 +// imm - Immediate offset, prior to scaling by operand size +// size - Operand size +// fmt - Instruction format +// localVar - If current instruction has local var +// varx - LclVarNum if this instruction contains local variable +// offs - Stack offset where it is accessed (loaded / stored). +// useRsvdReg - If this instruction needs reserved register. +// +// Return Value: +// "true" if the previous instruction has been overwritten. +// +bool emitter::OptimizeLdrStr(instruction ins, + emitAttr reg1Attr, + regNumber reg1, + regNumber reg2, + ssize_t imm, + emitAttr size, + insFormat fmt, + bool localVar, + int varx, + int offs DEBUG_ARG(bool useRsvdReg)) +{ + assert(ins == INS_ldr || ins == INS_str); + + if (!emitCanPeepholeLastIns() || (emitLastIns->idIns() != ins)) + { + return false; + } + + // Is the ldr/str even necessary? + if (IsRedundantLdStr(ins, reg1, reg2, imm, size, fmt)) + { + return true; + } + + // Register 2 needs conversion to unencoded value for following optimisation checks. + reg2 = encodingZRtoSP(reg2); + + // If the previous instruction was a matching load/store, then try to replace it instead of emitting. + // + if (ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt, localVar, varx, offs)) + { + assert(!useRsvdReg); + return true; + } + + // If we have a second LDR instruction from the same source, then try to replace it with a MOV. + if (IsOptimizableLdrToMov(ins, reg1, reg2, imm, size, fmt)) + { + emitIns_Mov(INS_mov, reg1Attr, reg1, emitLastIns->idReg1(), true); + return true; + } + + return false; +} + //----------------------------------------------------------------------------------- // ReplaceLdrStrWithPairInstr: Potentially, overwrite a previously-emitted "ldr" or "str" // instruction with an "ldp" or "stp" instruction. @@ -16191,66 +16447,96 @@ bool emitter::IsRedundantLdStr( // reg2 - Register 2 // imm - Immediate offset, prior to scaling by operand size // size - Operand size -// fmt - Instruction format +// fmt - Instruction format +// localVar - If current instruction has local var +// currLclVarNum - LclVarNum if this instruction contains local variable +// offs - Stack offset where it is accessed (loaded / stored). // // Return Value: // "true" if the previous instruction has been overwritten. // -bool emitter::ReplaceLdrStrWithPairInstr( - instruction ins, emitAttr reg1Attr, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt) +bool emitter::ReplaceLdrStrWithPairInstr(instruction ins, + emitAttr reg1Attr, + regNumber reg1, + regNumber reg2, + ssize_t imm, + emitAttr size, + insFormat fmt, + bool isCurrLclVar, + int varx, + int offs) { RegisterOrder optimizationOrder = IsOptimizableLdrStrWithPair(ins, reg1, reg2, imm, size, fmt); - if (optimizationOrder != eRO_none) + if (optimizationOrder == eRO_none) { - regNumber oldReg1 = emitLastIns->idReg1(); + return false; + } - ssize_t oldImm = emitGetInsSC(emitLastIns); - instruction optIns = (ins == INS_ldr) ? INS_ldp : INS_stp; + regNumber prevReg1 = emitLastIns->idReg1(); +#ifdef DEBUG + unsigned prevVarRefsOffs = emitLastIns->idDebugOnlyInfo()->idVarRefOffs; + unsigned newVarRefsOffs = emitVarRefOffs; +#endif - emitAttr oldReg1Attr; - switch (emitLastIns->idGCref()) - { - case GCT_GCREF: - oldReg1Attr = EA_GCREF; - break; - case GCT_BYREF: - oldReg1Attr = EA_BYREF; - break; - default: - oldReg1Attr = emitLastIns->idOpSize(); - break; - } + ssize_t prevImm = emitGetInsSC(emitLastIns); + instruction optIns = (ins == INS_ldr) ? INS_ldp : INS_stp; - // Remove the last instruction written. - emitRemoveLastInstruction(); + emitAttr prevReg1Attr; + ssize_t prevImmSize = prevImm * size; + ssize_t newImmSize = imm * size; + bool isLastLclVar = emitLastIns->idIsLclVar(); + int prevOffset = -1; + int prevLclVarNum = -1; - // Combine two 32 bit stores of value zero into one 64 bit store - if (ins == INS_str && reg1 == REG_ZR && oldReg1 == REG_ZR && size == EA_4BYTE) - { + if (emitLastIns->idIsLclVar()) + { + prevOffset = emitLastIns->idAddr()->iiaLclVar.lvaOffset(); + prevLclVarNum = emitLastIns->idAddr()->iiaLclVar.lvaVarNum(); + } - // The first register is at the lower offset for the ascending order - ssize_t offset = (optimizationOrder == eRO_ascending ? oldImm : imm) * size; - emitIns_R_R_I(INS_str, EA_8BYTE, REG_ZR, reg2, offset, INS_OPTS_NONE); - return true; - } + if (!isCurrLclVar) + { + assert((varx == -1) && (offs == -1)); + } - // Emit the new instruction. Make sure to scale the immediate value by the operand size. - if (optimizationOrder == eRO_ascending) - { - // The FIRST register is at the lower offset - emitIns_R_R_R_I(optIns, oldReg1Attr, oldReg1, reg1, reg2, oldImm * size, INS_OPTS_NONE, reg1Attr); - } - else - { - // The SECOND register is at the lower offset - emitIns_R_R_R_I(optIns, reg1Attr, reg1, oldReg1, reg2, imm * size, INS_OPTS_NONE, oldReg1Attr); - } + switch (emitLastIns->idGCref()) + { + case GCT_GCREF: + prevReg1Attr = EA_GCREF; + break; + case GCT_BYREF: + prevReg1Attr = EA_BYREF; + break; + default: + prevReg1Attr = emitLastIns->idOpSize(); + break; + } + + // Remove the last instruction written. + emitRemoveLastInstruction(); + // Combine two 32 bit stores of value zero into one 64 bit store + if ((ins == INS_str) && (reg1 == REG_ZR) && (prevReg1 == REG_ZR) && (size == EA_4BYTE)) + { + // The first register is at the lower offset for the ascending order + ssize_t offset = (optimizationOrder == eRO_ascending ? prevImm : imm) * size; + emitIns_R_R_I(INS_str, EA_8BYTE, REG_ZR, reg2, offset, INS_OPTS_NONE); return true; } - return false; + if (optimizationOrder == eRO_ascending) + { + emitIns_R_R_R_I_LdStPair(optIns, prevReg1Attr, reg1Attr, prevReg1, reg1, reg2, prevImmSize, prevLclVarNum, varx, + prevOffset, offs DEBUG_ARG(prevVarRefsOffs) DEBUG_ARG(newVarRefsOffs)); + } + else + { + emitIns_R_R_R_I_LdStPair(optIns, reg1Attr, prevReg1Attr, reg1, prevReg1, reg2, newImmSize, varx, prevLclVarNum, + offs, prevOffset DEBUG_ARG(newVarRefsOffs) DEBUG_ARG(prevVarRefsOffs)); + } + + return true; } //----------------------------------------------------------------------------------- @@ -16308,7 +16594,7 @@ emitter::RegisterOrder emitter::IsOptimizableLdrStrWithPair( // For LDR/ STR, there are 9 bits, so we need to limit the range explicitly in software. if ((imm < -64) || (imm > 63) || (prevImm < -64) || (prevImm > 63)) { - // Then one or more of the immediate values is out of range, so we cannot optimise. + // Then one or more of the immediate values is out of range, so we cannot optimize. return eRO_none; } @@ -16374,18 +16660,12 @@ emitter::RegisterOrder emitter::IsOptimizableLdrStrWithPair( return eRO_none; } - // Don't remove instructions whilst in prologs or epilogs, as these contain "unwindable" - // parts, where we need to report unwind codes to the OS, - if (emitIGisInProlog(emitCurIG) || emitIGisInEpilog(emitCurIG)) - { - return eRO_none; - } -#ifdef FEATURE_EH_FUNCLETS - if (emitIGisInFuncletProlog(emitCurIG) || emitIGisInFuncletEpilog(emitCurIG)) + if (emitComp->compGeneratingUnwindProlog || emitComp->compGeneratingUnwindEpilog) { + // Don't remove instructions while generating "unwind" part of prologs or epilogs, + // because for those instructions, we need to report unwind codes to the OS. return eRO_none; } -#endif return optimisationOrder; } diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index ee0e029c84b68c..59806d4b4ea252 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -128,66 +128,39 @@ bool IsRedundantMov(instruction ins, emitAttr size, regNumber dst, regNumber src bool IsRedundantLdStr(instruction ins, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); RegisterOrder IsOptimizableLdrStrWithPair( instruction ins, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); -bool ReplaceLdrStrWithPairInstr( - instruction ins, emitAttr reg1Attr, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); +bool ReplaceLdrStrWithPairInstr(instruction ins, + emitAttr reg1Attr, + regNumber reg1, + regNumber reg2, + ssize_t imm, + emitAttr size, + insFormat fmt, + bool localVar = false, + int varx = -1, + int offs = -1); bool IsOptimizableLdrToMov(instruction ins, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); - -// Try to optimize a Ldr or Str with an alternative instruction. -inline bool OptimizeLdrStr(instruction ins, - emitAttr reg1Attr, - regNumber reg1, - regNumber reg2, - ssize_t imm, - emitAttr size, - insFormat fmt, - bool localVar = false, - int varx = 0, - int offs = 0) +FORCEINLINE bool OptimizeLdrStr(instruction ins, + emitAttr reg1Attr, + regNumber reg1, + regNumber reg2, + ssize_t imm, + emitAttr size, + insFormat fmt, + bool localVar = false, + int varx = -1, + int offs = -1 DEBUG_ARG(bool useRsvdReg = false)); + +emitLclVarAddr* emitGetLclVarPairLclVar2(instrDesc* id) { - assert(ins == INS_ldr || ins == INS_str); - - if (!emitCanPeepholeLastIns() || (emitLastIns->idIns() != ins)) - { - return false; - } - - // Is the ldr/str even necessary? - if (IsRedundantLdStr(ins, reg1, reg2, imm, size, fmt)) + assert(id->idIsLclVarPair()); + if (id->idIsLargeCns()) { - return true; + return &(((instrDescLclVarPairCns*)id)->iiaLclVar2); } - - // Register 2 needs conversion to unencoded value for following optimisation checks. - reg2 = encodingZRtoSP(reg2); - - // If the previous instruction was a matching load/store, then try to replace it instead of emitting. - // - bool canReplaceWithPair = true; - if (ins == INS_str) + else { - // For INS_str, don't do this if either instruction had a local GC variable. - // For INS_ldr, it is fine to perform this optimization because the output code already handles the code of - // updating the gc refs. We do not need offset tracking for load cases. - if ((localVar && EA_IS_GCREF_OR_BYREF(reg1Attr)) || - (emitLastIns->idIsLclVar() && (emitLastIns->idGCref() != GCT_NONE))) - { - canReplaceWithPair = false; - } + return &(((instrDescLclVarPair*)id)->iiaLclVar2); } - - if (canReplaceWithPair && ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt)) - { - return true; - } - - // If we have a second LDR instruction from the same source, then try to replace it with a MOV. - if (IsOptimizableLdrToMov(ins, reg1, reg2, imm, size, fmt)) - { - emitIns_Mov(INS_mov, reg1Attr, reg1, emitLastIns->idReg1(), true); - return true; - } - - return false; } /************************************************************************ @@ -890,6 +863,19 @@ void emitIns_S_R(instruction ins, emitAttr attr, regNumber ireg, int varx, int o void emitIns_S_S_R_R( instruction ins, emitAttr attr, emitAttr attr2, regNumber ireg, regNumber ireg2, int varx, int offs); +void emitIns_R_R_R_I_LdStPair(instruction ins, + emitAttr attr, + emitAttr attr2, + regNumber reg1, + regNumber reg2, + regNumber reg3, + ssize_t imm, + int varx1 = -1, + int varx2 = -1, + int offs1 = -1, + int offs2 = -1 DEBUG_ARG(unsigned var1RefsOffs = BAD_IL_OFFSET) + DEBUG_ARG(unsigned var2RefsOffs = BAD_IL_OFFSET)); + void emitIns_R_S(instruction ins, emitAttr attr, regNumber ireg, int varx, int offs); void emitIns_R_R_S_S( diff --git a/src/coreclr/jit/emitfmtsxarch.h b/src/coreclr/jit/emitfmtsxarch.h index 7e90ca3b417de7..45ddb9bb188cfb 100644 --- a/src/coreclr/jit/emitfmtsxarch.h +++ b/src/coreclr/jit/emitfmtsxarch.h @@ -31,6 +31,39 @@ enum ID_OPS ID_OP_SPEC, // special handling required }; +enum IS_INFO +{ + IS_NONE = 0, // no scheduling information + + IS_R1_RD = 1 << 0, // has a reg1 op that is read-only + IS_R1_WR = 1 << 1, // has a reg1 op that is write-only + IS_R1_RW = 1 << 2, // has a reg1 op that is read-write + + IS_R2_RD = 1 << 3, // has a reg2 op that is read-only + IS_R2_WR = 1 << 4, // has a reg2 op that is write-only + IS_R2_RW = 1 << 5, // has a reg2 op that is read-write + + IS_R3_RD = 1 << 6, // has a reg3 op that is read-only + IS_R3_WR = 1 << 7, // has a reg3 op that is write-only + IS_R3_RW = 1 << 8, // has a reg3 op that is read-write + + IS_R4_RD = 1 << 9, // has a reg4 op that is read-only + IS_R4_WR = 1 << 10, // has a reg4 op that is write-only + IS_R4_RW = 1 << 11, // has a reg4 op that is read-write + + IS_GM_RD = 1 << 12, // has a [mem] op that is read-only + IS_GM_WR = 1 << 13, // has a [mem] op that is write-only + IS_GM_RW = 1 << 14, // has a [mem] op that is read-write + + IS_SF_RD = 1 << 15, // has a [stk] op that is read-only + IS_SF_WR = 1 << 16, // has a [stk] op that is write-only + IS_SF_RW = 1 << 17, // has a [stk] op that is read-write + + IS_AM_RD = 1 << 18, // has a [adr] op that is read-only + IS_AM_WR = 1 << 19, // has a [adr] op that is write-only + IS_AM_RW = 1 << 20, // has a [adr] op that is read-write +}; + ////////////////////////////////////////////////////////////////////////////// #else // !DEFINE_ID_OPS ////////////////////////////////////////////////////////////////////////////// @@ -71,141 +104,186 @@ enum ID_OPS ////////////////////////////////////////////////////////////////////////////// // -// enum insFormat instruction enum ID_OPS -// scheduling -// (unused) +// enum insFormat enum IS_INFO enum ID_OPS ////////////////////////////////////////////////////////////////////////////// -IF_DEF(NONE, IS_NONE, NONE) // no operands +IF_DEF(NONE, IS_NONE, NONE) // no operands -IF_DEF(LABEL, IS_NONE, JMP ) // label -IF_DEF(RWR_LABEL, IS_R1_WR, JMP ) // write label to register -IF_DEF(SWR_LABEL, IS_SF_WR, LBL ) // write label to stack +IF_DEF(LABEL, IS_NONE, JMP ) // label +IF_DEF(RWR_LABEL, IS_R1_WR, JMP ) // write label to register +IF_DEF(SWR_LABEL, IS_SF_WR, LBL ) // write label to stack -IF_DEF(METHOD, IS_NONE, CALL) // method -IF_DEF(METHPTR, IS_NONE, CALL) // method ptr (glbl) +IF_DEF(METHOD, IS_NONE, CALL) // method +IF_DEF(METHPTR, IS_NONE, CALL) // method ptr (glbl) -IF_DEF(CNS, IS_NONE, SCNS) // const +IF_DEF(CNS, IS_NONE, SCNS) // const //---------------------------------------------------------------------------- // NOTE: The order of the "RD/WR/RW" varieties must match that of // the "insUpdateModes" enum in "instr.h". //---------------------------------------------------------------------------- -IF_DEF(RRD, IS_R1_RD, NONE) // read reg -IF_DEF(RWR, IS_R1_WR, NONE) // write reg -IF_DEF(RRW, IS_R1_RW, NONE) // r/w reg +IF_DEF(RRD, IS_R1_RD, NONE) // read reg1 +IF_DEF(RWR, IS_R1_WR, NONE) // write reg1 +IF_DEF(RRW, IS_R1_RW, NONE) // r/w reg1 + +IF_DEF(RRD_CNS, IS_R1_RD, SCNS) // read reg1, const +IF_DEF(RWR_CNS, IS_R1_WR, SCNS) // write reg1, const +IF_DEF(RRW_CNS, IS_R1_RW, SCNS) // r/w reg1, const +IF_DEF(RRW_SHF, IS_R1_RW, SCNS) // r/w reg1, shift + +IF_DEF(RRD_RRD, IS_R1_RD|IS_R2_RD, NONE) // read reg1, read reg2 +IF_DEF(RWR_RRD, IS_R1_WR|IS_R2_RD, NONE) // write reg1, read reg2 +IF_DEF(RRW_RRD, IS_R1_RW|IS_R2_RD, NONE) // r/w reg1, read reg2 +IF_DEF(RRW_RRW, IS_R1_RW|IS_R2_RW, NONE) // r/w reg1, r/w reg2 - for XCHG reg, reg2 -IF_DEF(RRD_CNS, IS_R1_RD, SCNS) // read reg , const -IF_DEF(RWR_CNS, IS_R1_WR, SCNS) // write reg , const -IF_DEF(RRW_CNS, IS_R1_RW, SCNS) // r/w reg , const -IF_DEF(RRW_SHF, IS_R1_RW, SCNS) // r/w reg , shift-const +IF_DEF(RRD_RRD_CNS, IS_R1_RD|IS_R2_RD, SCNS) // read reg1, read reg2, const +IF_DEF(RWR_RRD_CNS, IS_R1_WR|IS_R2_RD, SCNS) // write reg1, read reg2, const +IF_DEF(RRW_RRD_CNS, IS_R1_RW|IS_R2_RD, SCNS) // r/w reg1, read reg2, const -IF_DEF(RRD_RRD, IS_R1_RD|IS_R2_RD, NONE) // read reg , read reg2 -IF_DEF(RWR_RRD, IS_R1_WR|IS_R2_RD, NONE) // write reg , read reg2 -IF_DEF(RRW_RRD, IS_R1_RW|IS_R2_RD, NONE) // r/w reg , read reg2 -IF_DEF(RRW_RRW, IS_R1_RW|IS_R2_RW, NONE) // r/w reg , r/w reg2 - for XCHG reg, reg2 -IF_DEF(RRW_RRW_CNS, IS_R1_RW|IS_R2_RW, SCNS) // r/w reg , r/w reg2 , const +IF_DEF(RRD_RRD_RRD, IS_R1_RD|IS_R2_RD|IS_R3_RD, NONE) // read reg1, read reg2, read reg3 +IF_DEF(RWR_RRD_RRD, IS_R1_WR|IS_R2_RD|IS_R3_RD, NONE) // write reg1, read reg2, read reg3 +IF_DEF(RRW_RRD_RRD, IS_R1_RW|IS_R2_RD|IS_R3_RD, NONE) // r/w reg1, read reg2, read reg3 -IF_DEF(RWR_RRD_RRD, IS_R1_WR|IS_R2_RD|IS_R3_RD, NONE) // write reg , read reg2 , read reg3 -IF_DEF(RWR_RRD_RRD_CNS, IS_R1_WR|IS_R2_RD|IS_R3_RD, SCNS) // write reg , read reg2 , read reg3, const +IF_DEF(RWR_RWR_RRD, IS_R1_WR|IS_R2_WR|IS_R3_RD, NONE) // write reg1, write reg2, read reg3 + +IF_DEF(RWR_RRD_RRD_CNS, IS_R1_WR|IS_R2_RD|IS_R3_RD, SCNS) // write reg1, read reg2, read reg3, const +IF_DEF(RWR_RRD_RRD_RRD, IS_R1_WR|IS_R2_RD|IS_R3_RD|IS_R4_RD, SCNS) // write reg1, read reg2, read reg3, read reg4 -IF_DEF(RWR_RRD_RRD_RRD, IS_R1_WR|IS_R2_RD|IS_R3_RD|IS_R4_RD, CNS) // write reg , read reg2 , read reg3 , read reg4 //---------------------------------------------------------------------------- // The following formats are used for direct addresses (e.g. static data members) //---------------------------------------------------------------------------- -IF_DEF(MRD, IS_GM_RD, SPEC) // read [mem] (indirect call req. SPEC) -IF_DEF(MWR, IS_GM_WR, DSP) // write [mem] -IF_DEF(MRW, IS_GM_RW, DSP) // r/w [mem] -IF_DEF(MRD_OFF, IS_GM_RD, DSP) // offset mem +IF_DEF(MRD, IS_GM_RD, SPEC) // read [mem] (indirect call req. SPEC) +IF_DEF(MWR, IS_GM_WR, DSP) // write [mem] +IF_DEF(MRW, IS_GM_RW, DSP) // r/w [mem] + +IF_DEF(MRD_CNS, IS_GM_RD, DSP_CNS) // read [mem], const +IF_DEF(MWR_CNS, IS_GM_WR, DSP_CNS) // write [mem], const +IF_DEF(MRW_CNS, IS_GM_RW, DSP_CNS) // r/w [mem], const +IF_DEF(MRW_SHF, IS_GM_RW, DSP_CNS) // r/w [mem], shift + +IF_DEF(MRD_RRD, IS_GM_RD|IS_R1_RD, DSP) // read [mem], read reg1 +IF_DEF(MWR_RRD, IS_GM_WR|IS_R1_RD, DSP) // write [mem], read reg1 +IF_DEF(MRW_RRD, IS_GM_RW|IS_R1_RD, DSP) // r/w [mem], read reg1 + +IF_DEF(MRD_RRD_CNS, IS_GM_RD|IS_R1_RD, DSP_CNS) // read [mem], read reg1, const +IF_DEF(MWR_RRD_CNS, IS_GM_WR|IS_R1_RD, DSP_CNS) // write [mem], read reg1, const +IF_DEF(MRW_RRD_CNS, IS_GM_RW|IS_R1_RD, DSP_CNS) // r/w [mem], read reg1, const + +IF_DEF(MWR_RRD_RRD, IS_GM_WR|IS_R1_RD|IS_R2_RD, DSP) // write [mem], read reg1, read reg2 + +IF_DEF(RRD_MRD, IS_R1_RD|IS_GM_RD, DSP) // read reg1, read [mem] +IF_DEF(RWR_MRD, IS_R1_WR|IS_GM_RD, DSP) // write reg1, read [mem] +IF_DEF(RRW_MRD, IS_R1_RW|IS_GM_RD, DSP) // r/w reg1, read [mem] -IF_DEF(RRD_MRD, IS_GM_RD|IS_R1_RD, DSP) // read reg , read [mem] -IF_DEF(RWR_MRD, IS_GM_RD|IS_R1_WR, DSP) // write reg , read [mem] -IF_DEF(RRW_MRD, IS_GM_RD|IS_R1_RW, DSP) // r/w reg , read [mem] -IF_DEF(RRW_MRD_CNS, IS_GM_RD|IS_R1_RW, DSP_CNS) // r/w reg , read [mem], const +IF_DEF(RRD_MRD_CNS, IS_R1_RD|IS_GM_RD, DSP_CNS) // read reg1, read [mem], const +IF_DEF(RWR_MRD_CNS, IS_R1_WR|IS_GM_RD, DSP_CNS) // write reg1, read [mem], const +IF_DEF(RRW_MRD_CNS, IS_R1_RW|IS_GM_RD, DSP_CNS) // r/w reg1, read [mem], const -IF_DEF(RWR_RRD_MRD, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP) // write reg , read reg2 , read [mem] -IF_DEF(RWR_MRD_CNS, IS_GM_RD|IS_R1_WR, DSP_CNS) // write reg , read [mem], const -IF_DEF(RWR_RRD_MRD_CNS, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP_CNS) // write reg , read reg2 , read [mem], const -IF_DEF(RWR_RRD_MRD_RRD, IS_GM_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, DSP_CNS) // write reg , read reg2 , read [mem], read reg3 -IF_DEF(RWR_MRD_OFF, IS_GM_RD|IS_R1_WR, DSP) // write reg , offset mem +IF_DEF(RRD_MRD_RRD, IS_R1_RD|IS_GM_RD|IS_R2_RD, DSP) // read reg1, read [mem], read reg2 +IF_DEF(RWR_MRD_RRD, IS_R1_WR|IS_GM_RD|IS_R2_RD, DSP) // write reg1, read [mem], read reg2 +IF_DEF(RRW_MRD_RRD, IS_R1_RW|IS_GM_RD|IS_R2_RD, DSP) // r/w reg1, read [mem], read reg2 -IF_DEF(MRD_RRD, IS_GM_RD|IS_R1_RD, DSP) // read [mem], read reg -IF_DEF(MWR_RRD, IS_GM_WR|IS_R1_RD, DSP) // write [mem], read reg -IF_DEF(MRW_RRD, IS_GM_RW|IS_R1_RD, DSP) // r/w [mem], read reg +IF_DEF(RRD_RRD_MRD, IS_R1_RD|IS_R2_RD|IS_GM_RD, DSP) // read reg1, read reg2, read [mem] +IF_DEF(RWR_RRD_MRD, IS_R1_WR|IS_R2_RD|IS_GM_RD, DSP) // write reg1, read reg2, read [mem] +IF_DEF(RRW_RRD_MRD, IS_R1_RW|IS_R2_RD|IS_GM_RD, DSP) // r/w reg1, read reg2, read [mem] -IF_DEF(MRD_CNS, IS_GM_RD, DSP_CNS) // read [mem], const -IF_DEF(MWR_CNS, IS_GM_WR, DSP_CNS) // write [mem], const -IF_DEF(MRW_CNS, IS_GM_RW, DSP_CNS) // r/w [mem], const +IF_DEF(RWR_RWR_MRD, IS_R1_WR|IS_R2_WR|IS_GM_RD, DSP) // write reg1, write reg2, read [mem] -IF_DEF(MWR_RRD_CNS, IS_GM_WR|IS_R1_RD, DSP_CNS) // write [mem], read reg, const +IF_DEF(RWR_RRD_MRD_CNS, IS_R1_WR|IS_R2_RD|IS_GM_RD, DSP_CNS) // write reg1, read reg2, read [mem], const +IF_DEF(RWR_RRD_MRD_RRD, IS_R1_WR|IS_R2_RD|IS_GM_RD|IS_R3_RD, DSP_CNS) // write reg1, read reg2, read [mem], read reg3 -IF_DEF(MRW_SHF, IS_GM_RW, DSP_CNS) // shift [mem], const +IF_DEF(MRD_OFF, IS_GM_RD, DSP) // read [mem + offset] +IF_DEF(RWR_MRD_OFF, IS_R1_WR|IS_GM_RD, DSP) // write reg1, read [mem + offset] //---------------------------------------------------------------------------- // The following formats are used for stack frame refs //---------------------------------------------------------------------------- -IF_DEF(SRD, IS_SF_RD, SPEC) // read [stk] (indirect call req. SPEC) -IF_DEF(SWR, IS_SF_WR, NONE) // write [stk] -IF_DEF(SRW, IS_SF_RW, NONE) // r/w [stk] +IF_DEF(SRD, IS_SF_RD, SPEC) // read [stk] (indirect call req. SPEC) +IF_DEF(SWR, IS_SF_WR, NONE) // write [stk] +IF_DEF(SRW, IS_SF_RW, NONE) // r/w [stk] -IF_DEF(RRD_SRD, IS_SF_RD|IS_R1_RD, NONE) // read reg , read [stk] -IF_DEF(RWR_SRD, IS_SF_RD|IS_R1_WR, NONE) // write reg , read [stk] -IF_DEF(RRW_SRD, IS_SF_RD|IS_R1_RW, NONE) // r/w reg , read [stk] -IF_DEF(RRW_SRD_CNS, IS_SF_RD|IS_R1_RW, CNS ) // r/w reg , read [stk], const +IF_DEF(SRD_CNS, IS_SF_RD, CNS) // read [stk], const +IF_DEF(SWR_CNS, IS_SF_WR, CNS) // write [stk], const +IF_DEF(SRW_CNS, IS_SF_RW, CNS) // r/w [stk], const +IF_DEF(SRW_SHF, IS_SF_RW, CNS) // r/w [stk], shift -IF_DEF(RWR_RRD_SRD, IS_SF_RD|IS_R1_WR|IS_R2_RD, NONE) // write reg , read reg2, read [stk] -IF_DEF(RWR_SRD_CNS, IS_SF_RD|IS_R1_WR, CNS ) // write reg , read [stk], const -IF_DEF(RWR_RRD_SRD_CNS, IS_SF_RD|IS_R1_WR|IS_R2_RD, CNS ) // write reg , read reg2, read [stk], const -IF_DEF(RWR_RRD_SRD_RRD, IS_SF_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, CNS ) // write reg , read reg2, read [stk], read reg3 +IF_DEF(SRD_RRD, IS_SF_RD|IS_R1_RD, NONE) // read [stk], read reg1 +IF_DEF(SWR_RRD, IS_SF_WR|IS_R1_RD, NONE) // write [stk], read reg1 +IF_DEF(SRW_RRD, IS_SF_RW|IS_R1_RD, NONE) // r/w [stk], read reg1 -IF_DEF(SRD_RRD, IS_SF_RD|IS_R1_RD, NONE) // read [stk], read reg -IF_DEF(SWR_RRD, IS_SF_WR|IS_R1_RD, NONE) // write [stk], read reg -IF_DEF(SRW_RRD, IS_SF_RW|IS_R1_RD, NONE) // r/w [stk], read reg +IF_DEF(SRD_RRD_CNS, IS_SF_RD|IS_R1_RD, CNS) // read [stk], read reg1, const +IF_DEF(SWR_RRD_CNS, IS_SF_WR|IS_R1_RD, CNS) // write [stk], read reg1, const +IF_DEF(SRW_RRD_CNS, IS_SF_RW|IS_R1_RD, CNS) // r/w [stk], read reg1, const -IF_DEF(SRD_CNS, IS_SF_RD, CNS ) // read [stk], const -IF_DEF(SWR_CNS, IS_SF_WR, CNS ) // write [stk], const -IF_DEF(SRW_CNS, IS_SF_RW, CNS ) // r/w [stk], const +IF_DEF(SWR_RRD_RRD, IS_SF_WR|IS_R1_RD|IS_R2_RD, NONE) // write [stk], read reg1, read reg2 -IF_DEF(SWR_RRD_CNS, IS_AM_WR|IS_R1_RD, AMD_CNS) // write [stk], read reg, const +IF_DEF(RRD_SRD, IS_R1_RD|IS_SF_RD, NONE) // read reg1, read [stk] +IF_DEF(RWR_SRD, IS_R1_WR|IS_SF_RD, NONE) // write reg1, read [stk] +IF_DEF(RRW_SRD, IS_R1_RW|IS_SF_RD, NONE) // r/w reg1, read [stk] -IF_DEF(SRW_SHF, IS_SF_RW, CNS ) // shift [stk], const +IF_DEF(RRD_SRD_CNS, IS_R1_RD|IS_SF_RD, CNS) // read reg1, read [stk], const +IF_DEF(RWR_SRD_CNS, IS_R1_WR|IS_SF_RD, CNS) // write reg1, read [stk], const +IF_DEF(RRW_SRD_CNS, IS_R1_RW|IS_SF_RD, CNS) // r/w reg1, read [stk], const + +IF_DEF(RRD_SRD_RRD, IS_R1_RD|IS_SF_RD|IS_R2_RD, NONE) // read reg1, read [stk], read reg2 +IF_DEF(RWR_SRD_RRD, IS_R1_WR|IS_SF_RD|IS_R2_RD, NONE) // write reg1, read [stk], read reg2 +IF_DEF(RRW_SRD_RRD, IS_R1_RW|IS_SF_RD|IS_R2_RD, NONE) // r/w reg1, read [stk], read reg2 + +IF_DEF(RRD_RRD_SRD, IS_R1_RD|IS_R2_RD|IS_SF_RD, NONE) // read reg1, read reg2, read [stk] +IF_DEF(RWR_RRD_SRD, IS_R1_WR|IS_R2_RD|IS_SF_RD, NONE) // write reg1, read reg2, read [stk] +IF_DEF(RRW_RRD_SRD, IS_R1_RW|IS_R2_RD|IS_SF_RD, NONE) // r/w reg1, read reg2, read [stk] + +IF_DEF(RWR_RWR_SRD, IS_R1_WR|IS_R2_WR|IS_SF_RD, NONE) // write reg1, write reg2, read [stk] + +IF_DEF(RWR_RRD_SRD_CNS, IS_R1_WR|IS_R2_RD|IS_SF_RD, CNS) // write reg1, read reg2, read [stk], const +IF_DEF(RWR_RRD_SRD_RRD, IS_R1_WR|IS_R2_RD|IS_SF_RD|IS_R3_RD, CNS) // write reg1, read reg2, read [stk], read reg3 //---------------------------------------------------------------------------- // The following formats are used for indirect address modes //---------------------------------------------------------------------------- +IF_DEF(ARD, IS_AM_RD, SPEC) // read [adr] (indirect call req. SPEC) +IF_DEF(AWR, IS_AM_WR, AMD) // write [adr] +IF_DEF(ARW, IS_AM_RW, AMD) // r/w [adr] + +IF_DEF(ARD_CNS, IS_AM_RD, AMD_CNS) // read [adr], const +IF_DEF(AWR_CNS, IS_AM_WR, AMD_CNS) // write [adr], const +IF_DEF(ARW_CNS, IS_AM_RW, AMD_CNS) // r/w [adr], const +IF_DEF(ARW_SHF, IS_AM_RW, AMD_CNS) // r/w [adr], shift + +IF_DEF(ARD_RRD, IS_AM_RD|IS_R1_RD, AMD) // read [adr], read reg1 +IF_DEF(AWR_RRD, IS_AM_WR|IS_R1_RD, AMD) // write [adr], read reg1 +IF_DEF(ARW_RRD, IS_AM_RW|IS_R1_RD, AMD) // r/w [adr], read reg1 -IF_DEF(ARD, IS_AM_RD, SPEC) // read [adr] (indirect call req. SPEC) -IF_DEF(AWR, IS_AM_WR, AMD ) // write [adr] -IF_DEF(ARW, IS_AM_RW, AMD ) // r/w [adr] +IF_DEF(ARD_RRD_CNS, IS_AM_RD|IS_R1_RD, AMD_CNS) // read [adr], read reg1, const +IF_DEF(AWR_RRD_CNS, IS_AM_WR|IS_R1_RD, AMD_CNS) // write [adr], read reg1, const +IF_DEF(ARW_RRD_CNS, IS_AM_RW|IS_R1_RD, AMD_CNS) // r/w [adr], read reg1, const -IF_DEF(RRD_ARD, IS_AM_RD|IS_R1_RD, AMD ) // read reg , read [adr] -IF_DEF(RWR_ARD, IS_AM_RD|IS_R1_WR, AMD ) // write reg , read [adr] -IF_DEF(RRW_ARD, IS_AM_RD|IS_R1_RW, AMD ) // r/w reg , read [adr] -IF_DEF(RRW_ARD_CNS, IS_AM_RD|IS_R1_RW, AMD_CNS) // r/w reg , read [adr], const +IF_DEF(AWR_RRD_RRD, IS_AM_WR|IS_R1_RD|IS_R2_RD, AMD_CNS) // write [adr], read reg1, read reg2 -IF_DEF(RWR_RRD_ARD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD ) // write reg , read reg2, read [adr] -IF_DEF(RWR_ARD_CNS, IS_AM_RD|IS_R1_WR, AMD_CNS) // write reg , read [adr], const -IF_DEF(RWR_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD) // write reg , read [adr], read reg2 -IF_DEF(RWR_RRD_ARD_CNS, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD_CNS) // write reg , read reg2, read [adr], const -IF_DEF(RWR_RRD_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, AMD_CNS) // write reg , read reg2, read [adr], read reg3 +IF_DEF(RRD_ARD, IS_R1_RD|IS_AM_RD, AMD) // read reg1, read [adr] +IF_DEF(RWR_ARD, IS_R1_WR|IS_AM_RD, AMD) // write reg1, read [adr] +IF_DEF(RRW_ARD, IS_R1_RW|IS_AM_RD, AMD) // r/w reg1, read [adr] -IF_DEF(ARD_RRD, IS_AM_RD|IS_R1_RD, AMD ) // read [adr], read reg -IF_DEF(AWR_RRD, IS_AM_WR|IS_R1_RD, AMD ) // write [adr], read reg -IF_DEF(ARW_RRD, IS_AM_RW|IS_R1_RD, AMD ) // r/w [adr], read reg +IF_DEF(RRD_ARD_CNS, IS_R1_RD|IS_AM_RD, AMD_CNS) // read reg1, read [adr], const +IF_DEF(RWR_ARD_CNS, IS_R1_WR|IS_AM_RD, AMD_CNS) // write reg1, read [adr], const +IF_DEF(RRW_ARD_CNS, IS_R1_RW|IS_AM_RD, AMD_CNS) // r/w reg1, read [adr], const -IF_DEF(AWR_RRD_RRD, IS_AM_WR|IS_R1_RD|IS_R2_RD, AMD ) // write [adr], read reg, read reg +IF_DEF(RRD_ARD_RRD, IS_R1_RD|IS_AM_RD|IS_R2_RD, AMD) // read reg1, read [adr], read reg2 +IF_DEF(RWR_ARD_RRD, IS_R1_WR|IS_AM_RD|IS_R2_RD, AMD) // write reg1, read [adr], read reg2 +IF_DEF(RRW_ARD_RRD, IS_R1_RW|IS_AM_RD|IS_R2_RD, AMD) // r/w reg1, read [adr], read reg2 -IF_DEF(ARD_CNS, IS_AM_RD, AMD_CNS) // read [adr], const -IF_DEF(AWR_CNS, IS_AM_WR, AMD_CNS) // write [adr], const -IF_DEF(ARW_CNS, IS_AM_RW, AMD_CNS) // r/w [adr], const +IF_DEF(RRD_RRD_ARD, IS_R1_RD|IS_R2_RD|IS_AM_RD, AMD) // read reg1, read reg2, read [adr] +IF_DEF(RWR_RRD_ARD, IS_R1_WR|IS_R2_RD|IS_AM_RD, AMD) // write reg1, read reg2, read [adr] +IF_DEF(RRW_RRD_ARD, IS_R1_RW|IS_R2_RD|IS_AM_RD, AMD) // r/w reg1, read reg2, read [adr] -IF_DEF(AWR_RRD_CNS, IS_AM_WR|IS_R1_RD, AMD_CNS) // write [adr], read reg, const +IF_DEF(RWR_RWR_ARD, IS_R1_WR|IS_R2_WR|IS_AM_RD, AMD) // write reg1, write reg2, read [adr] -IF_DEF(ARW_SHF, IS_AM_RW, AMD_CNS) // shift [adr], const +IF_DEF(RWR_RRD_ARD_CNS, IS_R1_WR|IS_R2_RD|IS_AM_RD, AMD_CNS) // write reg1, read reg2, read [adr], const +IF_DEF(RWR_RRD_ARD_RRD, IS_R1_WR|IS_R2_RD|IS_AM_RD|IS_R3_RD, AMD_CNS) // write reg1, read reg2, read [adr], read reg3 ////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/emitloongarch64.cpp b/src/coreclr/jit/emitloongarch64.cpp index cab014a0c50de0..53a19b45770b67 100644 --- a/src/coreclr/jit/emitloongarch64.cpp +++ b/src/coreclr/jit/emitloongarch64.cpp @@ -420,9 +420,9 @@ const emitJumpKind emitReverseJumpKinds[] = { * Return the allocated size (in bytes) of the given instruction descriptor. */ -size_t emitter::emitSizeOfInsDsc(instrDesc* id) +size_t emitter::emitSizeOfInsDsc(instrDesc* id) const { - if (emitIsScnsInsDsc(id)) + if (emitIsSmallInsDsc(id)) return SMALL_IDSC_SIZE; insOpts insOp = id->idInsOpt(); @@ -2455,9 +2455,8 @@ void emitter::emitIns_Call(EmitCallType callType, unsigned emitter::emitOutputCall(insGroup* ig, BYTE* dst, instrDesc* id, code_t code) { - unsigned char callInstrSize = sizeof(code_t); // 4 bytes - regMaskTP gcrefRegs; - regMaskTP byrefRegs; + regMaskTP gcrefRegs; + regMaskTP byrefRegs; VARSET_TP GCvars(VarSetOps::UninitVal()); @@ -2621,25 +2620,17 @@ unsigned emitter::emitOutputCall(insGroup* ig, BYTE* dst, instrDesc* id, code_t // So we're not really doing a "stack pop" here (note that "args" is 0), but we use this mechanism // to record the call for GC info purposes. (It might be best to use an alternate call, // and protect "emitStackPop" under the EMIT_TRACK_STACK_DEPTH preprocessor variable.) - emitStackPop(dst, /*isCall*/ true, callInstrSize, /*args*/ 0); + emitStackPop(dst, /*isCall*/ true, sizeof(code_t), /*args*/ 0); // Do we need to record a call location for GC purposes? // if (!emitFullGCinfo) { - emitRecordGCcall(dst, callInstrSize); + emitRecordGCcall(dst, sizeof(code_t)); } } - if (id->idIsCallRegPtr()) - { - callInstrSize = 1 << 2; - } - else - { - callInstrSize = id->idIsReloc() ? (2 << 2) : (4 << 2); // INS_OPTS_C: 2/4-ins. - } - return callInstrSize; + return id->idCodeSize(); } //---------------------------------------------------------------------------------- @@ -3098,7 +3089,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) BYTE* dstRW2 = dstRW + 4; // addr for updating gc info if needed. code_t code = 0; instruction ins; - size_t sz; // = emitSizeOfInsDsc(id); + size_t sz; #ifdef DEBUG #if DUMP_GC_TABLES @@ -3779,11 +3770,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } #ifdef DEBUG - /* Make sure we set the instruction descriptor size correctly */ - - // size_t expected = emitSizeOfInsDsc(id); - // assert(sz == expected); - if (emitComp->opts.disAsm || emitComp->verbose) { code_t* cp = (code_t*)(*dp + writeableOffset); @@ -5960,13 +5946,26 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) } } +/***************************************************************************** + * + * For LoongArch64, the `emitter::emitDispIns` only supports + * the `DOTNET_JitDump`. + */ void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { - // LA implements this similar by `emitter::emitDisInsName`. - // For LA maybe the `emitDispIns` is over complicate. - // The `emitter::emitDisInsName` is focused on the most important for debugging. - NYI_LOONGARCH64("LA not used the emitter::emitDispIns"); + if (ig) + { + BYTE* addr = emitCodeBlock + offset + writeableOffset; + + int size = id->idCodeSize(); + while (size > 0) + { + emitDisInsName(*(code_t*)addr, addr, id); + addr += 4; + size -= 4; + } + } } /***************************************************************************** diff --git a/src/coreclr/jit/emitloongarch64.h b/src/coreclr/jit/emitloongarch64.h index fcbb32fa7d17f4..da0452902646c4 100644 --- a/src/coreclr/jit/emitloongarch64.h +++ b/src/coreclr/jit/emitloongarch64.h @@ -20,14 +20,9 @@ struct CnsVal }; #ifdef DEBUG - /************************************************************************/ /* Debug-only routines to display instructions */ /************************************************************************/ - -const char* emitFPregName(unsigned reg, bool varName = true); -const char* emitVectorRegName(regNumber reg); - void emitDisInsName(code_t code, const BYTE* addr, instrDesc* id); #endif // DEBUG diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index bff4816e53a515..df007bfc270348 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -76,9 +76,9 @@ const emitJumpKind emitReverseJumpKinds[] = { * Return the allocated size (in bytes) of the given instruction descriptor. */ -size_t emitter::emitSizeOfInsDsc(instrDesc* id) +size_t emitter::emitSizeOfInsDsc(instrDesc* id) const { - if (emitIsScnsInsDsc(id)) + if (emitIsSmallInsDsc(id)) return SMALL_IDSC_SIZE; insOpts insOp = id->idInsOpt(); @@ -319,9 +319,10 @@ void emitter::emitIns_S_R_R(instruction ins, emitAttr attr, regNumber reg1, regN id->idIns(ins); + assert(isGeneralRegister(reg2)); code_t code = emitInsCode(ins); code |= (code_t)(reg1 & 0x1f) << 20; - code |= (code_t)(reg2 & 0x1f) << 15; + code |= (code_t)reg2 << 15; code |= (((imm >> 5) & 0x7f) << 25) | ((imm & 0x1f) << 7); id->idAddr()->iiaSetInstrEncode(code); @@ -566,26 +567,37 @@ void emitter::emitIns_R_R( code |= reg1 << 7; code |= reg2 << 15; } - else if ((INS_fcvt_w_s <= ins && INS_fmv_x_w >= ins) || (INS_fclass_s == ins || INS_fclass_d == ins) || - (INS_fcvt_w_d == ins || INS_fcvt_wu_d == ins) || (INS_fcvt_l_s == ins || INS_fcvt_lu_s == ins) || - (INS_fmv_x_d == ins)) + else if (INS_fmv_x_d == ins || INS_fmv_x_w == ins || INS_fclass_s == ins || INS_fclass_d == ins) { - // TODO-RISCV64-CQ: Check rounding mode assert(isGeneralRegisterOrR0(reg1)); assert(isFloatReg(reg2)); - code |= (reg1 & 0x1f) << 7; + code |= reg1 << 7; code |= (reg2 & 0x1f) << 15; } - else if ((INS_fcvt_s_w <= ins && INS_fmv_w_x >= ins) || (INS_fcvt_d_w == ins || INS_fcvt_d_wu == ins) || - (INS_fcvt_s_l == ins || INS_fcvt_s_lu == ins) || (INS_fmv_d_x == ins) || - (INS_fcvt_d_l == ins || INS_fcvt_d_lu == ins)) - + else if (INS_fcvt_w_s == ins || INS_fcvt_wu_s == ins || INS_fcvt_w_d == ins || INS_fcvt_wu_d == ins || + INS_fcvt_l_s == ins || INS_fcvt_lu_s == ins || INS_fcvt_l_d == ins || INS_fcvt_lu_d == ins) + { + assert(isGeneralRegisterOrR0(reg1)); + assert(isFloatReg(reg2)); + code |= reg1 << 7; + code |= (reg2 & 0x1f) << 15; + code |= 0x1 << 12; + } + else if (INS_fmv_w_x == ins || INS_fmv_d_x == ins) { - // TODO-RISCV64-CQ: Check rounding mode assert(isFloatReg(reg1)); assert(isGeneralRegisterOrR0(reg2)); code |= (reg1 & 0x1f) << 7; - code |= (reg2 & 0x1f) << 15; + code |= reg2 << 15; + } + else if (INS_fcvt_s_w == ins || INS_fcvt_s_wu == ins || INS_fcvt_d_w == ins || INS_fcvt_d_wu == ins || + INS_fcvt_s_l == ins || INS_fcvt_s_lu == ins || INS_fcvt_d_l == ins || INS_fcvt_d_lu == ins) + { + assert(isFloatReg(reg1)); + assert(isGeneralRegisterOrR0(reg2)); + code |= (reg1 & 0x1f) << 7; + code |= reg2 << 15; + code |= 0x7 << 12; } else if (INS_fcvt_s_d == ins || INS_fcvt_d_s == ins) { @@ -593,6 +605,7 @@ void emitter::emitIns_R_R( assert(isFloatReg(reg2)); code |= (reg1 & 0x1f) << 7; code |= (reg2 & 0x1f) << 15; + code |= 0x7 << 12; } else { @@ -623,20 +636,24 @@ void emitter::emitIns_R_R_I( (INS_lb <= ins && INS_lhu >= ins) || INS_ld == ins || INS_lw == ins || INS_jalr == ins || INS_fld == ins || INS_flw == ins) { - code |= (reg1 & 0x1f) << 7; // rd - code |= (reg2 & 0x1f) << 15; // rs1 - code |= imm << 20; // imm + assert(isGeneralRegister(reg2)); + code |= (reg1 & 0x1f) << 7; // rd + code |= reg2 << 15; // rs1 + code |= imm << 20; // imm } else if (INS_sd == ins || INS_sw == ins || INS_sh == ins || INS_sb == ins || INS_fsw == ins || INS_fsd == ins) { + assert(isGeneralRegister(reg2)); code |= (reg1 & 0x1f) << 20; // rs2 - code |= (reg2 & 0x1f) << 15; // rs1 + code |= reg2 << 15; // rs1 code |= (((imm >> 5) & 0x7f) << 25) | ((imm & 0x1f) << 7); // imm } else if (INS_beq <= ins && INS_bgeu >= ins) { - code |= (reg1 & 0x1f) << 15; - code |= (reg2 & 0x1f) << 20; + assert(isGeneralRegister(reg1)); + assert(isGeneralRegister(reg2)); + code |= reg1 << 15; + code |= reg2 << 20; code |= ((imm >> 11) & 0x1) << 7; code |= ((imm >> 1) & 0xf) << 8; code |= ((imm >> 5) & 0x3f) << 25; @@ -746,6 +763,10 @@ void emitter::emitIns_R_R_R( code |= ((reg1 & 0x1f) << 7); code |= ((reg2 & 0x1f) << 15); code |= ((reg3 & 0x1f) << 20); + if ((INS_fadd_s <= ins && INS_fsqrt_s >= ins) || (INS_fadd_d <= ins && INS_fsqrt_d >= ins)) + { + code |= 0x7 << 12; + } } else { @@ -1087,45 +1108,56 @@ void emitter::emitIns_I_la(emitAttr size, regNumber reg, ssize_t imm) { assert(!EA_IS_RELOC(size)); assert(isGeneralRegister(reg)); - if (0 == ((imm + 0x800) >> 32)) + + // TODO-CQ-RISCV: at least for imm=-2*1024*1024*1024 (and similar ones) code can be simplified to "lui rd, 0x80000" + + if (0 == ((imm + 0x800) >> 31)) { if (((imm + 0x800) >> 12) != 0) { emitIns_R_I(INS_lui, size, reg, ((imm + 0x800) >> 12)); if ((imm & 0xFFF) != 0) { - emitIns_R_R_I(INS_addiw, size, reg, reg, imm & 0xFFF); + emitIns_R_R_I(size == EA_4BYTE ? INS_addiw : INS_addi, size, reg, reg, imm & 0xFFF); } } else { - emitIns_R_R_I(INS_addiw, size, reg, REG_R0, imm & 0xFFF); + emitIns_R_R_I(size == EA_4BYTE ? INS_addiw : INS_addi, size, reg, REG_R0, imm & 0xFFF); } } else { - UINT32 high = (imm >> 32) & 0xffffffff; + UINT32 high = (imm >> 33) & 0x7fffffff; + regNumber highReg = reg; if (((high + 0x800) >> 12) != 0) { - emitIns_R_I(INS_lui, size, reg, ((high + 0x800) >> 12)); + emitIns_R_I(INS_lui, size, highReg, ((high + 0x800) >> 12)); if ((high & 0xFFF) != 0) { - emitIns_R_R_I(INS_addi, size, reg, reg, high & 0xFFF); + emitIns_R_R_I(size == EA_4BYTE ? INS_addiw : INS_addi, size, highReg, highReg, high & 0xFFF); } } else if ((high & 0xFFF) != 0) { - emitIns_R_R_I(INS_addi, size, reg, REG_R0, high & 0xFFF); + emitIns_R_R_I(size == EA_4BYTE ? INS_addiw : INS_addi, size, highReg, REG_R0, high & 0xFFF); } - UINT32 low = imm & 0xffffffff; - emitIns_R_R_I(INS_slli, size, reg, reg, 11); - emitIns_R_R_I(INS_addi, size, reg, reg, (low >> 21) & 0x7FF); + else + { + highReg = REG_R0; + } + UINT64 low = imm & 0x1ffffffff; + if (highReg != REG_R0) + { + emitIns_R_R_I(size == EA_4BYTE ? INS_slliw : INS_slli, size, highReg, highReg, 11); + } + emitIns_R_R_I(size == EA_4BYTE ? INS_addiw : INS_addi, size, reg, highReg, (low >> 22) & 0x7FF); - emitIns_R_R_I(INS_slli, size, reg, reg, 11); - emitIns_R_R_I(INS_addi, size, reg, reg, (low >> 10) & 0x7FF); + emitIns_R_R_I(size == EA_4BYTE ? INS_slliw : INS_slli, size, reg, reg, 11); + emitIns_R_R_I(size == EA_4BYTE ? INS_addiw : INS_addi, size, reg, reg, (low >> 11) & 0x7FF); - emitIns_R_R_I(INS_slli, size, reg, reg, 10); - emitIns_R_R_I(INS_addi, size, reg, reg, low & 0x3FF); + emitIns_R_R_I(size == EA_4BYTE ? INS_slliw : INS_slli, size, reg, reg, 11); + emitIns_R_R_I(size == EA_4BYTE ? INS_addiw : INS_addi, size, reg, reg, low & 0x7FF); } } @@ -1478,7 +1510,7 @@ unsigned emitter::emitOutputCall(insGroup* ig, BYTE* dst, instrDesc* id, code_t dst += 4; code = emitInsCode(INS_jalr); - code |= (code_t)(reg2 & 0x1f) << 7; + code |= (code_t)reg2 << 7; code |= (code_t)REG_T2 << 15; code |= (low & 0x3ff) << 20; // the offset default is 0; @@ -2205,12 +2237,12 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert(code == 0x00000013); #endif code = 0x00000013 | (codeGen->rsGetRsvdReg() << 15); - *(code_t*)dstRW = code | ((code_t)(reg1 & 0x1f) << 7) | (((code_t)doff & 0xfff) << 20); + *(code_t*)dstRW = code | ((code_t)reg1 << 7) | (((code_t)doff & 0xfff) << 20); } else { code = emitInsCode(ins); - code |= (code_t)((reg1 & 0x1f) << 7); + code |= (code_t)(reg1 & 0x1f) << 7; code |= (code_t)codeGen->rsGetRsvdReg() << 15; code |= (code_t)(doff & 0xfff) << 20; *(code_t*)dstRW = code; @@ -2417,8 +2449,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert((INS_bne & 0xefff) == INS_beq); code = emitInsCode((instruction)((int)ins ^ 0x1000)); - code |= ((code_t)(reg1) /*& 0x1f */) << 15; /* rj */ - code |= ((code_t)(reg2) /*& 0x1f */) << 20; /* rd */ + code |= (code_t)reg1 << 15; /* rj */ + code |= (code_t)reg2 << 20; /* rd */ code |= 0x8 << 7; *(code_t*)dstRW = code; dstRW += 4; @@ -2440,8 +2472,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert((INS_bgeu & 0xefff) == INS_bltu); code = emitInsCode((instruction)((int)ins ^ 0x1000)); - code |= ((code_t)(reg1) /*& 0x1f */) << 15; /* rj */ - code |= ((code_t)(reg2) /*& 0x1f */) << 20; /* rd */ + code |= (code_t)reg1 << 15; /* rj */ + code |= (code_t)reg2 << 20; /* rd */ code |= 0x8 << 7; *(code_t*)dstRW = code; dstRW += 4; @@ -3225,7 +3257,7 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) case 0x70: // FMV.X.W & FCLASS.S if (opcode4 == 0) // FMV.X.W { - printf("fmv.x.w %s, %s\n", xd, xs1); + printf("fmv.x.w %s, %s\n", xd, fs1); } else if (opcode4 == 1) // FCLASS.S { @@ -3247,7 +3279,7 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) } else if (opcode4 == 2) // FEQ.S { - printf("feq.s %s, %s, %s\n", fd, xs1, fs2); + printf("feq.s %s, %s, %s\n", xd, fs1, fs2); } else { @@ -3371,7 +3403,7 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) { printf("fcvt.w.d %s, %s\n", xd, fs1); } - if (opcode3 == 1) // FCVT.WU.D + else if (opcode3 == 1) // FCVT.WU.D { printf("fcvt.wu.d %s, %s\n", xd, fs1); } @@ -3383,7 +3415,6 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) { printf("fcvt.lu.d %s, %s\n", xd, fs1); } - else { NYI_RISCV64("illegal ins within emitDisInsName!"); @@ -4051,6 +4082,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, emitIns_R_R_I(INS_srli, EA_8BYTE, regOp2, regOp2, 32); } } + if (needCheckOv) { assert(!varTypeIsFloating(dst)); @@ -4060,6 +4092,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, if (dst->GetRegNum() == regOp1) { assert(codeGen->rsGetRsvdReg() != regOp1); + assert(REG_RA != regOp1); saveOperReg1 = codeGen->rsGetRsvdReg(); saveOperReg2 = regOp2; emitIns_R_R_I(INS_addi, attr, codeGen->rsGetRsvdReg(), regOp1, 0); @@ -4067,6 +4100,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, else if (dst->GetRegNum() == regOp2) { assert(codeGen->rsGetRsvdReg() != regOp2); + assert(REG_RA != regOp2); saveOperReg1 = regOp1; saveOperReg2 = codeGen->rsGetRsvdReg(); emitIns_R_R_I(INS_addi, attr, codeGen->rsGetRsvdReg(), regOp2, 0); @@ -4107,7 +4141,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, else { tempReg1 = REG_RA; // src1->GetSingleTempReg(); - tempReg2 = codeGen->rsGetRsvdReg(); + tempReg2 = REG_T5; // TODO-RISCV64-Bug?: Assign proper temp register assert(tempReg1 != tempReg2); assert(tempReg1 != saveOperReg1); assert(tempReg2 != saveOperReg2); diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 4e25a445bbaa80..5014781e3bce50 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -170,18 +170,25 @@ regNumber emitter::getSseShiftRegNumber(instruction ins) } } +bool emitter::HasVexEncoding(instruction ins) const +{ + insFlags flags = CodeGenInterface::instInfo[ins]; + return (flags & Encoding_VEX) != 0; +} + +bool emitter::HasEvexEncoding(instruction ins) const +{ + insFlags flags = CodeGenInterface::instInfo[ins]; + return (flags & Encoding_EVEX) != 0; +} + bool emitter::IsVexEncodableInstruction(instruction ins) const { if (!UseVEXEncoding()) { return false; } - - // There is also Translate_VEX, however we expect codegen to have handled - // this difference and given us the VEX exclusive version of the instruction - - insFlags flags = CodeGenInterface::instInfo[ins]; - return (flags & Encoding_VEX) != 0; + return HasVexEncoding(ins); } //------------------------------------------------------------------------ @@ -199,12 +206,7 @@ bool emitter::IsEvexEncodableInstruction(instruction ins) const { return false; } - - // There is also Translate_EVEX, however we expect codegen to have handled - // this difference and given us the EVEX exclusive version of the instruction - - insFlags flags = CodeGenInterface::instInfo[ins]; - return (flags & Encoding_EVEX) != 0; + return HasEvexEncoding(ins); } //------------------------------------------------------------------------ @@ -662,6 +664,30 @@ bool emitter::emitIsInstrWritingToReg(instrDesc* id, regNumber reg) case INS_call: return true; + case INS_imul_AX: + case INS_imul_BP: + case INS_imul_BX: + case INS_imul_CX: + case INS_imul_DI: + case INS_imul_DX: + case INS_imul_SI: + case INS_imul_SP: +#ifdef TARGET_AMD64 + case INS_imul_08: + case INS_imul_09: + case INS_imul_10: + case INS_imul_11: + case INS_imul_12: + case INS_imul_13: + case INS_imul_14: + case INS_imul_15: +#endif // TARGET_AMD64 + if (reg == inst3opImulReg(ins)) + { + return true; + } + break; + // These always write to RAX and RDX. case INS_idiv: case INS_div: @@ -752,85 +778,19 @@ bool emitter::emitIsInstrWritingToReg(instrDesc* id, regNumber reg) } #endif // TARGET_64BIT - switch (id->idInsFmt()) + if (id->idIsReg1Write() && (id->idReg1() == reg)) { - case IF_RWR: - case IF_RRW: - - case IF_RWR_CNS: - case IF_RRW_CNS: - case IF_RRW_SHF: - - case IF_RWR_RRD: - case IF_RRW_RRD: - case IF_RRW_RRW: - case IF_RRW_RRW_CNS: - - case IF_RWR_RRD_RRD: - case IF_RWR_RRD_RRD_CNS: - - case IF_RWR_RRD_RRD_RRD: - - case IF_RWR_MRD: - case IF_RRW_MRD: - case IF_RRW_MRD_CNS: - - case IF_RWR_RRD_MRD: - case IF_RWR_MRD_CNS: - case IF_RWR_RRD_MRD_CNS: - case IF_RWR_RRD_MRD_RRD: - case IF_RWR_MRD_OFF: - - case IF_RWR_SRD: - case IF_RRW_SRD: - case IF_RRW_SRD_CNS: - - case IF_RWR_RRD_SRD: - case IF_RWR_SRD_CNS: - case IF_RWR_RRD_SRD_CNS: - case IF_RWR_RRD_SRD_RRD: - - case IF_RWR_ARD: - case IF_RRW_ARD: - case IF_RRW_ARD_CNS: - - case IF_RWR_RRD_ARD: - case IF_RWR_ARD_CNS: - case IF_RWR_ARD_RRD: - case IF_RWR_RRD_ARD_CNS: - case IF_RWR_RRD_ARD_RRD: - { - if (id->idReg1() != reg) - { - switch (id->idInsFmt()) - { - // Handles instructions who write to two registers. - case IF_RRW_RRW: - case IF_RRW_RRW_CNS: - { - if (id->idReg2() == reg) - { - return true; - } - break; - } - - default: - break; - } - - return false; - } - - return true; - } + return true; + } - default: - { - return false; - } + if (id->idIsReg2Write() && (id->idReg2() == reg)) + { + return true; } + assert(!id->idIsReg3Write()); + assert(!id->idIsReg4Write()); + return false; } @@ -927,47 +887,30 @@ bool emitter::AreFlagsSetToZeroCmp(regNumber reg, emitAttr opSize, GenCondition return false; } - // Only consider if safe - // if (!emitCanPeepholeLastIns()) { + // Don't consider if not safe return false; } instrDesc* id = emitLastIns; instruction lastIns = id->idIns(); - insFormat fmt = id->idInsFmt(); - // make sure op1 is a reg - switch (fmt) + if (!id->idIsReg1Write() || (id->idReg1() != reg)) { - case IF_RWR_CNS: - case IF_RRW_CNS: - case IF_RRW_SHF: - case IF_RWR_RRD: - case IF_RRW_RRD: - case IF_RWR_MRD: - case IF_RWR_SRD: - case IF_RRW_SRD: - case IF_RWR_ARD: - case IF_RRW_ARD: - case IF_RWR: - case IF_RRD: - case IF_RRW: - case IF_RWR_RRD_RRD: - case IF_RWR_RRD_MRD: - case IF_RWR_RRD_ARD: - case IF_RWR_RRD_SRD: - break; - default: - return false; + // Don't consider instructions which didn't write a register + return false; } - if (id->idReg1() != reg) + if (id->idHasMemWrite() || id->idIsReg2Write()) { + // Don't consider instructions which also wrote a mem location or second register return false; } + assert(!id->idIsReg3Write()); + assert(!id->idIsReg4Write()); + // Certain instruction like and, or and xor modifies exactly same flags // as "test" instruction. // They reset OF and CF to 0 and modifies SF, ZF and PF. @@ -1022,29 +965,15 @@ bool emitter::AreFlagsSetForSignJumpOpt(regNumber reg, emitAttr opSize, GenCondi instruction lastIns = id->idIns(); insFormat fmt = id->idInsFmt(); - // make sure op1 is a reg - switch (fmt) + if (!id->idIsReg1Write() || (id->idReg1() != reg)) { - case IF_RWR_CNS: - case IF_RRW_CNS: - case IF_RRW_SHF: - case IF_RWR_RRD: - case IF_RRW_RRD: - case IF_RWR_MRD: - case IF_RWR_SRD: - case IF_RRW_SRD: - case IF_RWR_ARD: - case IF_RRW_ARD: - case IF_RWR: - case IF_RRD: - case IF_RRW: - break; - default: - return false; + // Don't consider instructions which didn't write a register + return false; } - if (id->idReg1() != reg) + if (id->idHasMemWrite() || id->idIsReg2Write()) { + // Don't consider instructions which also wrote a mem location or second register return false; } @@ -1362,6 +1291,10 @@ bool emitter::TakesRexWPrefix(const instrDesc* id) const case INS_shlx: case INS_shrx: #endif // TARGET_AMD64 + case INS_vcvtsd2usi: + case INS_vcvtss2usi: + case INS_vcvttsd2usi: + case INS_vcvttss2usi: { if (attr == EA_8BYTE) { @@ -1953,7 +1886,7 @@ emitter::code_t emitter::emitExtractVexPrefix(instruction ins, code_t& code) con { // 3-byte opcode: with the bytes ordered as 0x2211RM33 or // 4-byte opcode: with the bytes ordered as 0x22114433 - + // // check for a prefix in the 11 position BYTE sizePrefix = (code >> 16) & 0xFF; @@ -2582,6 +2515,10 @@ bool emitter::emitInsCanOnlyWriteSSE2OrAVXReg(instrDesc* id) case INS_sarx: case INS_shrx: #endif + case INS_vcvtsd2usi: + case INS_vcvtss2usi: + case INS_vcvttsd2usi: + case INS_vcvttss2usi: { // These SSE instructions write to a general purpose integer register. return false; @@ -2847,105 +2784,63 @@ unsigned emitter::emitGetVexPrefixSize(instrDesc* id) const return 3; } - regNumber regFor012Bits = REG_NA; - regNumber regForSibBits = REG_NA; + regNumber regFor012Bits; - switch (id->idInsFmt()) + if (id->idHasMemAdr()) { - case IF_ARD: - case IF_AWR_RRD: - case IF_RRD_ARD: - case IF_RRW_ARD: - case IF_RRW_ARD_CNS: - case IF_RWR_ARD: - case IF_RWR_ARD_CNS: - case IF_RWR_RRD_ARD: - case IF_RWR_RRD_ARD_CNS: - { - regFor012Bits = id->idAddr()->iiaAddrMode.amBaseReg; - regForSibBits = id->idAddr()->iiaAddrMode.amIndxReg; - break; - } + regNumber regForSibBits = id->idAddr()->iiaAddrMode.amIndxReg; - case IF_MRD: - case IF_MWR_RRD: - case IF_RRD_MRD: - case IF_RRD_SRD: - case IF_RRW_MRD: - case IF_RRW_MRD_CNS: - case IF_RRW_SRD: - case IF_RRW_SRD_CNS: - case IF_RWR_MRD: - case IF_RWR_MRD_CNS: - case IF_RWR_RRD_MRD: - case IF_RWR_RRD_MRD_CNS: - case IF_RWR_RRD_SRD: - case IF_RWR_RRD_SRD_CNS: - case IF_RWR_SRD: - case IF_RWR_SRD_CNS: - case IF_SRD: - case IF_SWR_RRD: + if (IsExtendedReg(regForSibBits)) { - // Nothing is encoded in a way to prevent the 2-byte encoding - break; + // When the REX.X bit is present, we must use the 3-byte encoding + // - REX.X is used to encode the extended index field for SIB addressing + return 3; } - case IF_RRD_CNS: - case IF_RRW_CNS: - case IF_RWR_CNS: - { - regFor012Bits = id->idReg1(); - break; - } + regFor012Bits = id->idAddr()->iiaAddrMode.amBaseReg; + } + else if (id->idHasMemGen() || id->idHasMemStk()) + { + // Nothing is encoded in a way to prevent the 2-byte encoding + // - We don't encode an index or base field so can't use REX.X or REX.B + return 2; + } + else if (id->idHasReg3()) + { + // All instructions which have 3 registers encode reg3 in the r/m byte + regFor012Bits = id->idReg3(); + } + else if (id->idHasReg2()) + { + // Most instructions which have 2 registers encode reg2 in the r/m byte + regFor012Bits = id->idReg2(); - case IF_RRD_RRD: - case IF_RRW_RRD: - case IF_RWR_RRD: - { - regFor012Bits = id->idReg2(); + // However, there are a couple with MR variants (such as the extract instructions) + // and movd which uses both float and general registers which may use op1 + ID_OPS idOp = static_cast(emitFmtToOps[id->idInsFmt()]); - if ((ins == INS_movd) && isFloatReg(regFor012Bits)) + if (idOp == ID_OP_SCNS) + { + if (hasCodeMR(ins)) { regFor012Bits = id->idReg1(); } - break; } - - case IF_RRW_RRW_CNS: + else if (ins == INS_movd) { - if (hasCodeMR(ins)) + if (isFloatReg(regFor012Bits)) { regFor012Bits = id->idReg1(); } - else - { - regFor012Bits = id->idReg2(); - } - break; - } - - case IF_RWR_RRD_RRD: - case IF_RWR_RRD_RRD_CNS: - case IF_RWR_RRD_RRD_RRD: - { - regFor012Bits = id->idReg3(); - break; - } - - default: - { - assert(!"Unhandled insFmt for emitGetVexPrefixSize"); - return 3; } } - - if ((regForSibBits != REG_NA) && IsExtendedReg(regForSibBits)) + else { - // When the REX.X bit is present, we must use the 3-byte encoding - return 3; + assert(id->idHasReg1()); + regFor012Bits = id->idReg1(); } - if ((regFor012Bits != REG_NA) && IsExtendedReg(regFor012Bits)) + if (IsExtendedReg(regFor012Bits)) { // When the REX.B bit is present, we must use the 3-byte encoding return 3; @@ -3010,7 +2905,7 @@ inline bool hasTupleTypeInfo(instruction ins) // Return Value: // the tuple type info for a given CPU instruction. // -inline insTupleType insTupleTypeInfo(instruction ins) +insTupleType emitter::insTupleTypeInfo(instruction ins) const { assert((unsigned)ins < ArrLen(insTupleTypeInfos)); assert(insTupleTypeInfos[ins] != INS_TT_NONE); @@ -3020,9 +2915,9 @@ inline insTupleType insTupleTypeInfo(instruction ins) // Return true if the instruction uses the SSE38 or SSE3A macro in instrsXArch.h. bool emitter::EncodedBySSE38orSSE3A(instruction ins) const { - const size_t SSE38 = 0x0F660038; - const size_t SSE3A = 0x0F66003A; - const size_t MASK = 0xFFFF00FF; + const size_t SSE38 = 0x0F000038; + const size_t SSE3A = 0x0F00003A; + const size_t MASK = 0xFF0000FF; size_t insCode = 0; @@ -3044,8 +2939,19 @@ bool emitter::EncodedBySSE38orSSE3A(instruction ins) const insCode = insCodeMR(ins); } - insCode &= MASK; - return insCode == SSE38 || insCode == SSE3A; + size_t mskCode = insCode & MASK; + + if ((mskCode != SSE38) && (mskCode != SSE3A)) + { + return false; + } + +#if defined(DEBUG) + insCode = (insCode >> 16) & 0xFF; + assert((insCode == 0x66) || (insCode == 0xF2) || (insCode == 0xF3)); +#endif // DEBUG + + return true; } /***************************************************************************** @@ -3910,36 +3816,52 @@ UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, code_t code) regNumber rgx; // The idAddr field is a union and only some of the instruction formats use the iiaAddrMode variant - // these are IF_AWR_*, IF_ARD_*, IF_ARW_* and IF_*_ARD + // these are IF_ARD_*, IF_ARW_*, and IF_AWR_* // ideally these should really be the only idInsFmts that we see here // but we have some outliers to deal with: // emitIns_R_L adds IF_RWR_LABEL and calls emitInsSizeAM // emitInsRMW adds IF_MRW_CNS, IF_MRW_RRD, IF_MRW_SHF, and calls emitInsSizeAM - switch (id->idInsFmt()) - { - case IF_RWR_LABEL: - case IF_MRW_CNS: - case IF_MRW_RRD: - case IF_MRW_SHF: - reg = REG_NA; - rgx = REG_NA; - break; - - default: - reg = id->idAddr()->iiaAddrMode.amBaseReg; - rgx = id->idAddr()->iiaAddrMode.amIndxReg; - break; - } - - if (id->idIsDspReloc()) + if (id->idHasMemAdr()) { - dspInByte = false; // relocs can't be placed in a byte - dspIsZero = false; // relocs won't always be zero + reg = id->idAddr()->iiaAddrMode.amBaseReg; + rgx = id->idAddr()->iiaAddrMode.amIndxReg; } else { - if (TakesEvexPrefix(id)) + reg = REG_NA; + rgx = REG_NA; + +#if defined(DEBUG) + switch (id->idInsFmt()) + { + case IF_RWR_LABEL: + case IF_MRW_CNS: + case IF_MRW_RRD: + case IF_MRW_SHF: + { + break; + } + + default: + { + assert(!"Unexpected insFormat in emitInsSizeAMD"); + reg = id->idAddr()->iiaAddrMode.amBaseReg; + rgx = id->idAddr()->iiaAddrMode.amIndxReg; + break; + } + } +#endif // DEBUG + } + + if (id->idIsDspReloc()) + { + dspInByte = false; // relocs can't be placed in a byte + dspIsZero = false; // relocs won't always be zero + } + else + { + if (TakesEvexPrefix(id)) { dsp = TryEvexCompressDisp8Byte(id, dsp, &dspInByte); } @@ -4477,7 +4399,9 @@ emitter::insFormat emitter::emitMapFmtForIns(insFormat fmt, instruction ins) unreached(); } } + default: + { if (IsMovInstruction(ins)) { // A `mov` instruction is always "write" @@ -4488,6 +4412,7 @@ emitter::insFormat emitter::emitMapFmtForIns(insFormat fmt, instruction ins) } } return fmt; + } } } @@ -4502,55 +4427,28 @@ emitter::insFormat emitter::emitMapFmtForIns(insFormat fmt, instruction ins) // emitter::insFormat emitter::emitMapFmtAtoM(insFormat fmt) { - switch (fmt) - { - case IF_ARD: - return IF_MRD; - case IF_AWR: - return IF_MWR; - case IF_ARW: - return IF_MRW; - - case IF_RRD_ARD: - return IF_RRD_MRD; - case IF_RWR_ARD: - return IF_RWR_MRD; - case IF_RWR_ARD_CNS: - return IF_RWR_MRD_CNS; - case IF_RRW_ARD: - return IF_RRW_MRD; - case IF_RRW_ARD_CNS: - return IF_RRW_MRD_CNS; - case IF_RWR_RRD_ARD: - return IF_RWR_RRD_MRD; - case IF_RWR_RRD_ARD_CNS: - return IF_RWR_RRD_MRD_CNS; - case IF_RWR_RRD_ARD_RRD: - return IF_RWR_RRD_MRD_RRD; + // We should only get here for AM formats + assert((fmt >= IF_ARD) && (fmt <= IF_RWR_RRD_ARD_RRD)); - case IF_ARD_RRD: - return IF_MRD_RRD; - case IF_AWR_RRD: - return IF_MWR_RRD; - case IF_ARW_RRD: - return IF_MRW_RRD; + // We should have the same number of AM and GM formats + static_assert_no_msg((IF_RWR_RRD_ARD_RRD - IF_ARD) == (IF_RWR_RRD_MRD_RRD - IF_MRD)); - case IF_ARD_CNS: - return IF_MRD_CNS; - case IF_AWR_CNS: - return IF_MWR_CNS; - case IF_ARW_CNS: - return IF_MRW_CNS; + // GM should precede AM in the list + static_assert_no_msg(IF_MRD < IF_ARD); - case IF_AWR_RRD_CNS: - return IF_MWR_RRD_CNS; + const unsigned delta = IF_ARD - IF_MRD; - case IF_ARW_SHF: - return IF_MRW_SHF; + // Spot check a few entries + static_assert_no_msg((IF_ARD - delta) == IF_MRD); + static_assert_no_msg((IF_ARD_CNS - delta) == IF_MRD_CNS); + static_assert_no_msg((IF_ARD_RRD - delta) == IF_MRD_RRD); + static_assert_no_msg((IF_RRD_ARD - delta) == IF_RRD_MRD); + static_assert_no_msg((IF_RRD_ARD_CNS - delta) == IF_RRD_MRD_CNS); + static_assert_no_msg((IF_RRD_ARD_RRD - delta) == IF_RRD_MRD_RRD); + static_assert_no_msg((IF_RRD_RRD_ARD - delta) == IF_RRD_RRD_MRD); + static_assert_no_msg((IF_RWR_RRD_ARD_RRD - delta) == IF_RWR_RRD_MRD_RRD); - default: - unreached(); - } + return static_cast(fmt - delta); } //------------------------------------------------------------------------ @@ -4694,7 +4592,7 @@ void emitter::spillIntArgRegsToShadowSlots() id = emitNewInstrAmd(EA_PTRSIZE, offset); id->idIns(INS_mov); - id->idInsFmt(IF_AWR_RRD); + id->idInsFmt(emitInsModeFormat(INS_mov, IF_ARD_RRD)); id->idAddr()->iiaAddrMode.amBaseReg = REG_SPBASE; id->idAddr()->iiaAddrMode.amIndxReg = REG_NA; id->idAddr()->iiaAddrMode.amScale = emitEncodeScale(1); @@ -4753,7 +4651,7 @@ void emitter::emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, G instrDesc* id = emitNewInstrAmd(attr, offset); id->idIns(ins); id->idReg1(dstReg); - emitHandleMemOp(mem, id, IF_RWR_ARD, ins); + emitHandleMemOp(mem, id, emitInsModeFormat(ins, IF_RRD_ARD), ins); UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)); id->idCodeSize(sz); dispIns(id); @@ -4867,7 +4765,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m int icon = (int)data->AsIntConCommon()->IconValue(); id = emitNewInstrAmdCns(attr, offset, icon); id->idIns(ins); - emitHandleMemOp(mem, id, IF_AWR_CNS, ins); + emitHandleMemOp(mem, id, emitInsModeFormat(ins, IF_ARD_CNS), ins); sz = emitInsSizeAM(id, insCodeMI(ins), icon); id->idCodeSize(sz); } @@ -4883,7 +4781,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m { id = emitNewInstrAmd(attr, offset); id->idIns(ins); - emitHandleMemOp(mem, id, IF_AWR_RRD, ins); + emitHandleMemOp(mem, id, emitInsModeFormat(ins, IF_ARD_RRD), ins); id->idReg1(op1->GetRegNum()); sz = emitInsSizeAM(id, insCodeMR(ins)); id->idCodeSize(sz); @@ -4896,7 +4794,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m id = emitNewInstrAmdCns(attr, offset, icon); id->idIns(ins); id->idReg1(op1->GetRegNum()); - emitHandleMemOp(mem, id, IF_AWR_RRD_CNS, ins); + emitHandleMemOp(mem, id, emitInsModeFormat(ins, IF_ARD_RRD_CNS), ins); sz = emitInsSizeAM(id, insCodeMR(ins), icon); id->idCodeSize(sz); } @@ -4907,7 +4805,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m assert(!data->isContained()); id = emitNewInstrAmd(attr, offset); id->idIns(ins); - emitHandleMemOp(mem, id, IF_AWR_RRD, ins); + emitHandleMemOp(mem, id, emitInsModeFormat(ins, IF_ARD_RRD), ins); id->idReg1(data->GetRegNum()); sz = emitInsSizeAM(id, insCodeMR(ins)); id->idCodeSize(sz); @@ -5411,7 +5309,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI else { id = emitNewInstrAmdCns(attr, offset, iconVal); - emitHandleMemOp(storeInd, id, IF_ARW_CNS, ins); + emitHandleMemOp(storeInd, id, emitInsModeFormat(ins, IF_ARD_CNS), ins); id->idIns(ins); sz = emitInsSizeAM(id, insCodeMI(ins), iconVal); } @@ -5422,7 +5320,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI // ind, reg id = emitNewInstrAmd(attr, offset); - emitHandleMemOp(storeInd, id, IF_ARW_RRD, ins); + emitHandleMemOp(storeInd, id, emitInsModeFormat(ins, IF_ARD_RRD), ins); id->idReg1(src->GetRegNum()); id->idIns(ins); sz = emitInsSizeAM(id, insCodeMR(ins)); @@ -5476,7 +5374,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI } instrDesc* id = emitNewInstrAmd(attr, offset); - emitHandleMemOp(storeInd, id, IF_ARW, ins); + emitHandleMemOp(storeInd, id, emitInsModeFormat(ins, IF_ARD), ins); id->idIns(ins); UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeMR(ins)); id->idCodeSize(sz); @@ -5824,7 +5722,7 @@ void emitter::emitIns_IJ(emitAttr attr, regNumber reg, unsigned base) instrDesc* id = emitNewInstrAmd(attr, base); id->idIns(ins); - id->idInsFmt(IF_ARD); + id->idInsFmt(emitInsModeFormat(ins, IF_ARD)); id->idAddr()->iiaAddrMode.amBaseReg = REG_NA; id->idAddr()->iiaAddrMode.amIndxReg = reg; id->idAddr()->iiaAddrMode.amScale = emitter::OPSZP; @@ -6451,7 +6349,7 @@ void emitter::emitIns_R_R_I(instruction ins, emitAttr attr, regNumber reg1, regN instrDesc* id = emitNewInstrSC(attr, ival); id->idIns(ins); - id->idInsFmt(IF_RRW_RRW_CNS); + id->idInsFmt(emitInsModeFormat(ins, IF_RRD_RRD_CNS)); id->idReg1(reg1); id->idReg2(reg2); @@ -6466,10 +6364,12 @@ void emitter::emitIns_R_R_I(instruction ins, emitAttr attr, regNumber reg1, regN case INS_extractps: case INS_vextractf128: case INS_vextractf32x8: + case INS_vextractf64x2: case INS_vextractf64x4: case INS_vextracti128: - case INS_vextracti64x4: case INS_vextracti32x8: + case INS_vextracti64x2: + case INS_vextracti64x4: case INS_shld: case INS_shrd: { @@ -6506,7 +6406,7 @@ void emitter::emitIns_AR(instruction ins, emitAttr attr, regNumber base, int off id->idIns(ins); - id->idInsFmt(IF_ARD); + id->idInsFmt(emitInsModeFormat(ins, IF_ARD)); id->idAddr()->iiaAddrMode.amBaseReg = base; id->idAddr()->iiaAddrMode.amIndxReg = REG_NA; @@ -6561,7 +6461,7 @@ void emitter::emitIns_R_A(instruction ins, emitAttr attr, regNumber reg1, GenTre id->idIns(ins); id->idReg1(reg1); - emitHandleMemOp(indir, id, IF_RRW_ARD, ins); + emitHandleMemOp(indir, id, emitInsModeFormat(ins, IF_RRD_ARD), ins); UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)); id->idCodeSize(sz); @@ -6581,7 +6481,7 @@ void emitter::emitIns_R_A_I(instruction ins, emitAttr attr, regNumber reg1, GenT id->idIns(ins); id->idReg1(reg1); - emitHandleMemOp(indir, id, IF_RRW_ARD_CNS, ins); + emitHandleMemOp(indir, id, emitInsModeFormat(ins, IF_RRD_ARD_CNS), ins); UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival); id->idCodeSize(sz); @@ -6600,7 +6500,7 @@ void emitter::emitIns_R_AR_I(instruction ins, emitAttr attr, regNumber reg1, reg id->idIns(ins); id->idReg1(reg1); - id->idInsFmt(IF_RRW_ARD_CNS); + id->idInsFmt(emitInsModeFormat(ins, IF_RRD_ARD_CNS)); id->idAddr()->iiaAddrMode.amBaseReg = base; id->idAddr()->iiaAddrMode.amIndxReg = REG_NA; @@ -6626,7 +6526,7 @@ void emitter::emitIns_R_C_I( instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs); id->idIns(ins); - id->idInsFmt(IF_RRW_MRD_CNS); + id->idInsFmt(emitInsModeFormat(ins, IF_RRD_MRD_CNS)); id->idReg1(reg1); id->idAddr()->iiaFieldHnd = fldHnd; @@ -6645,7 +6545,7 @@ void emitter::emitIns_R_S_I(instruction ins, emitAttr attr, regNumber reg1, int instrDesc* id = emitNewInstrCns(attr, ival); id->idIns(ins); - id->idInsFmt(IF_RRW_SRD_CNS); + id->idInsFmt(emitInsModeFormat(ins, IF_RRD_SRD_CNS)); id->idReg1(reg1); id->idAddr()->iiaLclVar.initLclVarAddr(varx, offs); @@ -6672,7 +6572,7 @@ void emitter::emitIns_R_R_A(instruction ins, emitAttr attr, regNumber reg1, regN id->idReg1(reg1); id->idReg2(reg2); - emitHandleMemOp(indir, id, IF_RWR_RRD_ARD, ins); + emitHandleMemOp(indir, id, (ins == INS_mulx) ? IF_RWR_RWR_ARD : emitInsModeFormat(ins, IF_RRD_RRD_ARD), ins); UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)); id->idCodeSize(sz); @@ -6692,7 +6592,7 @@ void emitter::emitIns_R_R_AR(instruction ins, emitAttr attr, regNumber reg1, reg id->idReg1(reg1); id->idReg2(reg2); - id->idInsFmt(IF_RWR_RRD_ARD); + id->idInsFmt(emitInsModeFormat(ins, IF_RRD_RRD_ARD)); id->idAddr()->iiaAddrMode.amBaseReg = base; id->idAddr()->iiaAddrMode.amIndxReg = REG_NA; @@ -6759,7 +6659,7 @@ void emitter::emitIns_R_AR_R(instruction ins, id->idReg1(reg1); id->idReg2(reg2); - id->idInsFmt(IF_RWR_ARD_RRD); + id->idInsFmt(emitInsModeFormat(ins, IF_RRD_ARD_RRD)); id->idAddr()->iiaAddrMode.amBaseReg = base; id->idAddr()->iiaAddrMode.amIndxReg = index; id->idAddr()->iiaAddrMode.amScale = emitEncodeSize((emitAttr)scale); @@ -6786,7 +6686,7 @@ void emitter::emitIns_R_R_C( instrDesc* id = emitNewInstrDsp(attr, offs); id->idIns(ins); - id->idInsFmt(IF_RWR_RRD_MRD); + id->idInsFmt((ins == INS_mulx) ? IF_RWR_RWR_MRD : emitInsModeFormat(ins, IF_RRD_RRD_MRD)); id->idReg1(reg1); id->idReg2(reg2); id->idAddr()->iiaFieldHnd = fldHnd; @@ -6810,7 +6710,7 @@ void emitter::emitIns_R_R_R(instruction ins, emitAttr attr, regNumber targetReg, instrDesc* id = emitNewInstr(attr); id->idIns(ins); - id->idInsFmt(IF_RWR_RRD_RRD); + id->idInsFmt((ins == INS_mulx) ? IF_RWR_RWR_RRD : emitInsModeFormat(ins, IF_RRD_RRD_RRD)); id->idReg1(targetReg); id->idReg2(reg1); id->idReg3(reg2); @@ -6830,7 +6730,7 @@ void emitter::emitIns_R_R_S(instruction ins, emitAttr attr, regNumber reg1, regN instrDesc* id = emitNewInstr(attr); id->idIns(ins); - id->idInsFmt(IF_RWR_RRD_SRD); + id->idInsFmt((ins == INS_mulx) ? IF_RWR_RWR_SRD : emitInsModeFormat(ins, IF_RRD_RRD_SRD)); id->idReg1(reg1); id->idReg2(reg2); id->idAddr()->iiaLclVar.initLclVarAddr(varx, offs); @@ -6954,10 +6854,12 @@ void emitter::emitIns_R_R_R_I( case INS_extractps: case INS_vextractf128: case INS_vextractf32x8: + case INS_vextractf64x2: case INS_vextractf64x4: case INS_vextracti128: - case INS_vextracti64x4: case INS_vextracti32x8: + case INS_vextracti64x2: + case INS_vextracti64x4: { code = insCodeMR(ins); break; @@ -7706,7 +7608,7 @@ void emitter::emitIns_C_R_I( instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs); id->idIns(ins); - id->idInsFmt(IF_MWR_RRD_CNS); + id->idInsFmt(emitInsModeFormat(ins, IF_MRD_RRD_CNS)); id->idReg1(reg); id->idAddr()->iiaFieldHnd = fldHnd; @@ -7737,7 +7639,7 @@ void emitter::emitIns_S_R_I(instruction ins, emitAttr attr, int varNum, int offs instrDesc* id = emitNewInstrAmdCns(attr, 0, ival); id->idIns(ins); - id->idInsFmt(IF_SWR_RRD_CNS); + id->idInsFmt(emitInsModeFormat(ins, IF_SRD_RRD_CNS)); id->idReg1(reg); id->idAddr()->iiaLclVar.initLclVarAddr(varNum, offs); #ifdef DEBUG @@ -7770,7 +7672,7 @@ void emitter::emitIns_A_R_I(instruction ins, emitAttr attr, GenTreeIndir* indir, instrDesc* id = emitNewInstrAmdCns(attr, indir->Offset(), imm); id->idIns(ins); id->idReg1(reg); - emitHandleMemOp(indir, id, IF_AWR_RRD_CNS, ins); + emitHandleMemOp(indir, id, emitInsModeFormat(ins, IF_ARD_RRD_CNS), ins); UNATIVE_OFFSET size = emitInsSizeAM(id, insCodeMR(ins), imm); id->idCodeSize(size); dispIns(id); @@ -8166,32 +8068,6 @@ void emitter::emitIns_SIMD_R_R_A( } } -//------------------------------------------------------------------------ -// emitIns_SIMD_R_R_AR: emits the code for a SIMD instruction that takes a register operand, a base memory register, -// and that returns a value in register -// -// Arguments: -// ins -- The instruction being emitted -// attr -- The emit attribute -// targetReg -- The target register -// op1Reg -- The register of the first operand -// base -- The base register used for the memory address -// offset -- The memory offset -// -void emitter::emitIns_SIMD_R_R_AR( - instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber base, int offset) -{ - if (UseSimdEncoding()) - { - emitIns_R_R_AR(ins, attr, targetReg, op1Reg, base, offset); - } - else - { - emitIns_Mov(INS_movaps, attr, targetReg, op1Reg, /* canSkip */ true); - emitIns_R_AR(ins, attr, targetReg, base, offset); - } -} - //------------------------------------------------------------------------ // emitIns_SIMD_R_R_C: emits the code for a SIMD instruction that takes a register operand, a field handle + offset, // and that returns a value in register @@ -8280,7 +8156,6 @@ void emitter::emitIns_SIMD_R_R_S( } } -#ifdef FEATURE_HW_INTRINSICS //------------------------------------------------------------------------ // emitIns_SIMD_R_R_A_I: emits the code for a SIMD instruction that takes a register operand, a GenTreeIndir address, // an immediate operand, and that returns a value in register @@ -8307,32 +8182,6 @@ void emitter::emitIns_SIMD_R_R_A_I( } } -//------------------------------------------------------------------------ -// emitIns_SIMD_R_R_AR_I: emits the code for a SIMD instruction that takes a register operand, a base memory register, -// an immediate operand, and that returns a value in register -// -// Arguments: -// ins -- The instruction being emitted -// attr -- The emit attribute -// targetReg -- The target register -// op1Reg -- The register of the first operand -// base -- The base register used for the memory address -// ival -- The immediate value -// -void emitter::emitIns_SIMD_R_R_AR_I( - instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber base, int ival) -{ - if (UseSimdEncoding()) - { - emitIns_R_R_AR_I(ins, attr, targetReg, op1Reg, base, 0, ival); - } - else - { - emitIns_Mov(INS_movaps, attr, targetReg, op1Reg, /* canSkip */ true); - emitIns_R_AR_I(ins, attr, targetReg, base, 0, ival); - } -} - //------------------------------------------------------------------------ // emitIns_SIMD_R_R_C_I: emits the code for a SIMD instruction that takes a register operand, a field handle + offset, // an immediate operand, and that returns a value in register @@ -8421,6 +8270,7 @@ void emitter::emitIns_SIMD_R_R_S_I( } } +#ifdef FEATURE_HW_INTRINSICS //------------------------------------------------------------------------ // emitIns_SIMD_R_R_R_A: emits the code for a SIMD instruction that takes two register operands, a GenTreeIndir address, // and that returns a value in register @@ -8865,6 +8715,109 @@ void emitter::emitIns_SIMD_R_R_S_R( emitIns_R_S(ins, attr, targetReg, varx, offs); } } + +//------------------------------------------------------------------------ +// emitIns_SIMD_R_R_R_A_I: emits the code for a SIMD instruction that takes two register operands, a GenTreeIndir +// address, an immediate operand, and that returns a value in register +// +// Arguments: +// ins -- The instruction being emitted +// attr -- The emit attribute +// targetReg -- The target register +// op1Reg -- The register of the first operand +// op2Reg -- The register of the second operand +// indir -- The GenTreeIndir used for the memory address +// ival -- The immediate value +// +void emitter::emitIns_SIMD_R_R_R_A_I(instruction ins, + emitAttr attr, + regNumber targetReg, + regNumber op1Reg, + regNumber op2Reg, + GenTreeIndir* indir, + int ival) +{ + assert(UseSimdEncoding()); + emitIns_Mov(INS_movaps, attr, targetReg, op1Reg, /* canSkip */ true); + emitIns_R_R_A_I(ins, attr, targetReg, op2Reg, indir, ival, IF_RWR_RRD_ARD_CNS); +} + +//------------------------------------------------------------------------ +// emitIns_SIMD_R_R_R_C_I: emits the code for a SIMD instruction that takes two register operands, a field handle + +// offset, an immediate operand, and that returns a value in register +// +// Arguments: +// ins -- The instruction being emitted +// attr -- The emit attribute +// targetReg -- The target register +// op1Reg -- The register of the first operand +// op2Reg -- The register of the second operand +// fldHnd -- The CORINFO_FIELD_HANDLE used for the memory address +// offs -- The offset added to the memory address from fldHnd +// ival -- The immediate value +// +void emitter::emitIns_SIMD_R_R_R_C_I(instruction ins, + emitAttr attr, + regNumber targetReg, + regNumber op1Reg, + regNumber op2Reg, + CORINFO_FIELD_HANDLE fldHnd, + int offs, + int ival) +{ + assert(UseSimdEncoding()); + emitIns_Mov(INS_movaps, attr, targetReg, op1Reg, /* canSkip */ true); + emitIns_R_R_C_I(ins, attr, targetReg, op2Reg, fldHnd, offs, ival); +} + +//------------------------------------------------------------------------ +// emitIns_SIMD_R_R_R_R_I: emits the code for a SIMD instruction that takes three register operands, an immediate +// operand, and that returns a value in register +// +// Arguments: +// ins -- The instruction being emitted +// attr -- The emit attribute +// targetReg -- The target register +// op1Reg -- The register of the first operand +// op2Reg -- The register of the second operand +// op3Reg -- The register of the third operand +// ival -- The immediate value +// +void emitter::emitIns_SIMD_R_R_R_R_I( + instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, regNumber op3Reg, int ival) +{ + assert(UseSimdEncoding()); + emitIns_Mov(INS_movaps, attr, targetReg, op1Reg, /* canSkip */ true); + emitIns_R_R_R_I(ins, attr, targetReg, op2Reg, op3Reg, ival); +} + +//------------------------------------------------------------------------ +// emitIns_SIMD_R_R_R_S_I: emits the code for a SIMD instruction that takes two register operands, a variable index + +// offset, an immediate operand, and that returns a value in register +// +// Arguments: +// ins -- The instruction being emitted +// attr -- The emit attribute +// targetReg -- The target register +// op1Reg -- The register of the first operand +// op2Reg -- The register of the second operand +// varx -- The variable index used for the memory address +// offs -- The offset added to the memory address from varx +// ival -- The immediate value +// +void emitter::emitIns_SIMD_R_R_R_S_I(instruction ins, + emitAttr attr, + regNumber targetReg, + regNumber op1Reg, + regNumber op2Reg, + int varx, + int offs, + int ival) +{ + assert(UseSimdEncoding()); + emitIns_Mov(INS_movaps, attr, targetReg, op1Reg, /* canSkip */ true); + emitIns_R_R_S_I(ins, attr, targetReg, op2Reg, varx, offs, ival); +} #endif // FEATURE_HW_INTRINSICS /***************************************************************************** @@ -9500,7 +9453,7 @@ void emitter::emitIns_Call(EmitCallType callType, // The function is "ireg" if id->idIsCallRegPtr(), // else [ireg+xmul*xreg+disp] - id->idInsFmt(IF_ARD); + id->idInsFmt(emitInsModeFormat(ins, IF_ARD)); id->idAddr()->iiaAddrMode.amBaseReg = ireg; id->idAddr()->iiaAddrMode.amIndxReg = xreg; @@ -9643,118 +9596,263 @@ void emitter::emitInsSanityCheck(instrDesc* id) } #endif -/***************************************************************************** - * - * Return the allocated size (in bytes) of the given instruction descriptor. - */ - -size_t emitter::emitSizeOfInsDsc(instrDesc* id) +//------------------------------------------------------------------------ +// emitSizeOfInsDsc_AMD: The allocated size, in bytes, of the AMD or AMD_CNS instrDesc +// +// Arguments: +// id - The instrDesc for which to get the size +// +// Returns: +// The allocated size, in bytes, of id +// +size_t emitter::emitSizeOfInsDsc_AMD(instrDesc* id) const { - if (emitIsScnsInsDsc(id)) + assert(!emitIsSmallInsDsc(id)); + +#if defined(DEBUG) + assert((unsigned)id->idInsFmt() < emitFmtCount); + ID_OPS idOp = (ID_OPS)emitFmtToOps[id->idInsFmt()]; + assert((idOp == ID_OP_AMD) || (idOp == ID_OP_AMD_CNS)); +#endif // DEBUG + + if (id->idIsLargeCns()) { - return SMALL_IDSC_SIZE; + if (id->idIsLargeDsp()) + { + return sizeof(instrDescCnsAmd); + } + else + { + return sizeof(instrDescCns); + } + } + else if (id->idIsLargeDsp()) + { + return sizeof(instrDescAmd); + } + else + { + return sizeof(instrDesc); } +} +//------------------------------------------------------------------------ +// emitSizeOfInsDsc_CNS: The allocated size, in bytes, of the CNS or SCNS instrDesc +// +// Arguments: +// id - The instrDesc for which to get the size +// +// Returns: +// The allocated size, in bytes, of id +// +size_t emitter::emitSizeOfInsDsc_CNS(instrDesc* id) const +{ +#if defined(DEBUG) assert((unsigned)id->idInsFmt() < emitFmtCount); - ID_OPS idOp = (ID_OPS)emitFmtToOps[id->idInsFmt()]; + assert((idOp == ID_OP_CNS) || (idOp == ID_OP_SCNS)); +#endif // DEBUG - // An INS_call instruction may use a "fat" direct/indirect call descriptor - // except for a local call to a label (i.e. call to a finally) - // Only ID_OP_CALL and ID_OP_SPEC check for this, so we enforce that the - // INS_call instruction always uses one of these idOps - - if (id->idIns() == INS_call) + if (emitIsSmallInsDsc(id)) + { + return SMALL_IDSC_SIZE; + } + else if (id->idIsLargeCns()) + { + return sizeof(instrDescCns); + } + else { - assert(idOp == ID_OP_CALL || // is a direct call - idOp == ID_OP_SPEC || // is a indirect call - idOp == ID_OP_JMP); // is a local call to finally clause + return sizeof(instrDesc); } +} - switch (idOp) +//------------------------------------------------------------------------ +// emitSizeOfInsDsc_NONE: The allocated size, in bytes, of the NONE instrDesc +// +// Arguments: +// id - The instrDesc for which to get the size +// +// Returns: +// The allocated size, in bytes, of id +// +size_t emitter::emitSizeOfInsDsc_NONE(instrDesc* id) const +{ +#if defined(DEBUG) + assert((unsigned)id->idInsFmt() < emitFmtCount); + ID_OPS idOp = (ID_OPS)emitFmtToOps[id->idInsFmt()]; + assert(idOp == ID_OP_NONE); +#endif // DEBUG + + if (emitIsSmallInsDsc(id)) { - case ID_OP_NONE: + return SMALL_IDSC_SIZE; + } #if FEATURE_LOOP_ALIGN - if (id->idIns() == INS_align) - { - return sizeof(instrDescAlign); - } + else if (id->idIns() == INS_align) + { + return sizeof(instrDescAlign); + } #endif - break; - - case ID_OP_LBL: - return sizeof(instrDescLbl); + else + { + return sizeof(instrDesc); + } +} - case ID_OP_JMP: - return sizeof(instrDescJmp); +//------------------------------------------------------------------------ +// emitSizeOfInsDsc_SPEC: The allocated size, in bytes, of the CALL or SPEC instrDesc +// +// Arguments: +// id - The instrDesc for which to get the size +// +// Returns: +// The allocated size, in bytes, of id +// +size_t emitter::emitSizeOfInsDsc_SPEC(instrDesc* id) const +{ + assert(!emitIsSmallInsDsc(id)); - case ID_OP_CALL: - case ID_OP_SPEC: - if (id->idIsLargeCall()) - { - /* Must be a "fat" indirect call descriptor */ - return sizeof(instrDescCGCA); - } +#if defined(DEBUG) + assert((unsigned)id->idInsFmt() < emitFmtCount); + ID_OPS idOp = (ID_OPS)emitFmtToOps[id->idInsFmt()]; + assert((idOp == ID_OP_CALL) || (idOp == ID_OP_SPEC)); +#endif // DEBUG - FALLTHROUGH; + if (id->idIsLargeCall()) + { + /* Must be a "fat" indirect call descriptor */ + return sizeof(instrDescCGCA); + } + else if (id->idIsLargeCns()) + { + if (id->idIsLargeDsp()) + { + return sizeof(instrDescCnsDsp); + } + else + { + return sizeof(instrDescCns); + } + } + else if (id->idIsLargeDsp()) + { + return sizeof(instrDescDsp); + } + else + { + return sizeof(instrDesc); + } +} + +//------------------------------------------------------------------------ +// emitSizeOfInsDsc_DSP: The allocated size, in bytes, of the DSP or DSP_CNS instrDesc +// +// Arguments: +// id - The instrDesc for which to get the size +// +// Returns: +// The allocated size, in bytes, of id +// +size_t emitter::emitSizeOfInsDsc_DSP(instrDesc* id) const +{ + assert(!emitIsSmallInsDsc(id)); + +#if defined(DEBUG) + assert((unsigned)id->idInsFmt() < emitFmtCount); + ID_OPS idOp = (ID_OPS)emitFmtToOps[id->idInsFmt()]; + assert((idOp == ID_OP_DSP) || (idOp == ID_OP_DSP_CNS)); +#endif // DEBUG + + if (id->idIsLargeCns()) + { + if (id->idIsLargeDsp()) + { + return sizeof(instrDescCnsDsp); + } + else + { + return sizeof(instrDescCns); + } + } + else if (id->idIsLargeDsp()) + { + return sizeof(instrDescDsp); + } + else + { + return sizeof(instrDesc); + } +} + +/***************************************************************************** + * + * Return the allocated size (in bytes) of the given instruction descriptor. + */ +size_t emitter::emitSizeOfInsDsc(instrDesc* id) const +{ + assert((unsigned)id->idInsFmt() < emitFmtCount); + ID_OPS idOp = (ID_OPS)emitFmtToOps[id->idInsFmt()]; + + // An INS_call instruction may use a "fat" direct/indirect call descriptor + // except for a local call to a label (i.e. call to a finally) + // Only ID_OP_CALL and ID_OP_SPEC check for this, so we enforce that the + // INS_call instruction always uses one of these idOps + + if (id->idIns() == INS_call) + { + assert((idOp == ID_OP_CALL) || // is a direct call + (idOp == ID_OP_SPEC) || // is a indirect call + (idOp == ID_OP_JMP)); // is a local call to finally clause + } + + switch (idOp) + { + case ID_OP_NONE: + { + return emitSizeOfInsDsc_NONE(id); + } + + case ID_OP_LBL: + { + return sizeof(instrDescLbl); + } + + case ID_OP_JMP: + { + return sizeof(instrDescJmp); + } + + case ID_OP_CALL: + case ID_OP_SPEC: + { + return emitSizeOfInsDsc_SPEC(id); + } case ID_OP_SCNS: case ID_OP_CNS: + { + return emitSizeOfInsDsc_CNS(id); + } + case ID_OP_DSP: case ID_OP_DSP_CNS: - if (id->idIsLargeCns()) - { - if (id->idIsLargeDsp()) - { - return sizeof(instrDescCnsDsp); - } - else - { - return sizeof(instrDescCns); - } - } - else - { - if (id->idIsLargeDsp()) - { - return sizeof(instrDescDsp); - } - else - { - return sizeof(instrDesc); - } - } + { + return emitSizeOfInsDsc_DSP(id); + } + case ID_OP_AMD: case ID_OP_AMD_CNS: - if (id->idIsLargeCns()) - { - if (id->idIsLargeDsp()) - { - return sizeof(instrDescCnsAmd); - } - else - { - return sizeof(instrDescCns); - } - } - else - { - if (id->idIsLargeDsp()) - { - return sizeof(instrDescAmd); - } - else - { - return sizeof(instrDesc); - } - } + { + return emitSizeOfInsDsc_AMD(id); + } default: + { NO_WAY("unexpected instruction descriptor format"); - break; + return sizeof(instrDesc); + } } - - return sizeof(instrDesc); } /***************************************************************************** @@ -9769,7 +9867,6 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) const char* rn = emitComp->compRegVarName(reg, varName); -#ifdef TARGET_AMD64 char suffix = '\0'; if (isMaskReg(reg)) @@ -9777,30 +9874,56 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) return rn; } +#ifdef TARGET_X86 + assert(strlen(rn) >= 3); +#endif // TARGET_X86 + switch (EA_SIZE(attr)) { case EA_64BYTE: - return emitZMMregName(reg); + { + if (IsXMMReg(reg)) + { + return emitZMMregName(reg); + } + break; + } case EA_32BYTE: - return emitYMMregName(reg); + { + if (IsXMMReg(reg)) + { + return emitYMMregName(reg); + } + break; + } case EA_16BYTE: - return emitXMMregName(reg); + { + if (IsXMMReg(reg)) + { + return emitXMMregName(reg); + } + break; + } case EA_8BYTE: + { if (IsXMMReg(reg)) { return emitXMMregName(reg); } break; + } case EA_4BYTE: + { if (IsXMMReg(reg)) { return emitXMMregName(reg); } +#if defined(TARGET_AMD64) if (reg > REG_R15) { break; @@ -9817,18 +9940,27 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) rb[rbc][2] = rn[2]; rb[rbc][3] = 0; rn = rb[rbc]; +#endif // TARGET_AMD64 break; + } case EA_2BYTE: + { +#if defined(TARGET_AMD64) if (reg > REG_RDI) { suffix = 'w'; goto APPEND_SUFFIX; } +#endif // TARGET_AMD64 + rn++; break; + } case EA_1BYTE: + { +#if defined(TARGET_AMD64) if (reg > REG_RDI) { suffix = 'b'; @@ -9865,64 +9997,24 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) rb[rbc][3] = 0; } } - - rn = rb[rbc]; - break; - - default: - break; - } #endif // TARGET_AMD64 -#ifdef TARGET_X86 - if (isMaskReg(reg)) - { - return rn; - } - assert(strlen(rn) >= 3); - - switch (EA_SIZE(attr)) - { - case EA_64BYTE: - return emitZMMregName(reg); - - case EA_32BYTE: - return emitYMMregName(reg); - - case EA_16BYTE: - return emitXMMregName(reg); - - case EA_8BYTE: - if (IsXMMReg(reg)) - { - return emitXMMregName(reg); - } - break; - - case EA_4BYTE: - if (IsXMMReg(reg)) - { - return emitXMMregName(reg); - } - break; - - case EA_2BYTE: - rn++; - break; - - case EA_1BYTE: +#if defined(TARGET_X86) rbc = (rbc + 1) % 2; rb[rbc][0] = rn[1]; rb[rbc][1] = 'l'; strcpy_s(&rb[rbc][2], sizeof(rb[0]) - 2, rn + 3); +#endif // TARGET_X86 rn = rb[rbc]; break; + } default: + { break; + } } -#endif // TARGET_X86 #if 0 // The following is useful if you want register names to be tagged with * or ^ representing gcref or byref, respectively, @@ -10175,7 +10267,7 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) printf("]"); #ifdef DEBUG - if (varx >= 0 && emitComp->opts.varNames) + if ((varx >= 0) && emitComp->opts.varNames && (((IL_OFFSET)offs) != BAD_IL_OFFSET)) { const char* varName = emitComp->compLocalVarName(varx, offs); @@ -10533,102 +10625,73 @@ void emitter::emitDispIns( /* Display a constant value if the instruction references one */ - if (!isNew) + if (!isNew && id->idHasMemGen()) { - switch (id->idInsFmt()) - { - int offs; + /* Is this actually a reference to a data section? */ + int offs = Compiler::eeGetJitDataOffs(id->idAddr()->iiaFieldHnd); - case IF_MRD_RRD: - case IF_MWR_RRD: - case IF_MRW_RRD: - - case IF_RRD_MRD: - case IF_RWR_MRD: - case IF_RRW_MRD: - - case IF_MRD_CNS: - case IF_MWR_CNS: - case IF_MRW_CNS: - case IF_MRW_SHF: + if (offs >= 0) + { + void* addr; - case IF_MRD: - case IF_MWR: - case IF_MRW: + /* Display a data section reference */ - case IF_MRD_OFF: + assert((unsigned)offs < emitConsDsc.dsdOffs); + addr = emitConsBlock ? emitConsBlock + offs : nullptr; - /* Is this actually a reference to a data section? */ +#if 0 + // TODO-XArch-Cleanup: Fix or remove this code. + /* Is the operand an integer or floating-point value? */ - offs = Compiler::eeGetJitDataOffs(id->idAddr()->iiaFieldHnd); + bool isFP = false; - if (offs >= 0) + if (CodeGen::instIsFP(id->idIns())) + { + switch (id->idIns()) { - void* addr; + case INS_fild: + case INS_fildl: + break; - /* Display a data section reference */ + default: + isFP = true; + break; + } + } - assert((unsigned)offs < emitConsDsc.dsdOffs); - addr = emitConsBlock ? emitConsBlock + offs : nullptr; + if (offs & 1) + printf("@CNS%02u", offs); + else + printf("@RWD%02u", offs); -#if 0 - // TODO-XArch-Cleanup: Fix or remove this code. - /* Is the operand an integer or floating-point value? */ + printf(" "); - bool isFP = false; + if (addr) + { + addr = 0; + // TODO-XArch-Bug?: + // This was busted by switching the order + // in which we output the code block vs. + // the data blocks -- when we get here, + // the data block has not been filled in + // yet, so we'll display garbage. - if (CodeGen::instIsFP(id->idIns())) + if (isFP) { - switch (id->idIns()) - { - case INS_fild: - case INS_fildl: - break; - - default: - isFP = true; - break; - } + if (id->idOpSize() == EA_4BYTE) + printf("DF %f \n", addr ? *(float *)addr : 0); + else + printf("DQ %lf\n", addr ? *(double *)addr : 0); } - - if (offs & 1) - printf("@CNS%02u", offs); else - printf("@RWD%02u", offs); - - printf(" "); - - if (addr) { - addr = 0; - // TODO-XArch-Bug?: - // This was busted by switching the order - // in which we output the code block vs. - // the data blocks -- when we get here, - // the data block has not been filled in - // yet, so we'll display garbage. - - if (isFP) - { - if (id->idOpSize() == EA_4BYTE) - printf("DF %f \n", addr ? *(float *)addr : 0); - else - printf("DQ %lf\n", addr ? *(double *)addr : 0); - } + if (id->idOpSize() <= EA_4BYTE) + printf("DD %d \n", addr ? *(int *)addr : 0); else - { - if (id->idOpSize() <= EA_4BYTE) - printf("DD %d \n", addr ? *(int *)addr : 0); - else - printf("DQ %D \n", addr ? *(__int64 *)addr : 0); - } + printf("DQ %D \n", addr ? *(__int64 *)addr : 0); } + } #endif - } - break; - - default: - break; } } @@ -10730,6 +10793,7 @@ void emitter::emitDispIns( const char* methodName; case IF_CNS: + { val = emitGetInsSC(id); #ifdef TARGET_AMD64 // no 8-byte immediates allowed here! @@ -10767,11 +10831,12 @@ void emitter::emitDispIns( emitDispCommentForHandle(srcVal, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); } break; + } case IF_ARD: case IF_AWR: case IF_ARW: - + { if (id->idIsCallRegPtr()) { printf("%s", emitRegName(id->idAddr()->iiaAddrMode.amBaseReg)); @@ -10812,10 +10877,12 @@ void emitter::emitDispIns( printf("%s", methodName); } break; + } case IF_RRD_ARD: case IF_RWR_ARD: case IF_RRW_ARD: + { #ifdef TARGET_AMD64 if (ins == INS_movsxd) { @@ -10838,7 +10905,9 @@ void emitter::emitDispIns( emitDispCommentForHandle(id->idDebugOnlyInfo()->idMemCookie, 0, id->idDebugOnlyInfo()->idFlags); break; + } + case IF_RRD_ARD_CNS: case IF_RRW_ARD_CNS: case IF_RWR_ARD_CNS: { @@ -10861,12 +10930,16 @@ void emitter::emitDispIns( break; } + case IF_ARD_RRD_CNS: case IF_AWR_RRD_CNS: + case IF_ARW_RRD_CNS: { switch (ins) { case INS_vextractf128: + case INS_vextractf64x2: case INS_vextracti128: + case INS_vextracti64x2: { // vextracti/f128 extracts 128-bit data, so we fix sstr as "xmm ptr" sstr = codeGen->genSizeStr(EA_ATTR(16)); @@ -10875,8 +10948,8 @@ void emitter::emitDispIns( case INS_vextractf32x8: case INS_vextractf64x4: - case INS_vextracti64x4: case INS_vextracti32x8: + case INS_vextracti64x4: { // vextracti/f*x* extracts 256-bit data, so we fix sstr as "ymm ptr" sstr = codeGen->genSizeStr(EA_ATTR(32)); @@ -10910,12 +10983,20 @@ void emitter::emitDispIns( break; } + case IF_RRD_RRD_ARD: case IF_RWR_RRD_ARD: + case IF_RRW_RRD_ARD: + case IF_RWR_RWR_ARD: + { printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); emitDispAddrMode(id); break; + } + case IF_RRD_ARD_RRD: case IF_RWR_ARD_RRD: + case IF_RRW_ARD_RRD: + { if (ins == INS_vpgatherqd || ins == INS_vgatherqps) { attr = EA_16BYTE; @@ -10925,6 +11006,7 @@ void emitter::emitDispIns( emitDispAddrMode(id); printf(", %s", emitRegName(id->idReg2(), attr)); break; + } case IF_RWR_RRD_ARD_CNS: { @@ -10962,11 +11044,12 @@ void emitter::emitDispIns( case IF_ARD_RRD: case IF_AWR_RRD: case IF_ARW_RRD: - + { printf("%s", sstr); emitDispAddrMode(id); printf(", %s", emitRegName(id->idReg1(), attr)); break; + } case IF_AWR_RRD_RRD: { @@ -10981,7 +11064,7 @@ void emitter::emitDispIns( case IF_AWR_CNS: case IF_ARW_CNS: case IF_ARW_SHF: - + { printf("%s", sstr); emitDispAddrMode(id); emitGetInsAmdCns(id, &cnsVal); @@ -11007,11 +11090,12 @@ void emitter::emitDispIns( } } break; + } case IF_SRD: case IF_SWR: case IF_SRW: - + { printf("%s", sstr); #if !FEATURE_FIXED_OUT_ARGS @@ -11029,11 +11113,12 @@ void emitter::emitDispIns( emitDispShift(ins); break; + } case IF_SRD_RRD: case IF_SWR_RRD: case IF_SRW_RRD: - + { printf("%s", sstr); emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), @@ -11041,12 +11126,13 @@ void emitter::emitDispIns( printf(", %s", emitRegName(id->idReg1(), attr)); break; + } case IF_SRD_CNS: case IF_SWR_CNS: case IF_SRW_CNS: case IF_SRW_SHF: - + { printf("%s", sstr); emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), @@ -11075,8 +11161,12 @@ void emitter::emitDispIns( } } break; + } + case IF_SRD_RRD_CNS: case IF_SWR_RRD_CNS: + case IF_SRW_RRD_CNS: + { assert(IsSSEOrAVXInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); @@ -11099,10 +11189,12 @@ void emitter::emitDispIns( goto PRINT_CONSTANT; } break; + } case IF_RRD_SRD: case IF_RWR_SRD: case IF_RRW_SRD: + { #ifdef TARGET_AMD64 if (ins == INS_movsxd) { @@ -11126,9 +11218,11 @@ void emitter::emitDispIns( id->idDebugOnlyInfo()->idVarRefOffs, asmfm); break; + } - case IF_RRW_SRD_CNS: + case IF_RRD_SRD_CNS: case IF_RWR_SRD_CNS: + case IF_RRW_SRD_CNS: { printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), @@ -11149,11 +11243,16 @@ void emitter::emitDispIns( break; } + case IF_RRD_RRD_SRD: case IF_RWR_RRD_SRD: + case IF_RRW_RRD_SRD: + case IF_RWR_RWR_SRD: + { printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); break; + } case IF_RWR_RRD_SRD_CNS: { @@ -11189,58 +11288,125 @@ void emitter::emitDispIns( break; } + case IF_RRD_SRD_RRD: + case IF_RWR_SRD_RRD: + case IF_RRW_SRD_RRD: + { + printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); + emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), + id->idDebugOnlyInfo()->idVarRefOffs, asmfm); + printf(", %s", emitRegName(id->idReg2(), attr)); + break; + } + + case IF_SWR_RRD_RRD: + { + printf("%s", sstr); + emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), + id->idDebugOnlyInfo()->idVarRefOffs, asmfm); + printf(", %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr)); + break; + } + case IF_RRD_RRD: case IF_RWR_RRD: case IF_RRW_RRD: - if (ins == INS_pmovmskb) - { - printf("%s, %s", emitRegName(id->idReg1(), EA_4BYTE), emitRegName(id->idReg2(), attr)); - } - else if ((ins == INS_cvtsi2ss32) || (ins == INS_cvtsi2sd32) || (ins == INS_cvtsi2ss64) || - (ins == INS_cvtsi2sd64)) - { - printf(" %s, %s", emitRegName(id->idReg1(), EA_16BYTE), emitRegName(id->idReg2(), attr)); - } - else if ((ins == INS_cvttsd2si) || (ins == INS_cvtss2si) || (ins == INS_cvtsd2si) || (ins == INS_cvttss2si)) + case IF_RRW_RRW: + { + switch (ins) { - printf(" %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), EA_16BYTE)); - } + case INS_pmovmskb: + { + printf("%s, %s", emitRegName(id->idReg1(), EA_4BYTE), emitRegName(id->idReg2(), attr)); + break; + } + + case INS_cvtsi2ss32: + case INS_cvtsi2sd32: + case INS_cvtsi2ss64: + case INS_cvtsi2sd64: + { + printf(" %s, %s", emitRegName(id->idReg1(), EA_16BYTE), emitRegName(id->idReg2(), attr)); + break; + } + + case INS_cvttsd2si: + case INS_cvtss2si: + case INS_cvtsd2si: + case INS_cvttss2si: + case INS_vcvtsd2usi: + case INS_vcvtss2usi: + case INS_vcvttsd2usi: + case INS_vcvttss2usi: + { + printf(" %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), EA_16BYTE)); + break; + } + #ifdef TARGET_AMD64 - else if (ins == INS_movsxd) - { - printf("%s, %s", emitRegName(id->idReg1(), EA_8BYTE), emitRegName(id->idReg2(), EA_4BYTE)); - } + case INS_movsxd: + { + printf("%s, %s", emitRegName(id->idReg1(), EA_8BYTE), emitRegName(id->idReg2(), EA_4BYTE)); + break; + } #endif // TARGET_AMD64 - else if (ins == INS_movsx || ins == INS_movzx) - { - printf("%s, %s", emitRegName(id->idReg1(), EA_PTRSIZE), emitRegName(id->idReg2(), attr)); - } - else if (ins == INS_bt) - { - // INS_bt operands are reversed. Display them in the normal order. - printf("%s, %s", emitRegName(id->idReg2(), attr), emitRegName(id->idReg1(), attr)); - } -#ifdef FEATURE_HW_INTRINSICS - else if (ins == INS_crc32 && attr != EA_8BYTE) - { - // The idReg1 is always 4 bytes, but the size of idReg2 can vary. - // This logic ensures that we print `crc32 eax, bx` instead of `crc32 ax, bx` - printf("%s, %s", emitRegName(id->idReg1(), EA_4BYTE), emitRegName(id->idReg2(), attr)); - } -#endif // FEATURE_HW_INTRINSICS - else - { - printf("%s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr)); - } - break; - case IF_RRW_RRW: - assert(ins == INS_xchg); - printf("%s,", emitRegName(id->idReg1(), attr)); - printf(" %s", emitRegName(id->idReg2(), attr)); + case INS_movsx: + case INS_movzx: + { + printf("%s, %s", emitRegName(id->idReg1(), EA_PTRSIZE), emitRegName(id->idReg2(), attr)); + break; + } + + case INS_bt: + { + // INS_bt operands are reversed. Display them in the normal order. + printf("%s, %s", emitRegName(id->idReg2(), attr), emitRegName(id->idReg1(), attr)); + break; + } + + case INS_crc32: + { + if (attr != EA_8BYTE) + { + // The idReg1 is always 4 bytes, but the size of idReg2 can vary. + // This logic ensures that we print `crc32 eax, bx` instead of `crc32 ax, bx` + printf("%s, %s", emitRegName(id->idReg1(), EA_4BYTE), emitRegName(id->idReg2(), attr)); + } + else + { + printf("%s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr)); + } + break; + } + + case INS_vpbroadcastb_gpr: + case INS_vpbroadcastd_gpr: + case INS_vpbroadcastw_gpr: + { + printf(" %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), EA_4BYTE)); + break; + } + + case INS_vpbroadcastq_gpr: + { + printf(" %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), EA_8BYTE)); + break; + } + + default: + { + printf("%s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr)); + break; + } + } break; + } + case IF_RRD_RRD_RRD: case IF_RWR_RRD_RRD: + case IF_RRW_RRD_RRD: + case IF_RWR_RWR_RRD: { assert(IsVexOrEvexEncodableInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); @@ -11265,6 +11431,7 @@ void emitter::emitDispIns( } case IF_RWR_RRD_RRD_CNS: + { assert(IsVexOrEvexEncodableInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); printf("%s, ", emitRegName(id->idReg1(), attr)); @@ -11272,17 +11439,19 @@ void emitter::emitDispIns( switch (ins) { - case INS_vinsertf64x4: case INS_vinsertf32x8: - case INS_vinserti64x4: + case INS_vinsertf64x4: case INS_vinserti32x8: + case INS_vinserti64x4: { attr = EA_32BYTE; break; } case INS_vinsertf128: + case INS_vinsertf64x2: case INS_vinserti128: + case INS_vinserti64x2: { attr = EA_16BYTE; break; @@ -11312,7 +11481,10 @@ void emitter::emitDispIns( val = emitGetInsSC(id); goto PRINT_CONSTANT; break; + } + case IF_RWR_RRD_RRD_RRD: + { assert(IsAVXOnlyInstruction(ins)); assert(UseVEXEncoding()); printf("%s, ", emitRegName(id->idReg1(), attr)); @@ -11320,14 +11492,20 @@ void emitter::emitDispIns( printf("%s, ", emitRegName(id->idReg3(), attr)); printf("%s", emitRegName(id->idReg4(), attr)); break; - case IF_RRW_RRW_CNS: + } + + case IF_RRD_RRD_CNS: + case IF_RWR_RRD_CNS: + case IF_RRW_RRD_CNS: { emitAttr tgtAttr = attr; switch (ins) { case INS_vextractf128: + case INS_vextractf64x2: case INS_vextracti128: + case INS_vextracti64x2: { tgtAttr = EA_16BYTE; break; @@ -11335,8 +11513,8 @@ void emitter::emitDispIns( case INS_vextractf32x8: case INS_vextractf64x4: - case INS_vextracti64x4: case INS_vextracti32x8: + case INS_vextracti64x4: { tgtAttr = EA_32BYTE; break; @@ -11400,19 +11578,46 @@ void emitter::emitDispIns( case IF_RRD: case IF_RWR: case IF_RRW: + { printf("%s", emitRegName(id->idReg1(), attr)); emitDispShift(ins); break; + } + case IF_RRD_CNS: + case IF_RWR_CNS: + case IF_RRW_CNS: case IF_RRW_SHF: + { printf("%s", emitRegName(id->idReg1(), attr)); - emitDispShift(ins, (BYTE)emitGetInsSC(id)); + + emitGetInsCns(id, &cnsVal); + val = cnsVal.cnsVal; + + if (id->idInsFmt() == IF_RRW_SHF) + { + emitDispShift(ins, (BYTE)val); + } + else + { + printf(", "); + + if (cnsVal.cnsReloc) + { + emitDispReloc(val); + } + else + { + goto PRINT_CONSTANT; + } + } break; + } case IF_RRD_MRD: case IF_RWR_MRD: case IF_RRW_MRD: - + { if (ins == INS_movsx || ins == INS_movzx) { attr = EA_PTRSIZE; @@ -11433,9 +11638,11 @@ void emitter::emitDispIns( offs = emitGetInsDsp(id); emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); break; + } - case IF_RRW_MRD_CNS: + case IF_RRD_MRD_CNS: case IF_RWR_MRD_CNS: + case IF_RRW_MRD_CNS: { printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); offs = emitGetInsDsp(id); @@ -11456,12 +11663,16 @@ void emitter::emitDispIns( break; } + case IF_MRD_RRD_CNS: case IF_MWR_RRD_CNS: + case IF_MRW_RRD_CNS: { switch (ins) { case INS_vextractf128: + case INS_vextractf64x2: case INS_vextracti128: + case INS_vextracti64x2: { // vextracti/f128 extracts 128-bit data, so we fix sstr as "xmm ptr" sstr = codeGen->genSizeStr(EA_ATTR(16)); @@ -11470,8 +11681,8 @@ void emitter::emitDispIns( case INS_vextractf32x8: case INS_vextractf64x4: - case INS_vextracti64x4: case INS_vextracti32x8: + case INS_vextracti64x4: { // vextracti/f*x* extracts 256-bit data, so we fix sstr as "ymm ptr" sstr = codeGen->genSizeStr(EA_ATTR(32)); @@ -11505,11 +11716,16 @@ void emitter::emitDispIns( break; } + case IF_RRD_RRD_MRD: case IF_RWR_RRD_MRD: + case IF_RRW_RRD_MRD: + case IF_RWR_RWR_MRD: + { printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); offs = emitGetInsDsp(id); emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); break; + } case IF_RWR_RRD_MRD_CNS: { @@ -11547,27 +11763,29 @@ void emitter::emitDispIns( } case IF_RWR_MRD_OFF: - + { printf("%s, %s", emitRegName(id->idReg1(), attr), "offset"); offs = emitGetInsDsp(id); emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); break; + } case IF_MRD_RRD: case IF_MWR_RRD: case IF_MRW_RRD: - + { printf("%s", sstr); offs = emitGetInsDsp(id); emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); printf(", %s", emitRegName(id->idReg1(), attr)); break; + } case IF_MRD_CNS: case IF_MWR_CNS: case IF_MRW_CNS: case IF_MRW_SHF: - + { printf("%s", sstr); offs = emitGetInsDsp(id); emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); @@ -11591,43 +11809,51 @@ void emitter::emitDispIns( goto PRINT_CONSTANT; } break; + } case IF_MRD: case IF_MWR: case IF_MRW: - + { printf("%s", sstr); offs = emitGetInsDsp(id); emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); emitDispShift(ins); break; + } case IF_MRD_OFF: - + { printf("offset "); offs = emitGetInsDsp(id); emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); break; + } - case IF_RRD_CNS: - case IF_RWR_CNS: - case IF_RRW_CNS: - printf("%s, ", emitRegName(id->idReg1(), attr)); - val = emitGetInsSC(id); - if (id->idIsCnsReloc()) - { - emitDispReloc(val); - } - else - { - goto PRINT_CONSTANT; - } + case IF_RRD_MRD_RRD: + case IF_RWR_MRD_RRD: + case IF_RRW_MRD_RRD: + { + printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); + offs = emitGetInsDsp(id); + emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); + printf(", %s", emitRegName(id->idReg2(), attr)); break; + } + + case IF_MWR_RRD_RRD: + { + printf("%s", sstr); + offs = emitGetInsDsp(id); + emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); + printf(", %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr)); + break; + } case IF_LABEL: case IF_RWR_LABEL: case IF_SWR_LABEL: - + { if (ins == INS_lea) { printf("%s, ", emitRegName(id->idReg1(), attr)); @@ -11664,9 +11890,11 @@ void emitter::emitDispIns( printf("L_M%03u_" FMT_BB, emitComp->compMethodID, id->idAddr()->iiaBBlabel->bbNum); } break; + } case IF_METHOD: case IF_METHPTR: + { methodName = emitComp->eeGetMethodFullName((CORINFO_METHOD_HANDLE)id->idDebugOnlyInfo()->idMemCookie); if (id->idInsFmt() == IF_METHPTR) @@ -11682,8 +11910,10 @@ void emitter::emitDispIns( } break; + } case IF_NONE: + { #if FEATURE_LOOP_ALIGN if (ins == INS_align) { @@ -11698,6 +11928,7 @@ void emitter::emitDispIns( } #endif break; + } default: printf("unexpected format %s", emitIfName(id->idInsFmt())); @@ -11957,6 +12188,8 @@ BYTE* emitter::emitOutputAlign(insGroup* ig, instrDesc* id, BYTE* dst) BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) { + assert(id->idHasMemAdr()); + regNumber reg; regNumber rgx; ssize_t dsp; @@ -12048,28 +12281,23 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // relative addressing which results in smaller instruction size. if ((ins == INS_mov) && (id->idReg1() == REG_EAX) && (reg == REG_NA) && (rgx == REG_NA)) { - switch (id->idInsFmt()) - { - case IF_RWR_ARD: - - assert(code == (insCodeRM(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8))); + insFormat insFmt = id->idInsFmt(); - code &= ~((code_t)0xFFFFFFFF); - code |= 0xA0; - isMoffset = true; - break; - - case IF_AWR_RRD: - - assert(code == (insCodeMR(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8))); + if (insFmt == IF_RWR_ARD) + { + assert(code == (insCodeRM(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8))); - code &= ~((code_t)0xFFFFFFFF); - code |= 0xA2; - isMoffset = true; - break; + code &= ~((code_t)0xFFFFFFFF); + code |= 0xA0; + isMoffset = true; + } + else if (insFmt == IF_AWR_RRD) + { + assert(code == (insCodeMR(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8))); - default: - break; + code &= ~((code_t)0xFFFFFFFF); + code |= 0xA2; + isMoffset = true; } } } @@ -12089,8 +12317,13 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) switch (id->idInsFmt()) { + case IF_RRD_RRD_ARD: case IF_RWR_RRD_ARD: + case IF_RRW_RRD_ARD: + case IF_RWR_RWR_ARD: + case IF_RRD_ARD_RRD: case IF_RWR_ARD_RRD: + case IF_RRW_ARD_RRD: case IF_RWR_RRD_ARD_CNS: case IF_RWR_RRD_ARD_RRD: { @@ -12098,8 +12331,18 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) break; } + case IF_RRD_ARD: + case IF_RWR_ARD: + case IF_RRW_ARD: + case IF_AWR_RRD_RRD: + { + src1 = id->idReg1(); + break; + } + default: { + assert(!"Unhandled insFmt in emitOutputAM"); src1 = id->idReg1(); break; } @@ -12110,7 +12353,10 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) } else if (IsDstSrcSrcAVXInstruction(ins)) { - code = insEncodeReg3456(id, id->idReg2(), size, code); + if (id->idHasReg2()) + { + code = insEncodeReg3456(id, id->idReg2(), size, code); + } } } @@ -12845,6 +13091,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) case IF_ARW_RRD: case IF_ARW_CNS: + case IF_ARW_SHF: if (id->idGCref() == GCT_BYREF) { assert(ins == INS_add || ins == INS_sub || ins == INS_sub_hide); @@ -12875,8 +13122,19 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) case IF_RWR_ARD: case IF_RRW_ARD: case IF_RWR_RRD_ARD: + case IF_RRW_RRD_ARD: + { emitGCregDeadUpd(id->idReg1(), dst); break; + } + + case IF_RWR_RWR_ARD: + { + emitGCregDeadUpd(id->idReg1(), dst); + emitGCregDeadUpd(id->idReg2(), dst); + break; + } + default: break; } @@ -12908,6 +13166,8 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) { + assert(id->idHasMemStk()); + int adr; int dsp; bool EBPbased; @@ -13334,8 +13594,19 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) case IF_RWR_SRD: // Register Write, Stack Read case IF_RRW_SRD: // Register Read/Write, Stack Read case IF_RWR_RRD_SRD: + case IF_RRW_RRD_SRD: + { + emitGCregDeadUpd(id->idReg1(), dst); + break; + } + + case IF_RWR_RWR_SRD: + { emitGCregDeadUpd(id->idReg1(), dst); + emitGCregDeadUpd(id->idReg2(), dst); break; + } + default: break; } @@ -13367,6 +13638,8 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) { + assert(id->idHasMemGen()); + BYTE* addr; CORINFO_FIELD_HANDLE fldh; ssize_t offs; @@ -13431,28 +13704,23 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // relative addressing which results in smaller instruction size. if (ins == INS_mov && id->idReg1() == REG_EAX) { - switch (id->idInsFmt()) - { - case IF_RWR_MRD: - - assert(code == (insCodeRM(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500)); - - code &= ~((code_t)0xFFFFFFFF); - code |= 0xA0; - isMoffset = true; - break; - - case IF_MWR_RRD: + insFormat insFmt = id->idInsFmt(); - assert(code == (insCodeMR(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500)); + if (insFmt == IF_RWR_MRD) + { + assert(code == (insCodeRM(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500)); - code &= ~((code_t)0xFFFFFFFF); - code |= 0xA2; - isMoffset = true; - break; + code &= ~((code_t)0xFFFFFFFF); + code |= 0xA0; + isMoffset = true; + } + else if (insFmt == IF_MWR_RRD) + { + assert(code == (insCodeMR(ins) | (insEncodeReg345(id, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500)); - default: - break; + code &= ~((code_t)0xFFFFFFFF); + code |= 0xA2; + isMoffset = true; } } } @@ -13780,6 +14048,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) case IF_MRD_CNS: case IF_MWR_CNS: case IF_MRW_CNS: + case IF_MRW_SHF: break; case IF_RRW_MRD: @@ -13807,8 +14076,19 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) case IF_RWR_MRD: case IF_RRW_MRD: case IF_RWR_RRD_MRD: + case IF_RRW_RRD_MRD: + { emitGCregDeadUpd(id->idReg1(), dst); break; + } + + case IF_RWR_RWR_MRD: + { + emitGCregDeadUpd(id->idReg1(), dst); + emitGCregDeadUpd(id->idReg2(), dst); + break; + } + default: break; } @@ -13846,6 +14126,8 @@ BYTE* emitter::emitOutputR(BYTE* dst, instrDesc* id) regNumber reg = id->idReg1(); emitAttr size = id->idOpSize(); + assert(!id->idHasReg2()); + // We would to update GC info correctly assert(!IsSSEInstruction(ins)); assert(!IsVexOrEvexEncodableInstruction(ins)); @@ -14086,6 +14368,8 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) regNumber reg2 = id->idReg2(); emitAttr size = id->idOpSize(); + assert(!id->idHasReg3()); + if (IsAvx512OrPriorInstruction(ins)) { assert((ins != INS_movd) || (isFloatReg(reg1) != isFloatReg(reg2))); @@ -14309,7 +14593,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) break; case IF_RWR_RRD: - + { if (emitSyncThisObjReg != REG_NA && emitIGisInProlog(emitCurIG) && reg2 == (int)REG_ARG_0) { // We're relocating "this" in the prolog @@ -14333,9 +14617,10 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) emitGCregLiveUpd(id->idGCref(), reg1, dst); break; + } case IF_RRW_RRD: - + { switch (id->idIns()) { /* @@ -14401,8 +14686,10 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) } break; + } case IF_RRW_RRW: + { // This must be "xchg reg1, reg2" assert(id->idIns() == INS_xchg); @@ -14441,6 +14728,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) } } break; + } default: #ifdef DEBUG @@ -14456,6 +14744,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) switch (id->idInsFmt()) { case IF_RRD_CNS: + { // INS_mulEAX can not be used with any of these formats assert(ins != INS_mulEAX && ins != INS_imulEAX); @@ -14468,12 +14757,14 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) emitGCregDeadUpd(tgtReg, dst); } break; + } case IF_RWR_RRD: case IF_RRW_RRD: - case IF_RWR_RRD_RRD: + { emitGCregDeadUpd(reg1, dst); break; + } default: break; @@ -14553,10 +14844,20 @@ BYTE* emitter::emitOutputRRR(BYTE* dst, instrDesc* id) switch (id->idInsFmt()) { case IF_RWR_RRD_RRD: + case IF_RRW_RRD_RRD: case IF_RWR_RRD_RRD_CNS: case IF_RWR_RRD_RRD_RRD: + { + emitGCregDeadUpd(id->idReg1(), dst); + break; + } + + case IF_RWR_RWR_RRD: + { emitGCregDeadUpd(id->idReg1(), dst); + emitGCregDeadUpd(id->idReg2(), dst); break; + } default: break; @@ -14580,6 +14881,8 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id) ssize_t val = emitGetInsSC(id); bool valInByte = ((signed char)val == (target_ssize_t)val) && (ins != INS_mov) && (ins != INS_test); + assert(!id->idHasReg2()); + // BT reg,imm might be useful but it requires special handling of the immediate value // (it is always encoded in a byte). Let's not complicate things until this is needed. assert(ins != INS_bt); @@ -15253,7 +15556,7 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) insGroup* tmpIGlabel = id->idAddr()->iiaIGlabel; bool tmpDspReloc = id->idIsDspReloc(); - id->idInsFmt(IF_SWR_CNS); + id->idInsFmt(emitInsModeFormat(ins, IF_SRD_CNS)); id->idAddr()->iiaLclVar = ((instrDescLbl*)id)->dstLclVar; id->idSetIsDspReloc(false); @@ -15279,7 +15582,7 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) idAmd->idDebugOnlyInfo(id->idDebugOnlyInfo()); } - idAmd->idInsFmt(IF_RWR_ARD); + idAmd->idInsFmt(emitInsModeFormat(ins, IF_RRD_ARD)); idAmd->idAddr()->iiaAddrMode.amBaseReg = REG_NA; idAmd->idAddr()->iiaAddrMode.amIndxReg = REG_NA; emitSetAmdDisp(idAmd, distVal); // set the displacement @@ -15477,9 +15780,9 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI disp8Compression = inputSize * 4; break; case INS_TT_TUPLE8: - // N = input size in bytes * 4, 32bit for 512 only + // N = input size in bytes * 8, 32bit for 512 only assert((inputSize == 4 && vectorLength >= 64)); - disp8Compression = inputSize * 4; + disp8Compression = inputSize * 8; break; case INS_TT_HALF_MEM: // N = vector length in bytes / 2 @@ -15578,6 +15881,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) /* No operands */ /********************************************************************/ case IF_NONE: + { // the loop alignment pseudo instruction if (ins == INS_align) { @@ -15652,19 +15956,23 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } break; + } /********************************************************************/ /* Simple constant, local label, method */ /********************************************************************/ case IF_CNS: + { dst = emitOutputIV(dst, id); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_CNS(id); break; + } case IF_LABEL: case IF_RWR_LABEL: case IF_SWR_LABEL: + { assert(id->idGCref() == GCT_NONE); assert(id->idIsBound() || emitJmpInstHasNoCode(id)); @@ -15679,9 +15987,11 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } sz = (id->idInsFmt() == IF_SWR_LABEL ? sizeof(instrDescLbl) : sizeof(instrDescJmp)); break; + } case IF_METHOD: case IF_METHPTR: + { // Assume we'll be recording this call recCall = true; @@ -15876,6 +16186,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) #endif // DEBUG break; + } /********************************************************************/ /* One register operand */ @@ -15884,15 +16195,18 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_RRD: case IF_RWR: case IF_RRW: + { dst = emitOutputR(dst, id); sz = SMALL_IDSC_SIZE; break; + } /********************************************************************/ /* Register and register/constant */ /********************************************************************/ case IF_RRW_SHF: + { code = insCodeMR(ins); // Emit the VEX prefix if it exists code = AddSimdPrefixIfNeeded(id, code, size); @@ -15919,40 +16233,56 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutputRexOrSimdPrefixIfNeeded(ins, dst, code); dst += emitOutputWord(dst, code); dst += emitOutputByte(dst, emitGetInsSC(id)); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_CNS(id); // Update GC info. assert(!id->idGCref()); emitGCregDeadUpd(id->idReg1(), dst); break; + } case IF_RRD_RRD: case IF_RWR_RRD: case IF_RRW_RRD: case IF_RRW_RRW: + { dst = emitOutputRR(dst, id); sz = SMALL_IDSC_SIZE; break; + } case IF_RRD_CNS: case IF_RWR_CNS: case IF_RRW_CNS: + { dst = emitOutputRI(dst, id); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_CNS(id); break; + } + case IF_RRD_RRD_RRD: case IF_RWR_RRD_RRD: + case IF_RRW_RRD_RRD: + case IF_RWR_RWR_RRD: + { dst = emitOutputRRR(dst, id); - sz = emitSizeOfInsDsc(id); + sz = sizeof(instrDesc); break; + } + case IF_RWR_RRD_RRD_CNS: case IF_RWR_RRD_RRD_RRD: + { dst = emitOutputRRR(dst, id); - sz = emitSizeOfInsDsc(id); dst += emitOutputByte(dst, emitGetInsSC(id)); + sz = emitSizeOfInsDsc_CNS(id); break; + } - case IF_RRW_RRW_CNS: + case IF_RRD_RRD_CNS: + case IF_RWR_RRD_CNS: + case IF_RRW_RRD_CNS: + { assert(id->idGCref() == GCT_NONE); // Get the 'base' opcode (it's a big one) @@ -16063,7 +16393,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } dst += emitOutputByte(dst, emitGetInsSC(id)); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_CNS(id); // Kill any GC ref in the destination register if necessary. if (!emitInsCanOnlyWriteSSE2OrAVXReg(id)) @@ -16071,6 +16401,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) emitGCregDeadUpd(id->idReg1(), dst); } break; + } /********************************************************************/ /* Address mode operand */ @@ -16079,7 +16410,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_ARD: case IF_AWR: case IF_ARW: - + { dst = emitCodeWithInstructionSize(dst, emitOutputAM(dst, id, insCodeMR(ins)), &callInstrSize); switch (ins) @@ -16116,20 +16447,33 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) goto DONE_CALL; default: - sz = emitSizeOfInsDsc(id); + { + if (id->idInsFmt() == IF_ARD) + { + sz = emitSizeOfInsDsc_SPEC(id); + } + else + { + sz = emitSizeOfInsDsc_AMD(id); + } break; + } } break; + } - case IF_RRW_ARD_CNS: + case IF_RRD_ARD_CNS: case IF_RWR_ARD_CNS: + case IF_RRW_ARD_CNS: + { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); code = insCodeRM(ins); - // Special case 4-byte AVX instructions if (EncodedBySSE38orSSE3A(ins)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputAM(dst, id, code, &cnsVal); } else @@ -16139,25 +16483,35 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst = emitOutputAM(dst, id, code | regcode, &cnsVal); } - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_AMD(id); break; + } + case IF_ARD_RRD_CNS: case IF_AWR_RRD_CNS: + case IF_ARW_RRD_CNS: + { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); - code = insCodeMR(ins); - dst = emitOutputAM(dst, id, code, &cnsVal); - sz = emitSizeOfInsDsc(id); + dst = emitOutputAM(dst, id, insCodeMR(ins), &cnsVal); + sz = emitSizeOfInsDsc_AMD(id); break; + } case IF_RRD_ARD: case IF_RWR_ARD: case IF_RRW_ARD: + case IF_RRD_RRD_ARD: case IF_RWR_RRD_ARD: + case IF_RRW_RRD_ARD: + case IF_RWR_RWR_ARD: { code = insCodeRM(ins); + if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputAM(dst, id, code); } else @@ -16166,16 +16520,18 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); dst = emitOutputAM(dst, id, code | regcode); } - sz = emitSizeOfInsDsc(id); + + sz = emitSizeOfInsDsc_AMD(id); break; } + case IF_RRD_ARD_RRD: case IF_RWR_ARD_RRD: + case IF_RRW_ARD_RRD: { assert(IsAVX2GatherInstruction(ins)); - code = insCodeRM(ins); - dst = emitOutputAM(dst, id, code); - sz = emitSizeOfInsDsc(id); + dst = emitOutputAM(dst, id, insCodeRM(ins)); + sz = emitSizeOfInsDsc_AMD(id); break; } @@ -16185,8 +16541,11 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert(IsAvx512OrPriorInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); code = insCodeRM(ins); + if (EncodedBySSE38orSSE3A(ins)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputAM(dst, id, code, &cnsVal); } else @@ -16195,42 +16554,60 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); dst = emitOutputAM(dst, id, code | regcode, &cnsVal); } - sz = emitSizeOfInsDsc(id); + + sz = emitSizeOfInsDsc_AMD(id); break; } case IF_ARD_RRD: case IF_AWR_RRD: case IF_ARW_RRD: - code = insCodeMR(ins); - code = AddSimdPrefixIfNeeded(id, code, size); - regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); - dst = emitOutputAM(dst, id, code | regcode); - sz = emitSizeOfInsDsc(id); + { + code = insCodeMR(ins); + + if (EncodedBySSE38orSSE3A(ins)) + { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte + dst = emitOutputAM(dst, id, code); + } + else + { + code = AddSimdPrefixIfNeeded(id, code, size); + regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); + dst = emitOutputAM(dst, id, code | regcode); + } + + sz = emitSizeOfInsDsc_AMD(id); break; + } case IF_AWR_RRD_RRD: { code = insCodeMR(ins); code = AddSimdPrefixIfNeeded(id, code, size); dst = emitOutputAM(dst, id, code); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_AMD(id); break; } case IF_ARD_CNS: case IF_AWR_CNS: case IF_ARW_CNS: + { emitGetInsAmdCns(id, &cnsVal); dst = emitOutputAM(dst, id, insCodeMI(ins), &cnsVal); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_AMD(id); break; + } case IF_ARW_SHF: + { emitGetInsAmdCns(id, &cnsVal); dst = emitOutputAM(dst, id, insCodeMR(ins), &cnsVal); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_AMD(id); break; + } /********************************************************************/ /* Stack-based operand */ @@ -16239,7 +16616,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_SRD: case IF_SWR: case IF_SRW: - + { assert(ins != INS_pop_hide); if (ins == INS_pop) { @@ -16263,40 +16640,50 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { goto IND_CALL; } - break; + } case IF_SRD_CNS: case IF_SWR_CNS: case IF_SRW_CNS: + { emitGetInsCns(id, &cnsVal); dst = emitOutputSV(dst, id, insCodeMI(ins), &cnsVal); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_CNS(id); break; + } case IF_SRW_SHF: + { emitGetInsCns(id, &cnsVal); dst = emitOutputSV(dst, id, insCodeMR(ins), &cnsVal); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_CNS(id); break; + } + case IF_SRD_RRD_CNS: case IF_SWR_RRD_CNS: + case IF_SRW_RRD_CNS: + { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); - code = insCodeMR(ins); - dst = emitOutputSV(dst, id, insCodeMR(ins), &cnsVal); - sz = emitSizeOfInsDsc(id); + dst = emitOutputSV(dst, id, insCodeMR(ins), &cnsVal); + sz = emitSizeOfInsDsc_CNS(id); break; + } - case IF_RRW_SRD_CNS: + case IF_RRD_SRD_CNS: case IF_RWR_SRD_CNS: + case IF_RRW_SRD_CNS: + { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsCns(id, &cnsVal); code = insCodeRM(ins); - // Special case 4-byte AVX instructions if (EncodedBySSE38orSSE3A(ins)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputSV(dst, id, code, &cnsVal); } else @@ -16319,8 +16706,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst = emitOutputSV(dst, id, code | regcode, &cnsVal); } - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_CNS(id); break; + } case IF_RRD_SRD: case IF_RWR_SRD: @@ -16328,10 +16716,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { code = insCodeRM(ins); - // 4-byte AVX instructions are special cased inside emitOutputSV - // since they do not have space to encode ModRM byte. if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputSV(dst, id, code); } else @@ -16347,12 +16735,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); dst = emitOutputSV(dst, id, code | regcode); } - - sz = emitSizeOfInsDsc(id); + sz = sizeof(instrDesc); break; } + case IF_RRD_RRD_SRD: case IF_RWR_RRD_SRD: + case IF_RRW_RRD_SRD: + case IF_RWR_RWR_SRD: { assert(IsVexOrEvexEncodableInstruction(ins)); @@ -16361,10 +16751,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = insEncodeReg3456(id, id->idReg2(), size, code); // encode source operand reg in 'vvvv' bits in 1's complement form - // 4-byte AVX instructions are special cased inside emitOutputSV - // since they do not have space to encode ModRM byte. if (EncodedBySSE38orSSE3A(ins)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputSV(dst, id, code); } else @@ -16372,6 +16762,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); dst = emitOutputSV(dst, id, code | regcode); } + sz = sizeof(instrDesc); break; } @@ -16387,43 +16778,69 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = insEncodeReg3456(id, id->idReg2(), size, code); // encode source operand reg in 'vvvv' bits in 1's complement form - // 4-byte AVX instructions are special cased inside emitOutputSV - // since they do not have space to encode ModRM byte. - if (EncodedBySSE38orSSE3A(ins)) - { - dst = emitOutputSV(dst, id, code, &cnsVal); - } - else - { + if (EncodedBySSE38orSSE3A(ins)) + { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte + dst = emitOutputSV(dst, id, code, &cnsVal); + } + else + { + regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); + dst = emitOutputSV(dst, id, code | regcode, &cnsVal); + } + sz = emitSizeOfInsDsc_CNS(id); + break; + } + + case IF_SRD_RRD: + case IF_SWR_RRD: + case IF_SRW_RRD: + { + code = insCodeMR(ins); + + if (EncodedBySSE38orSSE3A(ins)) + { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte + dst = emitOutputSV(dst, id, code); + } + else + { + code = AddSimdPrefixIfNeeded(id, code, size); + + // In case of AVX instructions that take 3 operands, encode reg1 as first source. + // Note that reg1 is both a source and a destination. + // + // TODO-XArch-CQ: Eventually we need to support 3 operand instruction formats. For + // now we use the single source as source1 and source2. + // For this format, moves do not support a third operand, so we only need to handle the binary ops. + if (IsDstDstSrcAVXInstruction(ins)) + { + // encode source operand reg in 'vvvv' bits in 1's complement form + code = insEncodeReg3456(id, id->idReg1(), size, code); + } + regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); - dst = emitOutputSV(dst, id, code | regcode, &cnsVal); + dst = emitOutputSV(dst, id, code | regcode); } - sz = emitSizeOfInsDsc(id); + sz = sizeof(instrDesc); break; } - case IF_SRD_RRD: - case IF_SWR_RRD: - case IF_SRW_RRD: - code = insCodeMR(ins); - code = AddSimdPrefixIfNeeded(id, code, size); - - // In case of AVX instructions that take 3 operands, encode reg1 as first source. - // Note that reg1 is both a source and a destination. - // - // TODO-XArch-CQ: Eventually we need to support 3 operand instruction formats. For - // now we use the single source as source1 and source2. - // For this format, moves do not support a third operand, so we only need to handle the binary ops. - if (IsDstDstSrcAVXInstruction(ins)) - { - // encode source operand reg in 'vvvv' bits in 1's complement form - code = insEncodeReg3456(id, id->idReg1(), size, code); - } + case IF_RRD_SRD_RRD: + case IF_RWR_SRD_RRD: + case IF_RRW_SRD_RRD: + { + assert(IsAVX2GatherInstruction(ins)); + unreached(); + } - regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); - dst = emitOutputSV(dst, id, code | regcode); - break; + case IF_SWR_RRD_RRD: + { + unreached(); + } /********************************************************************/ /* Direct memory address */ @@ -16432,25 +16849,39 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_MRD: case IF_MRW: case IF_MWR: - + { noway_assert(ins != INS_call); dst = emitOutputCV(dst, id, insCodeMR(ins) | 0x0500); - sz = emitSizeOfInsDsc(id); + if (id->idInsFmt() == IF_MRD) + { + sz = emitSizeOfInsDsc_SPEC(id); + } + else + { + sz = emitSizeOfInsDsc_DSP(id); + } break; + } case IF_MRD_OFF: + { dst = emitOutputCV(dst, id, insCodeMI(ins)); + sz = sizeof(instrDesc); break; + } - case IF_RRW_MRD_CNS: + case IF_RRD_MRD_CNS: case IF_RWR_MRD_CNS: + case IF_RRW_MRD_CNS: + { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsDcmCns(id, &cnsVal); code = insCodeRM(ins); - // Special case 4-byte AVX instructions if (EncodedBySSE38orSSE3A(ins)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputCV(dst, id, code, &cnsVal); } else @@ -16473,19 +16904,24 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst = emitOutputCV(dst, id, code | regcode | 0x0500, &cnsVal); } - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_DSP(id); break; + } + case IF_MRD_RRD_CNS: case IF_MWR_RRD_CNS: - assert((ins == INS_vextractf128) || (ins == INS_vextractf32x8) || (ins == INS_vextractf64x4) || - (ins == INS_vextracti128) || (ins == INS_vextracti32x8) || (ins == INS_vextracti64x4)); + case IF_MRW_RRD_CNS: + { + assert((ins == INS_vextractf128) || (ins == INS_vextractf32x8) || (ins == INS_vextractf64x2) || + (ins == INS_vextractf64x4) || (ins == INS_vextracti128) || (ins == INS_vextracti32x8) || + (ins == INS_vextracti64x2) || (ins == INS_vextracti64x4)); assert(UseSimdEncoding()); emitGetInsDcmCns(id, &cnsVal); - code = insCodeMR(ins); // we do not need VEX.vvvv to encode the register operand - dst = emitOutputCV(dst, id, code, &cnsVal); - sz = emitSizeOfInsDsc(id); + dst = emitOutputCV(dst, id, insCodeMR(ins), &cnsVal); + sz = emitSizeOfInsDsc_DSP(id); break; + } case IF_RRD_MRD: case IF_RWR_MRD: @@ -16493,15 +16929,22 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { code = insCodeRM(ins); - // Special case 4-byte AVX instructions if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputCV(dst, id, code); } else { code = AddSimdPrefixIfNeeded(id, code, size); + // In case of AVX instructions that take 3 operands, encode reg1 as first source. + // Note that reg1 is both a source and a destination. + // + // TODO-XArch-CQ: Eventually we need to support 3 operand instruction formats. For + // now we use the single source as source1 and source2. + // For this format, moves do not support a third operand, so we only need to handle the binary ops. if (IsDstDstSrcAVXInstruction(ins)) { // encode source operand reg in 'vvvv' bits in 1's complement form @@ -16510,6 +16953,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); CORINFO_FIELD_HANDLE fldh = id->idAddr()->iiaFieldHnd; + if (fldh == FLD_GLOBAL_GS) { dst = emitOutputCV(dst, id, code | regcode | 0x0400); @@ -16520,11 +16964,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } } - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_DSP(id); break; } + case IF_RRD_RRD_MRD: case IF_RWR_RRD_MRD: + case IF_RRW_RRD_MRD: + case IF_RWR_RWR_MRD: { // This should only be called on AVX instructions assert(IsVexOrEvexEncodableInstruction(ins)); @@ -16534,9 +16981,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = insEncodeReg3456(id, id->idReg2(), size, code); // encode source operand reg in 'vvvv' bits in 1's complement form - // Special case 4-byte AVX instructions if (EncodedBySSE38orSSE3A(ins)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputCV(dst, id, code); } else @@ -16544,7 +16992,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); dst = emitOutputCV(dst, id, code | regcode | 0x0500); } - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_DSP(id); break; } @@ -16560,9 +17008,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = insEncodeReg3456(id, id->idReg2(), size, code); // encode source operand reg in 'vvvv' bits in 1's complement form - // Special case 4-byte AVX instructions if (EncodedBySSE38orSSE3A(ins)) { + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte dst = emitOutputCV(dst, id, code, &cnsVal); } else @@ -16570,11 +17019,12 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); dst = emitOutputCV(dst, id, code | regcode | 0x0500, &cnsVal); } - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_DSP(id); break; } case IF_RWR_MRD_OFF: + { code = insCode(ins); code = AddSimdPrefixIfNeeded(id, code, size); @@ -16592,45 +17042,77 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regcode = insEncodeReg012(id, id->idReg1(), size, &code); dst = emitOutputCV(dst, id, code | 0x30 | regcode); - sz = emitSizeOfInsDsc(id); + + sz = emitSizeOfInsDsc_DSP(id); break; + } case IF_MRD_RRD: case IF_MWR_RRD: case IF_MRW_RRD: + { code = insCodeMR(ins); - code = AddSimdPrefixIfNeeded(id, code, size); - // In case of AVX instructions that take 3 operands, encode reg1 as first source. - // Note that reg1 is both a source and a destination. - // - // TODO-XArch-CQ: Eventually we need to support 3 operand instruction formats. For - // now we use the single source as source1 and source2. - // For this format, moves do not support a third operand, so we only need to handle the binary ops. - if (IsDstDstSrcAVXInstruction(ins)) + if (EncodedBySSE38orSSE3A(ins)) { - // encode source operand reg in 'vvvv' bits in 1's complement form - code = insEncodeReg3456(id, id->idReg1(), size, code); + // Special case 4-byte AVX instructions as the + // regcode position conflicts with the opcode byte + dst = emitOutputCV(dst, id, code); + } + else + { + code = AddSimdPrefixIfNeeded(id, code, size); + + // In case of AVX instructions that take 3 operands, encode reg1 as first source. + // Note that reg1 is both a source and a destination. + // + // TODO-XArch-CQ: Eventually we need to support 3 operand instruction formats. For + // now we use the single source as source1 and source2. + // For this format, moves do not support a third operand, so we only need to handle the binary ops. + if (IsDstDstSrcAVXInstruction(ins)) + { + // encode source operand reg in 'vvvv' bits in 1's complement form + code = insEncodeReg3456(id, id->idReg1(), size, code); + } + + regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); + dst = emitOutputCV(dst, id, code | regcode | 0x0500); } - regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); - dst = emitOutputCV(dst, id, code | regcode | 0x0500); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_DSP(id); break; + } case IF_MRD_CNS: case IF_MWR_CNS: case IF_MRW_CNS: + { emitGetInsDcmCns(id, &cnsVal); dst = emitOutputCV(dst, id, insCodeMI(ins) | 0x0500, &cnsVal); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_DSP(id); break; + } case IF_MRW_SHF: + { emitGetInsDcmCns(id, &cnsVal); dst = emitOutputCV(dst, id, insCodeMR(ins) | 0x0500, &cnsVal); - sz = emitSizeOfInsDsc(id); + sz = emitSizeOfInsDsc_DSP(id); break; + } + + case IF_RRD_MRD_RRD: + case IF_RWR_MRD_RRD: + case IF_RRW_MRD_RRD: + { + assert(IsAVX2GatherInstruction(ins)); + unreached(); + } + + case IF_MWR_RRD_RRD: + { + unreached(); + } /********************************************************************/ /* oops */ @@ -16802,150 +17284,61 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) #pragma warning(pop) #endif -emitter::insFormat emitter::getMemoryOperation(instrDesc* id) +emitter::insFormat emitter::getMemoryOperation(instrDesc* id) const { - insFormat result = IF_NONE; instruction ins = id->idIns(); insFormat insFmt = id->idInsFmt(); if (ins == INS_lea) { // an INS_lea instruction doesn't actually read memory - insFmt = IF_NONE; + return IF_NONE; } - switch (insFmt) - { - case IF_NONE: - case IF_LABEL: - case IF_RWR_LABEL: - case IF_METHOD: - case IF_CNS: - - case IF_RRD: - case IF_RWR: - case IF_RRW: - case IF_RRD_CNS: - case IF_RWR_CNS: - case IF_RRW_CNS: - case IF_RRW_SHF: - case IF_RRD_RRD: - case IF_RWR_RRD: - case IF_RRW_RRD: - case IF_RRW_RRW: - case IF_RRW_RRW_CNS: - case IF_RWR_RRD_RRD: - case IF_RWR_RRD_RRD_CNS: - case IF_RWR_RRD_RRD_RRD: - // none, or register only - result = IF_NONE; - break; - - case IF_ARD: - case IF_RRD_ARD: - case IF_RWR_ARD: - case IF_RRW_ARD: - case IF_RWR_ARD_CNS: - case IF_RWR_RRD_ARD: - case IF_RRW_ARD_CNS: - case IF_RWR_ARD_RRD: - case IF_RWR_RRD_ARD_CNS: - case IF_RWR_RRD_ARD_RRD: - case IF_ARD_CNS: - case IF_ARD_RRD: - // Address [reg+reg*scale+cns] - read - result = IF_ARD; - break; - - case IF_AWR: - case IF_AWR_RRD: - case IF_AWR_CNS: - case IF_AWR_RRD_CNS: - case IF_AWR_RRD_RRD: - // Address [reg+reg*scale+cns] - write - result = IF_AWR; - break; - - case IF_ARW: - case IF_ARW_RRD: - case IF_ARW_CNS: - case IF_ARW_SHF: - // Address [reg+reg*scale+cns] - read and write - result = IF_ARW; - break; - - case IF_MRD: - case IF_MRD_CNS: - case IF_MRD_OFF: - case IF_MRD_RRD: - case IF_RRD_MRD: - case IF_RRW_MRD: - case IF_RWR_MRD: - case IF_RWR_MRD_CNS: - case IF_RWR_MRD_OFF: - case IF_RWR_RRD_MRD: - case IF_RRW_MRD_CNS: - case IF_RWR_RRD_MRD_CNS: - case IF_RWR_RRD_MRD_RRD: - case IF_METHPTR: - // Address [cns] - read - result = IF_MRD; - break; + return ExtractMemoryFormat(insFmt); +} - case IF_MWR: - case IF_MWR_CNS: - case IF_MWR_RRD: - case IF_MWR_RRD_CNS: - // Address [cns] - write - result = IF_MWR; - break; +emitter::insFormat emitter::ExtractMemoryFormat(insFormat insFmt) const +{ + IS_INFO isInfo = emitGetSchedInfo(insFmt); - case IF_MRW: - case IF_MRW_CNS: - case IF_MRW_RRD: - case IF_MRW_SHF: - // Address [cns] - read and write - result = IF_MWR; - break; + IS_INFO mask = static_cast(isInfo & (IS_GM_RD | IS_GM_RW | IS_GM_WR)); + if (mask != 0) + { + static_assert_no_msg(0 == (IS_GM_RD >> 13)); + static_assert_no_msg(1 == (IS_GM_WR >> 13)); + static_assert_no_msg(2 == (IS_GM_RW >> 13)); - case IF_SRD: - case IF_SRD_CNS: - case IF_SRD_RRD: + insFormat result = static_cast(IF_MRD + (mask >> 13)); + assert((result == IF_MRD) || (result == IF_MWR) || (result == IF_MRW)); + return result; + } - case IF_RRD_SRD: - case IF_RRW_SRD: - case IF_RWR_SRD: - case IF_RWR_SRD_CNS: - case IF_RWR_RRD_SRD: - case IF_RRW_SRD_CNS: - case IF_RWR_RRD_SRD_CNS: - case IF_RWR_RRD_SRD_RRD: - // Stack [RSP] - read - result = IF_SRD; - break; + mask = static_cast(isInfo & (IS_SF_RD | IS_SF_RW | IS_SF_WR)); + if (mask != 0) + { + static_assert_no_msg(0 == (IS_SF_RD >> 16)); + static_assert_no_msg(1 == (IS_SF_WR >> 16)); + static_assert_no_msg(2 == (IS_SF_RW >> 16)); - case IF_SWR: - case IF_SWR_CNS: - case IF_SWR_RRD: - case IF_SWR_RRD_CNS: - case IF_SWR_LABEL: - // Stack [RSP] - write - result = IF_SWR; - break; + insFormat result = static_cast(IF_SRD + (mask >> 16)); + assert((result == IF_SRD) || (result == IF_SWR) || (result == IF_SRW)); + return result; + } - case IF_SRW: - case IF_SRW_CNS: - case IF_SRW_RRD: - case IF_SRW_SHF: - // Stack [RSP] - read and write - result = IF_SWR; - break; + mask = static_cast(isInfo & (IS_AM_RD | IS_AM_RW | IS_AM_WR)); + if (mask != 0) + { + static_assert_no_msg(0 == (IS_AM_RD >> 19)); + static_assert_no_msg(1 == (IS_AM_WR >> 19)); + static_assert_no_msg(2 == (IS_AM_RW >> 19)); - default: - result = IF_NONE; - break; + insFormat result = static_cast(IF_ARD + (mask >> 19)); + assert((result == IF_ARD) || (result == IF_AWR) || (result == IF_ARW)); + return result; } - return result; + + return IF_NONE; } #if defined(DEBUG) || defined(LATE_DISASM) @@ -17423,7 +17816,7 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_shld: case INS_shrd: result.insLatency += PERFSCORE_LATENCY_3C; - if (insFmt == IF_RRW_RRW_CNS) + if (insFmt == IF_RRW_RRD_CNS) { // ins reg, reg, cns result.insThroughput = PERFSCORE_THROUGHPUT_1C; @@ -17541,10 +17934,8 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins break; case IF_SRD: - result.insThroughput = PERFSCORE_THROUGHPUT_3C; - break; - case IF_ARD: + case IF_MRD: result.insThroughput = PERFSCORE_THROUGHPUT_3C; break; @@ -17773,11 +18164,65 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_cvttps2dq: case INS_cvtps2dq: case INS_cvtdq2ps: + case INS_vcvtpd2qq: + case INS_vcvtpd2uqq: + case INS_vcvtps2udq: + case INS_vcvtqq2pd: + case INS_vcvttps2udq: + case INS_vcvtudq2ps: + case INS_vcvttpd2qq: + case INS_vcvttpd2uqq: + case INS_vcvtuqq2pd: + case INS_vfixupimmpd: + case INS_vfixupimmps: + case INS_vfixupimmsd: + case INS_vfixupimmss: + case INS_vgetexppd: + case INS_vgetexpps: + case INS_vgetexpsd: + case INS_vgetexpss: + case INS_vgetmantpd: + case INS_vgetmantps: + case INS_vgetmantsd: + case INS_vgetmantss: + case INS_vrangepd: + case INS_vrangeps: + case INS_vrangesd: + case INS_vrangess: + case INS_vreducepd: + case INS_vreduceps: + case INS_vreducesd: + case INS_vreducess: + case INS_vscalefpd: + case INS_vscalefps: + case INS_vscalefsd: + case INS_vscalefss: + { + result.insThroughput = PERFSCORE_THROUGHPUT_2X; + result.insLatency += PERFSCORE_LATENCY_4C; + break; + } + + case INS_vpmovdb: case INS_vpmovdw: + case INS_vpmovqb: case INS_vpmovqd: + case INS_vpmovqw: + case INS_vpmovsdb: + case INS_vpmovsdw: + case INS_vpmovsqb: + case INS_vpmovsqd: + case INS_vpmovsqw: + case INS_vpmovswb: + case INS_vpmovusdb: + case INS_vpmovusdw: + case INS_vpmovusqb: + case INS_vpmovusqd: + case INS_vpmovusqw: + case INS_vpmovuswb: case INS_vpmovwb: - result.insThroughput = PERFSCORE_THROUGHPUT_2X; - result.insLatency += PERFSCORE_LATENCY_4C; + result.insThroughput = PERFSCORE_THROUGHPUT_2C; + result.insLatency += (opSize == EA_16BYTE) ? PERFSCORE_LATENCY_2C : PERFSCORE_LATENCY_4C; break; case INS_haddps: @@ -17826,13 +18271,41 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins result.insLatency += PERFSCORE_LATENCY_4C; break; + case INS_vrcp14pd: + case INS_vrcp14ps: + case INS_vrcp14sd: + case INS_vrcp14ss: + case INS_vrsqrt14pd: + case INS_vrsqrt14sd: + case INS_vrsqrt14ps: + case INS_vrsqrt14ss: + { + if (opSize == EA_64BYTE) + { + result.insThroughput = PERFSCORE_THROUGHPUT_2C; + result.insLatency += PERFSCORE_LATENCY_8C; + } + else + { + result.insThroughput = PERFSCORE_THROUGHPUT_1C; + result.insLatency += PERFSCORE_LATENCY_4C; + } + break; + } + case INS_roundpd: case INS_roundps: case INS_roundsd: case INS_roundss: + case INS_vrndscalepd: + case INS_vrndscaleps: + case INS_vrndscalesd: + case INS_vrndscaless: + { result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += PERFSCORE_LATENCY_8C; break; + } case INS_cvttsd2si: case INS_cvtsd2si: @@ -17840,12 +18313,20 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_cvtsi2ss32: case INS_cvtsi2sd64: case INS_cvtsi2ss64: + case INS_vcvtsd2usi: + case INS_vcvttsd2usi: + case INS_vcvtusi2sd32: + case INS_vcvtusi2sd64: + case INS_vcvtusi2ss32: + case INS_vcvtusi2ss64: result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += PERFSCORE_LATENCY_7C; break; case INS_cvttss2si: case INS_cvtss2si: + case INS_vcvtss2usi: + case INS_vcvttss2usi: result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += opSize == EA_8BYTE ? PERFSCORE_LATENCY_8C : PERFSCORE_LATENCY_7C; break; @@ -17935,13 +18416,24 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_psignw: case INS_psignd: case INS_vpsravd: + case INS_vpsravq: + case INS_vpsravw: case INS_blendvps: case INS_blendvpd: case INS_pblendvb: + case INS_vpcmpeqb: + case INS_vpcmpeqw: + case INS_vpcmpeqd: + case INS_vpcmpeqq: + case INS_vpcmpgtb: + case INS_vpcmpgtw: + case INS_vpcmpgtd: case INS_vpsllvd: case INS_vpsllvq: + case INS_vpsllvw: case INS_vpsrlvd: case INS_vpsrlvq: + case INS_vpsrlvw: case INS_vpternlogd: result.insThroughput = PERFSCORE_THROUGHPUT_2X; result.insLatency += PERFSCORE_LATENCY_1C; @@ -18066,26 +18558,37 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_psadbw: case INS_vpermps: case INS_vpermpd: + case INS_vpermpd_reg: case INS_vpermd: case INS_vpermq: + case INS_vpermq_reg: case INS_vperm2i128: case INS_vperm2f128: case INS_vextractf128: case INS_vextractf32x8: + case INS_vextractf64x2: case INS_vextractf64x4: case INS_vextracti128: case INS_vextracti32x8: + case INS_vextracti64x2: case INS_vextracti64x4: case INS_vinsertf128: - case INS_vinsertf64x4: case INS_vinsertf32x8: + case INS_vinsertf64x2: + case INS_vinsertf64x4: case INS_vinserti128: - case INS_vinserti64x4: case INS_vinserti32x8: + case INS_vinserti64x2: + case INS_vinserti64x4: result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += PERFSCORE_LATENCY_3C; break; + case INS_vpermw: + result.insThroughput = PERFSCORE_THROUGHPUT_2C; + result.insLatency += PERFSCORE_LATENCY_6C; + break; + case INS_pextrb: case INS_pextrd: case INS_pextrw: @@ -18127,6 +18630,10 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_cmppd: case INS_cmpss: case INS_cmpsd: + case INS_vcmpps: + case INS_vcmppd: + case INS_vcmpss: + case INS_vcmpsd: result.insThroughput = PERFSCORE_THROUGHPUT_2X; result.insLatency = PERFSCORE_LATENCY_4C; break; @@ -18174,6 +18681,15 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_cvtdq2pd: case INS_cvtpd2ps: case INS_cvttpd2dq: + case INS_vcvtpd2udq: + case INS_vcvtps2qq: + case INS_vcvtps2uqq: + case INS_vcvtqq2ps: + case INS_vcvttpd2udq: + case INS_vcvttps2qq: + case INS_vcvttps2uqq: + case INS_vcvtudq2pd: + case INS_vcvtuqq2ps: result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += opSize == EA_32BYTE ? PERFSCORE_LATENCY_7C : PERFSCORE_LATENCY_5C; break; @@ -18206,22 +18722,34 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins break; case INS_vpbroadcastb: + case INS_vpbroadcastb_gpr: case INS_vpbroadcastw: + case INS_vpbroadcastw_gpr: case INS_vpbroadcastd: + case INS_vpbroadcastd_gpr: case INS_vpbroadcastq: + case INS_vpbroadcastq_gpr: case INS_vbroadcasti128: case INS_vbroadcastf128: + case INS_vbroadcastf64x2: + case INS_vbroadcasti64x2: + case INS_vbroadcastf64x4: + case INS_vbroadcasti64x4: + case INS_vbroadcastf32x2: + case INS_vbroadcasti32x2: + case INS_vbroadcastf32x8: + case INS_vbroadcasti32x8: case INS_vbroadcastss: case INS_vbroadcastsd: if (memAccessKind == PERFSCORE_MEMORY_NONE) { result.insThroughput = PERFSCORE_THROUGHPUT_1C; - result.insLatency = opSize == EA_32BYTE ? PERFSCORE_LATENCY_3C : PERFSCORE_LATENCY_1C; + result.insLatency = opSize == EA_16BYTE ? PERFSCORE_LATENCY_1C : PERFSCORE_LATENCY_3C; } else { result.insThroughput = PERFSCORE_THROUGHPUT_2X; - result.insLatency += opSize == EA_32BYTE ? PERFSCORE_LATENCY_3C : PERFSCORE_LATENCY_2C; + result.insLatency += opSize == EA_16BYTE ? PERFSCORE_LATENCY_2C : PERFSCORE_LATENCY_3C; if (ins == INS_vpbroadcastb || ins == INS_vpbroadcastw) { result.insLatency += PERFSCORE_LATENCY_1C; diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index 25846609b507fc..1ac3ad219ab9b4 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -105,6 +105,8 @@ static bool IsKInstruction(instruction ins); static regNumber getBmiRegNumber(instruction ins); static regNumber getSseShiftRegNumber(instruction ins); +bool HasVexEncoding(instruction ins) const; +bool HasEvexEncoding(instruction ins) const; bool IsVexEncodableInstruction(instruction ins) const; bool IsEvexEncodableInstruction(instruction ins) const; bool IsVexOrEvexEncodableInstruction(instruction ins) const; @@ -183,6 +185,8 @@ code_t AddVexPrefixIfNeededAndNotPresent(instruction ins, code_t code, emitAttr return code; } +insTupleType insTupleTypeInfo(instruction ins) const; + //------------------------------------------------------------------------ // HasKMaskRegisterDest: Temporary check to identify instructions that can // be Evex encoded but require Opmask(KMask) register support. @@ -491,6 +495,12 @@ void emitAdjustStackDepthPushPop(instruction ins); void emitAdjustStackDepth(instruction ins, ssize_t val); #endif // !FEATURE_FIXED_OUT_ARGS +size_t emitSizeOfInsDsc_AMD(instrDesc* id) const; +size_t emitSizeOfInsDsc_CNS(instrDesc* id) const; +size_t emitSizeOfInsDsc_DSP(instrDesc* id) const; +size_t emitSizeOfInsDsc_NONE(instrDesc* id) const; +size_t emitSizeOfInsDsc_SPEC(instrDesc* id) const; + /***************************************************************************** * * Convert between an index scale in bytes to a smaller encoding used for @@ -680,18 +690,13 @@ void emitIns_AX_R(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, void emitIns_SIMD_R_R_I(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, int ival); void emitIns_SIMD_R_R_A(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, GenTreeIndir* indir); -void emitIns_SIMD_R_R_AR( - instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber base, int offset); void emitIns_SIMD_R_R_C( instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, CORINFO_FIELD_HANDLE fldHnd, int offs); void emitIns_SIMD_R_R_R(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg); void emitIns_SIMD_R_R_S(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, int varx, int offs); -#ifdef FEATURE_HW_INTRINSICS void emitIns_SIMD_R_R_A_I( instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, GenTreeIndir* indir, int ival); -void emitIns_SIMD_R_R_AR_I( - instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber base, int ival); void emitIns_SIMD_R_R_C_I(instruction ins, emitAttr attr, regNumber targetReg, @@ -704,6 +709,7 @@ void emitIns_SIMD_R_R_R_I( void emitIns_SIMD_R_R_S_I( instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, int varx, int offs, int ival); +#ifdef FEATURE_HW_INTRINSICS void emitIns_SIMD_R_R_R_A( instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTreeIndir* indir); void emitIns_SIMD_R_R_R_AR( @@ -733,6 +739,37 @@ void emitIns_SIMD_R_R_C_R(instruction ins, int offs); void emitIns_SIMD_R_R_S_R( instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, int varx, int offs); + +void emitIns_SIMD_R_R_R_A_I(instruction ins, + emitAttr attr, + regNumber targetReg, + regNumber op1Reg, + regNumber op2Reg, + GenTreeIndir* indir, + int ival); +void emitIns_SIMD_R_R_R_C_I(instruction ins, + emitAttr attr, + regNumber targetReg, + regNumber op1Reg, + regNumber op2Reg, + CORINFO_FIELD_HANDLE fldHnd, + int offs, + int ival); +void emitIns_SIMD_R_R_R_R_I(instruction ins, + emitAttr attr, + regNumber targetReg, + regNumber op1Reg, + regNumber op2Reg, + regNumber op3Reg, + int ival); +void emitIns_SIMD_R_R_R_S_I(instruction ins, + emitAttr attr, + regNumber targetReg, + regNumber op1Reg, + regNumber op2Reg, + int varx, + int offs, + int ival); #endif // FEATURE_HW_INTRINSICS enum EmitCallType diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index f0b87d933e17c8..5a8f5f9ff0bc56 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -2536,7 +2536,6 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed { LclVarDsc* lclDsc = lvaGetDesc(lclNum); assert(lclDsc->lvSingleDef == 0); - // could restrict this to TYP_REF lclDsc->lvSingleDef = !lclDsc->lvHasMultipleILStoreOp && !lclDsc->lvHasLdAddrOp; if (lclDsc->lvSingleDef) @@ -3494,19 +3493,20 @@ void Compiler::fgFindBasicBlocks() // This temp should already have the type of the return value. JITDUMP("\nInliner: re-using pre-existing spill temp V%02u\n", lvaInlineeReturnSpillTemp); - if (info.compRetType == TYP_REF) + // We may have co-opted an existing temp for the return spill. + // We likely assumed it was single-def at the time, but now + // we can see it has multiple definitions. + if ((fgReturnCount > 1) && (lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef == 1)) { - // We may have co-opted an existing temp for the return spill. - // We likely assumed it was single-def at the time, but now - // we can see it has multiple definitions. - if ((fgReturnCount > 1) && (lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef == 1)) + // Make sure it is no longer marked single def. This is only safe + // to do if we haven't ever updated the type. + if (info.compRetType == TYP_REF) { - // Make sure it is no longer marked single def. This is only safe - // to do if we haven't ever updated the type. assert(!lvaTable[lvaInlineeReturnSpillTemp].lvClassInfoUpdated); - JITDUMP("Marked return spill temp V%02u as NOT single def temp\n", lvaInlineeReturnSpillTemp); - lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 0; } + + JITDUMP("Marked return spill temp V%02u as NOT single def temp\n", lvaInlineeReturnSpillTemp); + lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 0; } } else @@ -3515,18 +3515,18 @@ void Compiler::fgFindBasicBlocks() lvaInlineeReturnSpillTemp = lvaGrabTemp(false DEBUGARG("Inline return value spill temp")); lvaTable[lvaInlineeReturnSpillTemp].lvType = info.compRetType; + // The return spill temp is single def only if the method has a single return block. + if (fgReturnCount == 1) + { + lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 1; + JITDUMP("Marked return spill temp V%02u as a single def temp\n", lvaInlineeReturnSpillTemp); + } + // If the method returns a ref class, set the class of the spill temp // to the method's return value. We may update this later if it turns // out we can prove the method returns a more specific type. if (info.compRetType == TYP_REF) { - // The return spill temp is single def only if the method has a single return block. - if (fgReturnCount == 1) - { - lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 1; - JITDUMP("Marked return spill temp V%02u as a single def temp\n", lvaInlineeReturnSpillTemp); - } - CORINFO_CLASS_HANDLE retClassHnd = impInlineInfo->inlineCandidateInfo->methInfo.args.retTypeClass; if (retClassHnd != nullptr) { diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index d1b1adb3b0d376..0fcae61c53cdf0 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -3436,7 +3436,7 @@ void Compiler::fgDebugCheckLinkedLocals() bool ShouldLink(GenTree* node) { - return node->OperIsLocal() || node->OperIs(GT_LCL_ADDR); + return node->OperIsAnyLocal(); } public: @@ -3524,7 +3524,7 @@ void Compiler::fgDebugCheckLinkedLocals() int nodeIndex = 0; for (GenTree* cur = first; cur != nullptr; cur = cur->gtNext) { - success &= cur->OperIsLocal() || cur->OperIs(GT_LCL_ADDR); + success &= cur->OperIsAnyLocal(); success &= (nodeIndex < expected->Height()) && (cur == expected->Bottom(nodeIndex)); nodeIndex++; } @@ -4200,6 +4200,90 @@ class SsaCheckVisitor : public GenTreeVisitor void SetBlock(BasicBlock* block) { m_block = block; + CheckPhis(block); + } + + void CheckPhis(BasicBlock* block) + { + Statement* nonPhiStmt = nullptr; + for (Statement* const stmt : block->Statements()) + { + // All PhiDefs should appear before any other statements + // + if (!stmt->IsPhiDefnStmt()) + { + if (nonPhiStmt == nullptr) + { + nonPhiStmt = stmt; + } + continue; + } + + if (nonPhiStmt != nullptr) + { + SetHasErrors(); + JITDUMP("[error] " FMT_BB " PhiDef " FMT_STMT " appears after non-PhiDef " FMT_STMT "\n", block->bbNum, + stmt->GetID(), nonPhiStmt->GetID()); + } + + GenTree* const phiDefNode = stmt->GetRootNode(); + assert(phiDefNode->IsPhiDefn()); + GenTreeLclVarCommon* const phiDefLclNode = phiDefNode->gtGetOp1()->AsLclVarCommon(); + GenTreePhi* const phi = phiDefNode->gtGetOp2()->AsPhi(); + + // Verify each GT_PHI_ARG is the right local. + // + // If block does not begin a handler, verify GT_PHI_ARG blocks are unique + // (that is, each pred supplies at most one ssa def). + // + BitVecTraits bitVecTraits(m_compiler->fgBBNumMax + 1, m_compiler); + BitVec phiPreds(BitVecOps::MakeEmpty(&bitVecTraits)); + + for (GenTreePhi::Use& use : phi->Uses()) + { + GenTreePhiArg* const phiArgNode = use.GetNode()->AsPhiArg(); + if (phiArgNode->GetLclNum() != phiDefLclNode->GetLclNum()) + { + SetHasErrors(); + JITDUMP("[error] Wrong local V%02u in PhiArg [%06u] -- expected V%02u\n", phiArgNode->GetLclNum(), + m_compiler->dspTreeID(phiArgNode), phiDefLclNode->GetLclNum()); + } + + // Handlers can have multiple PhiArgs from the same block and implicit preds. + // So we can't easily check their PhiArgs. + // + if (m_compiler->bbIsHandlerBeg(block)) + { + continue; + } + + BasicBlock* const phiArgBlock = phiArgNode->gtPredBB; + + if (phiArgBlock != nullptr) + { + if (BitVecOps::IsMember(&bitVecTraits, phiPreds, phiArgBlock->bbNum)) + { + SetHasErrors(); + JITDUMP("[error] " FMT_BB " [%06u]: multiple PhiArgs for predBlock " FMT_BB "\n", block->bbNum, + m_compiler->dspTreeID(phi), phiArgBlock->bbNum); + } + + BitVecOps::AddElemD(&bitVecTraits, phiPreds, phiArgBlock->bbNum); + + // If phiArgBlock is not a pred of block we either have messed up when building + // SSA or made modifications after building SSA and possibly should have pruned + // out or updated this PhiArg. + // + FlowEdge* const edge = m_compiler->fgGetPredForBlock(block, phiArgBlock); + + if (edge == nullptr) + { + JITDUMP("[info] " FMT_BB " [%06u]: stale PhiArg [%06u] pred block " FMT_BB "\n", block->bbNum, + m_compiler->dspTreeID(phi), m_compiler->dspTreeID(phiArgNode), phiArgBlock->bbNum); + } + } + } + } } void DoChecks() diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index 526cea6443d4ba..da2ce15b72dec0 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -1453,7 +1453,7 @@ PhaseStatus Compiler::fgPostImportationCleanup() { LclVarDsc* returnSpillVarDsc = lvaGetDesc(lvaInlineeReturnSpillTemp); - if (returnSpillVarDsc->lvSingleDef) + if ((returnSpillVarDsc->lvType == TYP_REF) && returnSpillVarDsc->lvSingleDef) { lvaUpdateClass(lvaInlineeReturnSpillTemp, retExprClassHnd, impInlineInfo->retExprClassHndIsExact); } @@ -3445,24 +3445,14 @@ bool Compiler::fgBlockEndFavorsTailDuplication(BasicBlock* block, unsigned lclNu while (count < limit) { count++; + unsigned storeLclNum; GenTree* const tree = stmt->GetRootNode(); - if (tree->OperIs(GT_ASG) && !tree->OperIsBlkOp()) + if (tree->OperIsStoreLcl(&storeLclNum) && (storeLclNum == lclNum) && !tree->OperIsBlkOp()) { - GenTree* const op1 = tree->AsOp()->gtOp1; - - if (op1->IsLocal()) + GenTree* const data = tree->Data(); + if (data->OperIsArrLength() || data->OperIsConst() || data->OperIsCompare()) { - const unsigned op1LclNum = op1->AsLclVarCommon()->GetLclNum(); - - if (op1LclNum == lclNum) - { - GenTree* const op2 = tree->AsOp()->gtOp2; - - if (op2->OperIsArrLength() || op2->OperIsConst() || op2->OperIsCompare()) - { - return true; - } - } + return true; } } @@ -3616,36 +3606,29 @@ bool Compiler::fgBlockIsGoodTailDuplicationCandidate(BasicBlock* target, unsigne // Otherwise check the first stmt. // Verify the branch is just a simple local compare. // + unsigned storeLclNum; GenTree* const firstTree = firstStmt->GetRootNode(); - - if (firstTree->gtOper != GT_ASG) - { - return false; - } - - GenTree* const lhs = firstTree->AsOp()->gtOp1; - if (!lhs->OperIs(GT_LCL_VAR)) + if (!firstTree->OperIsStoreLclVar(&storeLclNum)) { return false; } - const unsigned lhsLcl = lhs->AsLclVarCommon()->GetLclNum(); - if (lhsLcl != *lclNum) + if (storeLclNum != *lclNum) { return false; } // Could allow unary here too... // - GenTree* const rhs = firstTree->AsOp()->gtOp2; - if (!rhs->OperIsBinary()) + GenTree* const data = firstTree->Data(); + if (!data->OperIsBinary()) { return false; } // op1 must be some combinations of casts of local or constant // (or unary) - op1 = rhs->AsOp()->gtOp1; + op1 = data->AsOp()->gtOp1; while (op1->gtOper == GT_CAST) { op1 = op1->AsOp()->gtOp1; @@ -3658,7 +3641,7 @@ bool Compiler::fgBlockIsGoodTailDuplicationCandidate(BasicBlock* target, unsigne // op2 must be some combinations of casts of local or constant // (or unary) - op2 = rhs->AsOp()->gtOp2; + op2 = data->AsOp()->gtOp2; // A binop may not actually have an op2. // diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp index a215559cbdb2f3..39c16f10314b7b 100644 --- a/src/coreclr/jit/fgprofile.cpp +++ b/src/coreclr/jit/fgprofile.cpp @@ -2333,12 +2333,42 @@ PhaseStatus Compiler::fgPrepareToInstrumentMethod() prejit ? (JitConfig.JitMinimalPrejitProfiling() > 0) : (JitConfig.JitMinimalJitProfiling() > 0); // In majority of cases, methods marked with [Intrinsic] are imported directly - // in Tier1 so the profile will never be consumed. Thus, let's avoid unnecessary probes. + // in Tier1 so the profile will never be consumed. Thus, let's avoid unnecessary probes... if (minimalProfiling && (info.compFlags & CORINFO_FLG_INTRINSIC) != 0) { - fgCountInstrumentor = new (this, CMK_Pgo) NonInstrumentor(this); - fgHistogramInstrumentor = new (this, CMK_Pgo) NonInstrumentor(this); - return PhaseStatus::MODIFIED_NOTHING; + //... except a few intrinsics that might still need it: + bool shouldBeInstrumented = false; + NamedIntrinsic ni = lookupNamedIntrinsic(info.compMethodHnd); + switch (ni) + { + // These are marked as [Intrinsic] only to be handled (unrolled) for constant inputs. + // In other cases they have large managed implementations we want to profile. + case NI_System_String_Equals: + case NI_System_Buffer_Memmove: + case NI_System_MemoryExtensions_Equals: + case NI_System_MemoryExtensions_SequenceEqual: + case NI_System_MemoryExtensions_StartsWith: + + // Same here, these are only folded when JIT knows the exact types + case NI_System_Type_IsAssignableFrom: + case NI_System_Type_IsAssignableTo: + case NI_System_Type_op_Equality: + case NI_System_Type_op_Inequality: + shouldBeInstrumented = true; + break; + + default: + // Some Math intrinsics have large managed implementations we want to profile. + shouldBeInstrumented = ni >= NI_SYSTEM_MATH_START && ni <= NI_SYSTEM_MATH_END; + break; + } + + if (!shouldBeInstrumented) + { + fgCountInstrumentor = new (this, CMK_Pgo) NonInstrumentor(this); + fgHistogramInstrumentor = new (this, CMK_Pgo) NonInstrumentor(this); + return PhaseStatus::MODIFIED_NOTHING; + } } if (minimalProfiling && (fgBBcount < 2)) @@ -2425,6 +2455,12 @@ PhaseStatus Compiler::fgInstrumentMethod() } } + // Even though we haven't yet instrumented, we may have made changes in anticipation... + // + const bool madeAnticipatoryChanges = fgCountInstrumentor->ModifiedFlow() || fgHistogramInstrumentor->ModifiedFlow(); + const PhaseStatus earlyExitPhaseStatus = + madeAnticipatoryChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING; + // Optionally, when jitting, if there were no class probes and only one count probe, // suppress instrumentation. // @@ -2448,13 +2484,14 @@ PhaseStatus Compiler::fgInstrumentMethod() { JITDUMP( "Not instrumenting method: minimal probing enabled, and method has only one counter and no class probes\n"); - return PhaseStatus::MODIFIED_NOTHING; + + return earlyExitPhaseStatus; } if (schema.size() == 0) { JITDUMP("Not instrumenting method: no schemas were created\n"); - return PhaseStatus::MODIFIED_NOTHING; + return earlyExitPhaseStatus; } JITDUMP("Instrumenting method: %d count probes and %d class probes\n", fgCountInstrumentor->SchemaCount(), @@ -2485,13 +2522,9 @@ PhaseStatus Compiler::fgInstrumentMethod() if (res != E_NOTIMPL) { noway_assert(!"Error: unexpected hresult from allocPgoInstrumentationBySchema"); - return PhaseStatus::MODIFIED_NOTHING; } - // We may have modified control flow preparing for instrumentation. - // - const bool modifiedFlow = fgCountInstrumentor->ModifiedFlow() || fgHistogramInstrumentor->ModifiedFlow(); - return modifiedFlow ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING; + return earlyExitPhaseStatus; } JITDUMP("Instrumentation data base address is %p\n", dspPtr(profileMemory)); @@ -2674,35 +2707,25 @@ PhaseStatus Compiler::fgIncorporateProfileData() if (fgPgoHaveWeights) { - // We expect not to have both block and edge counts. We may have other - // forms of profile data even if we do not have any counts. - // - // As of 4/6/2023 the following invariant check turns out to no longer hold. - // Tracking issue: https://github.com/dotnet/runtime/issues/84446 + // If for some reason we have both block and edge counts, prefer the edge counts. // - // assert(!haveBlockCounts || !haveEdgeCounts); - bool dataIsGood = false; - if (haveBlockCounts) + if (haveEdgeCounts) { - dataIsGood = fgIncorporateBlockCounts(); + dataIsGood = fgIncorporateEdgeCounts(); } - else if (haveEdgeCounts) + else if (haveBlockCounts) { - dataIsGood = fgIncorporateEdgeCounts(); + dataIsGood = fgIncorporateBlockCounts(); } - // Profile incorporation may have tossed out all PGO data if it - // encountered major issues. This is perhaps too drastic. Consider - // at least keeping the class profile data, or perhaps enable full synthesis. - // - // If profile incorporation hit fixable problems, run synthesis in repair mode. + // If profile incorporation hit fixable problems, run synthesis in blend mode. // if (fgPgoHaveWeights && !dataIsGood) { - JITDUMP("\nIncorporated count data had inconsistencies; repairing profile...\n"); - ProfileSynthesis::Run(this, ProfileSynthesisOption::RepairLikelihoods); + JITDUMP("\nIncorporated count data had inconsistencies; blending profile...\n"); + ProfileSynthesis::Run(this, ProfileSynthesisOption::BlendLikelihoods); } } @@ -3521,10 +3544,9 @@ void EfficientEdgeCountReconstructor::Propagate() // if (m_badcode || m_mismatch || m_failedToConverge || m_allWeightsZero) { - // Make sure nothing else in the jit looks at the profile data. + // Make sure nothing else in the jit looks at the count profile data. // m_comp->fgPgoHaveWeights = false; - m_comp->fgPgoSchema = nullptr; if (m_badcode) { @@ -3543,7 +3565,7 @@ void EfficientEdgeCountReconstructor::Propagate() m_comp->fgPgoFailReason = "PGO data available, profile data was all zero"; } - JITDUMP("... discarding profile data: %s\n", m_comp->fgPgoFailReason); + JITDUMP("... discarding profile count data: %s\n", m_comp->fgPgoFailReason); return; } diff --git a/src/coreclr/jit/fgprofilesynthesis.cpp b/src/coreclr/jit/fgprofilesynthesis.cpp index 4930122f50ae0d..286510cf71d606 100644 --- a/src/coreclr/jit/fgprofilesynthesis.cpp +++ b/src/coreclr/jit/fgprofilesynthesis.cpp @@ -620,9 +620,12 @@ void ProfileSynthesis::BlendLikelihoods() case BBJ_COND: case BBJ_SWITCH: { - // Capture the existing weights and assign new - // weights based on heuristics. - weight_t sum = SumOutgoingLikelihoods(block, &likelihoods); + // Capture the existing weights and assign new likelihoods based on synthesis. + // + weight_t const sum = SumOutgoingLikelihoods(block, &likelihoods); + bool const unlikely = Compiler::fgProfileWeightsEqual(sum, 0.0, epsilon); + bool const consistent = Compiler::fgProfileWeightsEqual(sum, 1.0, epsilon); + bool const zero = Compiler::fgProfileWeightsEqual(block->bbWeight, 0.0, epsilon); if (block->bbJumpKind == BBJ_COND) { @@ -633,10 +636,12 @@ void ProfileSynthesis::BlendLikelihoods() AssignLikelihoodSwitch(block); } - if (Compiler::fgProfileWeightsEqual(sum, 0.0, epsilon)) + if (unlikely || zero) { - // Existing likelihood was zero. Go with the synthesized likelihoods. - JITDUMP("Existing likelihoods in " FMT_BB " were zero, synthesizing new ones\n", block->bbNum); + // Existing likelihood was zero, or profile weight was zero. Just use synthesis likelihoods. + // + JITDUMP("%s in " FMT_BB " was zero, using synthesized likelihoods\n", + unlikely ? "Existing likelihood" : "Block weight", block->bbNum); break; } @@ -645,6 +650,7 @@ void ProfileSynthesis::BlendLikelihoods() if (!Compiler::fgProfileWeightsEqual(sum, 1.0, epsilon)) { // Existing likelihood was too low or too high. Scale. + // weight_t scale = 1.0 / sum; JITDUMP("Scaling old likelihoods in " FMT_BB " by " FMT_WT "\n", block->bbNum, scale); for (iter = likelihoods.begin(); iter != likelihoods.end(); iter++) diff --git a/src/coreclr/jit/fgstmt.cpp b/src/coreclr/jit/fgstmt.cpp index cf503ec5b57c6f..7fa2250633c3ed 100644 --- a/src/coreclr/jit/fgstmt.cpp +++ b/src/coreclr/jit/fgstmt.cpp @@ -171,7 +171,7 @@ Statement* Compiler::fgNewStmtAtEnd(BasicBlock* block, GenTree* tree, const Debu //------------------------------------------------------------------------ // fgInsertStmtNearEnd: Insert the given statement at the end of the given basic block, -// but before the GT_JTRUE, if present. +// but before the terminating node, if present. // // Arguments: // block - the block into which 'stmt' will be inserted; @@ -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->KindIs(BBJ_EHFINALLYRET, BBJ_EHFAULTRET, BBJ_EHFILTERRET, BBJ_COND, BBJ_SWITCH, BBJ_RETURN)) { Statement* firstStmt = block->firstStmt(); noway_assert(firstStmt != nullptr); @@ -191,24 +191,28 @@ void Compiler::fgInsertStmtNearEnd(BasicBlock* block, Statement* stmt) Statement* insertionPoint = lastStmt->GetPrevStmt(); #if DEBUG - if (block->bbJumpKind == BBJ_COND) + if (block->KindIs(BBJ_COND)) { - assert(lastStmt->GetRootNode()->gtOper == GT_JTRUE); + assert(lastStmt->GetRootNode()->OperIs(GT_JTRUE)); } - else if (block->bbJumpKind == BBJ_RETURN) + else if (block->KindIs(BBJ_RETURN)) { - assert((lastStmt->GetRootNode()->gtOper == GT_RETURN) || (lastStmt->GetRootNode()->gtOper == GT_JMP) || + assert((lastStmt->GetRootNode()->OperIs(GT_RETURN, GT_JMP)) || // BBJ_RETURN blocks in functions returning void do not get a GT_RETURN node if they // have a .tail prefix (even if canTailCall returns false for these calls) // code:Compiler::impImportBlockCode (search for the RET: label) // Ditto for real tail calls (all code after them has been removed) - ((lastStmt->GetRootNode()->gtOper == GT_CALL) && + (lastStmt->GetRootNode()->OperIs(GT_CALL) && ((info.compRetType == TYP_VOID) || lastStmt->GetRootNode()->AsCall()->IsTailCall()))); } + else if (block->KindIs(BBJ_EHFINALLYRET, BBJ_EHFAULTRET, BBJ_EHFILTERRET)) + { + assert(lastStmt->GetRootNode()->OperIs(GT_RETFILT)); + } else { - assert(block->bbJumpKind == BBJ_SWITCH); - assert(lastStmt->GetRootNode()->gtOper == GT_SWITCH); + assert(block->KindIs(BBJ_SWITCH)); + assert(lastStmt->GetRootNode()->OperIs(GT_SWITCH)); } #endif // DEBUG @@ -524,6 +528,7 @@ inline bool OperIsControlFlow(genTreeOps oper) { case GT_JTRUE: case GT_JCMP: + case GT_JTEST: case GT_JCC: case GT_SWITCH: case GT_LABEL: diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 38b5e3bd821338..e521469fb99771 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -336,10 +336,7 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block) // Use a double indirection GenTree* addr = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pAddrOfCaptureThreadGlobal, GTF_ICON_CONST_PTR, true); - - value = gtNewOperNode(GT_IND, TYP_INT, addr); - // This indirection won't cause an exception. - value->gtFlags |= GTF_IND_NONFAULTING; + value = gtNewIndir(TYP_INT, addr, GTF_IND_NONFAULTING); } else { @@ -899,6 +896,9 @@ bool Compiler::fgAddrCouldBeNull(GenTree* addr) case GT_COMMA: return fgAddrCouldBeNull(addr->AsOp()->gtOp2); + case GT_CALL: + return !addr->IsHelperCall() || !s_helperCallProperties.NonNullReturn(addr->AsCall()->GetHelperNum()); + case GT_ADD: if (addr->AsOp()->gtOp1->gtOper == GT_CNS_INT) { @@ -2698,7 +2698,7 @@ PhaseStatus Compiler::fgAddInternal() { // Test the JustMyCode VM global state variable GenTree* embNode = gtNewIconEmbHndNode(dbgHandle, pDbgHandle, GTF_ICON_GLOBAL_PTR, info.compMethodHnd); - GenTree* guardCheckVal = gtNewOperNode(GT_IND, TYP_INT, embNode); + GenTree* guardCheckVal = gtNewIndir(TYP_INT, embNode); GenTree* guardCheckCond = gtNewOperNode(GT_EQ, TYP_INT, guardCheckVal, gtNewZeroConNode(TYP_INT)); // Create the callback which will yield the final answer @@ -2841,6 +2841,189 @@ PhaseStatus Compiler::fgFindOperOrder() return PhaseStatus::MODIFIED_EVERYTHING; } +//------------------------------------------------------------------------ +// fgRationalizeAssignments: Rewrite assignment nodes into stores. +// +// TODO-ASG: delete. +// +PhaseStatus Compiler::fgRationalizeAssignments() +{ + class AssignmentRationalizationVisitor : public GenTreeVisitor + { + public: + enum + { + DoPreOrder = true + }; + + AssignmentRationalizationVisitor(Compiler* compiler) : GenTreeVisitor(compiler) + { + } + + fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) + { + GenTree* node = *use; + + // GTF_ASG is sometimes not propagated from setup arg assignments so we have to check for GTF_CALL too. + if ((node->gtFlags & (GTF_ASG | GTF_CALL)) == 0) + { + return fgWalkResult::WALK_SKIP_SUBTREES; + } + + if (node->OperIs(GT_ASG)) + { + GenTreeFlags lhsRhsFlags = node->gtGetOp1()->gtFlags | node->gtGetOp2()->gtFlags; + *use = m_compiler->fgRationalizeAssignment(node->AsOp()); + + // TP: return early quickly for simple assignments. + if ((lhsRhsFlags & (GTF_ASG | GTF_CALL)) == 0) + { + return fgWalkResult::WALK_SKIP_SUBTREES; + } + } + + return fgWalkResult::WALK_CONTINUE; + } + }; + + AssignmentRationalizationVisitor visitor(this); + for (BasicBlock* block : Blocks()) + { + for (Statement* stmt : block->Statements()) + { + GenTree** use = stmt->GetRootNodePointer(); + if (visitor.PreOrderVisit(use, nullptr) == fgWalkResult::WALK_CONTINUE) + { + visitor.WalkTree(use, nullptr); + } + } + } + + compAssignmentRationalized = true; + +#ifdef DEBUG + if (JitConfig.JitStressMorphStores()) + { + for (BasicBlock* block : Blocks()) + { + for (Statement* stmt : block->Statements()) + { + fgMorphBlockStmt(block, stmt DEBUGARG("fgRationalizeAssignments")); + } + } + } +#endif // DEBUG + + return PhaseStatus::MODIFIED_EVERYTHING; +} + +//------------------------------------------------------------------------ +// fgRationalizeAssignment: Rewrite GT_ASG into a store node. +// +// Arguments: +// assignment - The assignment node to rewrite +// +// Return Value: +// Assignment's location, turned into the appropriate store node. +// +GenTree* Compiler::fgRationalizeAssignment(GenTreeOp* assignment) +{ + assert(assignment->OperGet() == GT_ASG); + + bool isReverseOp = assignment->IsReverseOp(); + GenTree* location = assignment->gtGetOp1(); + GenTree* value = assignment->gtGetOp2(); + if (location->OperIsLocal()) + { + assert((location->gtFlags & GTF_VAR_DEF) != 0); + } + else if (value->OperIs(GT_LCL_VAR)) + { + assert((value->gtFlags & GTF_VAR_DEF) == 0); + } + + if (assignment->OperIsInitBlkOp()) + { + // No SIMD types are allowed for InitBlks (including zero-inits). + assert(assignment->TypeIs(TYP_STRUCT) && location->TypeIs(TYP_STRUCT)); + } + + genTreeOps storeOp; + switch (location->OperGet()) + { + case GT_LCL_VAR: + storeOp = GT_STORE_LCL_VAR; + break; + case GT_LCL_FLD: + storeOp = GT_STORE_LCL_FLD; + break; + case GT_BLK: + storeOp = GT_STORE_BLK; + break; + case GT_IND: + storeOp = GT_STOREIND; + break; + default: + unreached(); + } + + JITDUMP("Rewriting GT_ASG(%s, X) to %s(X)\n", GenTree::OpName(location->OperGet()), GenTree::OpName(storeOp)); + + GenTree* store = location; + store->SetOperRaw(storeOp); + store->Data() = value; + store->gtFlags |= GTF_ASG; + store->AddAllEffectsFlags(value); + store->AddAllEffectsFlags(assignment->gtFlags & GTF_GLOB_REF); // TODO-ASG: zero-diff quirk, delete. + if (isReverseOp && !store->OperIsLocalStore()) + { + store->SetReverseOp(); + } + store->CopyRawCosts(assignment); + + if (storeOp == GT_STOREIND) + { + store->AsStoreInd()->SetRMWStatusDefault(); + } + + // [..., LHS, ..., RHS, ASG] -> [..., ..., RHS, LHS] (normal) + // [..., RHS, ..., LHS, ASG] -> [..., RHS, ..., LHS] (reversed) + if (assignment->gtPrev != nullptr) + { + assert(fgNodeThreading == NodeThreading::AllTrees); + if (isReverseOp) + { + GenTree* nextNode = assignment->gtNext; + store->gtNext = nextNode; + if (nextNode != nullptr) + { + nextNode->gtPrev = store; + } + } + else + { + if (store->gtPrev != nullptr) + { + store->gtPrev->gtNext = store->gtNext; + } + store->gtNext->gtPrev = store->gtPrev; + + store->gtPrev = assignment->gtPrev; + store->gtNext = assignment->gtNext; + store->gtPrev->gtNext = store; + if (store->gtNext != nullptr) + { + store->gtNext->gtPrev = store; + } + } + } + + DISPNODE(store); + JITDUMP("\n"); + + return store; +} + //------------------------------------------------------------------------ // fgSimpleLowering: do full walk of all IR, lowering selected operations // and computing lvaOutgoingArgSpaceSize. diff --git a/src/coreclr/jit/forwardsub.cpp b/src/coreclr/jit/forwardsub.cpp index a2636938ef446b..7be061365d2e2a 100644 --- a/src/coreclr/jit/forwardsub.cpp +++ b/src/coreclr/jit/forwardsub.cpp @@ -743,7 +743,7 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) // Don't substitute nodes args morphing doesn't handle into struct args. // if (fsv.IsCallArg() && fsv.GetNode()->TypeIs(TYP_STRUCT) && - !fwdSubNode->OperIs(GT_BLK, GT_FIELD, GT_LCL_VAR, GT_LCL_FLD, GT_MKREFANY)) + !fwdSubNode->OperIs(GT_BLK, GT_LCL_VAR, GT_LCL_FLD, GT_MKREFANY)) { JITDUMP(" use is a struct arg; fwd sub node is not OBJ/LCL_VAR/LCL_FLD/MKREFANY\n"); return false; diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 3d2748659ef185..3f5d9d5eee7f93 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -264,7 +264,6 @@ void GenTree::InitNodeSize() GenTree::s_gtNodeSizes[GT_ARR_INDEX] = TREE_NODE_SZ_LARGE; GenTree::s_gtNodeSizes[GT_ARR_OFFSET] = TREE_NODE_SZ_LARGE; GenTree::s_gtNodeSizes[GT_RET_EXPR] = TREE_NODE_SZ_LARGE; - GenTree::s_gtNodeSizes[GT_FIELD] = TREE_NODE_SZ_LARGE; GenTree::s_gtNodeSizes[GT_FIELD_ADDR] = TREE_NODE_SZ_LARGE; GenTree::s_gtNodeSizes[GT_CMPXCHG] = TREE_NODE_SZ_LARGE; GenTree::s_gtNodeSizes[GT_QMARK] = TREE_NODE_SZ_LARGE; @@ -319,7 +318,7 @@ void GenTree::InitNodeSize() static_assert_no_msg(sizeof(GenTreeConditional) <= TREE_NODE_SZ_SMALL); static_assert_no_msg(sizeof(GenTreeCast) <= TREE_NODE_SZ_LARGE); // *** large node static_assert_no_msg(sizeof(GenTreeBox) <= TREE_NODE_SZ_LARGE); // *** large node - static_assert_no_msg(sizeof(GenTreeField) <= TREE_NODE_SZ_LARGE); // *** large node + static_assert_no_msg(sizeof(GenTreeFieldAddr) <= TREE_NODE_SZ_LARGE); // *** large node static_assert_no_msg(sizeof(GenTreeFieldList) <= TREE_NODE_SZ_SMALL); static_assert_no_msg(sizeof(GenTreeColon) <= TREE_NODE_SZ_SMALL); static_assert_no_msg(sizeof(GenTreeCall) <= TREE_NODE_SZ_LARGE); // *** large node @@ -567,7 +566,7 @@ void GenTree::DumpNodeSizes(FILE* fp) LocalsGenTreeList::iterator LocalsGenTreeList::begin() const { GenTree* first = m_stmt->GetTreeList(); - assert((first == nullptr) || first->OperIsLocal() || first->OperIs(GT_LCL_ADDR)); + assert((first == nullptr) || first->OperIsAnyLocal()); return iterator(static_cast(first)); } @@ -730,12 +729,15 @@ ClassLayout* GenTree::GetLayout(Compiler* compiler) const switch (OperGet()) { case GT_LCL_VAR: + case GT_STORE_LCL_VAR: return compiler->lvaGetDesc(AsLclVar())->GetLayout(); case GT_LCL_FLD: + case GT_STORE_LCL_FLD: return AsLclFld()->GetLayout(); case GT_BLK: + case GT_STORE_BLK: return AsBlk()->GetLayout(); case GT_COMMA: @@ -750,10 +752,6 @@ ClassLayout* GenTree::GetLayout(Compiler* compiler) const structHnd = compiler->impGetRefAnyClass(); break; - case GT_FIELD: - compiler->eeGetFieldType(AsField()->gtFldHnd, &structHnd); - break; - case GT_CALL: structHnd = AsCall()->gtRetClsHnd; break; @@ -2155,30 +2153,17 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc if (call->gtCallType == CT_HELPER) { - switch (eeGetHelperNum(call->gtCallMethHnd)) + CorInfoHelpFunc helper = eeGetHelperNum(call->gtCallMethHnd); + switch (helper) { + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: case CORINFO_HELP_NEWARR_1_DIRECT: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: { // This is an array allocation site. Grab the array length node. - arrayLength = call->gtArgs.GetArgByIndex(1)->GetNode(); - break; - } - - case CORINFO_HELP_READYTORUN_NEWARR_1: - { - // On arm when compiling on certain platforms for ready to - // run, a handle will be inserted before the length. To - // handle this case, we will grab the last argument as - // that's always the length. See - // CallArgs::AddFinalArgsAndDetermineABIInfo for where the - // handle is inserted. - for (CallArg& arg : call->gtArgs.Args()) - { - arrayLength = arg.GetNode(); - } + arrayLength = call->gtArgs.GetUserArgByIndex(1)->GetNode(); break; } @@ -2391,6 +2376,18 @@ bool GenTreeCall::IsHelperCall(Compiler* compiler, unsigned helper) const return IsHelperCall(compiler->eeFindHelper(helper)); } +//------------------------------------------------------------------------- +// GetHelperNum: Get the helper identifier for this call. +// +// Return Value: +// CORINFO_HELP_UNDEF if this call is not a helper call, appropriate +// CorInfoHelpFunc otherwise. +// +CorInfoHelpFunc GenTreeCall::GetHelperNum() const +{ + return IsHelperCall() ? Compiler::eeGetHelperNum(gtCallMethHnd) : CORINFO_HELP_UNDEF; +} + //-------------------------------------------------------------------------- // Equals: Check if 2 CALL nodes are equal. // @@ -2680,6 +2677,20 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) // these should be included in the comparison. switch (oper) { + case GT_STORE_LCL_FLD: + if ((op1->AsLclFld()->GetLclOffs() != op2->AsLclFld()->GetLclOffs()) || + (op1->AsLclFld()->GetLayout() != op2->AsLclFld()->GetLayout())) + { + return false; + } + FALLTHROUGH; + case GT_STORE_LCL_VAR: + if (op1->AsLclVarCommon()->GetLclNum() != op2->AsLclVarCommon()->GetLclNum()) + { + return false; + } + break; + case GT_ARR_LENGTH: if (op1->AsArrLen()->ArrLenOffset() != op2->AsArrLen()->ArrLenOffset()) { @@ -2728,9 +2739,8 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) } break; - case GT_FIELD: case GT_FIELD_ADDR: - if (op1->AsField()->gtFldHnd != op2->AsField()->gtFldHnd) + if (op1->AsFieldAddr()->gtFldHnd != op2->AsFieldAddr()->gtFldHnd) { return false; } @@ -2757,6 +2767,20 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) // these should be included in the hash code. switch (oper) { + case GT_STORE_BLK: + if (op1->AsBlk()->GetLayout() != op2->AsBlk()->GetLayout()) + { + return false; + } + FALLTHROUGH; + + case GT_STOREIND: + if ((op1->gtFlags & GTF_IND_FLAGS) != (op2->gtFlags & GTF_IND_FLAGS)) + { + return false; + } + break; + case GT_INTRINSIC: if (op1->AsIntrinsic()->gtIntrinsicName != op2->AsIntrinsic()->gtIntrinsicName) { @@ -2925,7 +2949,7 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) if (tree->OperIsLeaf()) { - if ((tree->OperIsLocal() || tree->OperIs(GT_LCL_ADDR)) && (tree->AsLclVarCommon()->GetLclNum() == lclNum)) + if (tree->OperIsAnyLocal() && (tree->AsLclVarCommon()->GetLclNum() == lclNum)) { return true; } @@ -2982,8 +3006,6 @@ bool Compiler::gtHasLocalsWithAddrOp(GenTree* tree) DoLclVarsOnly = true, }; - bool HasAddrTakenLocal = false; - LocalsWithAddrOpVisitor(Compiler* comp) : GenTreeVisitor(comp) { } @@ -2993,7 +3015,6 @@ bool Compiler::gtHasLocalsWithAddrOp(GenTree* tree) LclVarDsc* varDsc = m_compiler->lvaGetDesc((*use)->AsLclVarCommon()); if (varDsc->lvHasLdAddrOp || varDsc->IsAddressExposed()) { - HasAddrTakenLocal = true; return WALK_ABORT; } @@ -3002,8 +3023,48 @@ bool Compiler::gtHasLocalsWithAddrOp(GenTree* tree) }; LocalsWithAddrOpVisitor visitor(this); - visitor.WalkTree(&tree, nullptr); - return visitor.HasAddrTakenLocal; + return visitor.WalkTree(&tree, nullptr) == WALK_ABORT; +} + +//------------------------------------------------------------------------------ +// gtHasAddressExposedLocal: +// Check if this tree contains locals with IsAddressExposed() flags set. Does +// a full tree walk. +// +// Paramters: +// tree - the tree +// +// Return Value: +// True if any sub tree is such a local. +// +bool Compiler::gtHasAddressExposedLocals(GenTree* tree) +{ + struct Visitor : GenTreeVisitor + { + enum + { + DoPreOrder = true, + DoLclVarsOnly = true, + }; + + Visitor(Compiler* comp) : GenTreeVisitor(comp) + { + } + + fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) + { + LclVarDsc* varDsc = m_compiler->lvaGetDesc((*use)->AsLclVarCommon()); + if (varDsc->IsAddressExposed()) + { + return WALK_ABORT; + } + + return WALK_CONTINUE; + } + }; + + Visitor visitor(this); + return visitor.WalkTree(&tree, nullptr) == WALK_ABORT; } #ifdef DEBUG @@ -3191,6 +3252,17 @@ unsigned Compiler::gtHashValue(GenTree* tree) // these should be included in the hash code. switch (oper) { + case GT_STORE_LCL_VAR: + hash = genTreeHashAdd(hash, tree->AsLclVar()->GetLclNum()); + break; + case GT_STORE_LCL_FLD: + hash = genTreeHashAdd(hash, tree->AsLclFld()->GetLclNum()); + hash = genTreeHashAdd(hash, tree->AsLclFld()->GetLclOffs()); + hash = genTreeHashAdd(hash, tree->AsLclFld()->GetLayout()); + break; + case GT_STOREIND: + hash = genTreeHashAdd(hash, tree->AsStoreInd()->GetRMWStatus()); + break; case GT_ARR_LENGTH: hash += tree->AsArrLen()->ArrLenOffset(); break; @@ -3220,9 +3292,8 @@ unsigned Compiler::gtHashValue(GenTree* tree) static_cast(reinterpret_cast(tree->AsBlk()->GetLayout()))); break; - case GT_FIELD: case GT_FIELD_ADDR: - hash = genTreeHashAdd(hash, tree->AsField()->gtFldHnd); + hash = genTreeHashAdd(hash, tree->AsFieldAddr()->gtFldHnd); break; // For the ones below no extra argument matters for comparison. @@ -3528,13 +3599,10 @@ GenTree* Compiler::gtReverseCond(GenTree* tree) GenTreeCC* cc = tree->AsCC(); cc->gtCondition = GenCondition::Reverse(cc->gtCondition); } - else if (tree->OperIs(GT_JCMP)) + else if (tree->OperIs(GT_JCMP, GT_JTEST)) { - // Flip the GTF_JCMP_EQ - // On ARM64, this causes switching - // cbz <=> cbnz - // tbz <=> tbnz - tree->gtFlags ^= GTF_JCMP_EQ; + GenTreeOpCC* opCC = tree->AsOpCC(); + opCC->gtCondition = GenCondition::Reverse(opCC->gtCondition); } else { @@ -4043,7 +4111,7 @@ void Compiler::gtPrepareCost(GenTree* tree) bool Compiler::gtIsLikelyRegVar(GenTree* tree) { - if (tree->gtOper != GT_LCL_VAR) + if (!tree->OperIsScalarLocal()) { return false; } @@ -4086,6 +4154,176 @@ bool Compiler::gtIsLikelyRegVar(GenTree* tree) return true; } +//------------------------------------------------------------------------ +// gtGetLclVarNodeCost: Calculate the cost for a local variable node. +// +// Used for both uses and defs. Only the node's own cost is calculated. +// +// Arguments: +// node - The node in question +// pCostEx - [out] parameter for the execution cost +// pCostSz - [out] parameter for the size cost +// isLikelyRegVar - Is the local likely to end up enregistered +// +void Compiler::gtGetLclVarNodeCost(GenTreeLclVar* node, int* pCostEx, int* pCostSz, bool isLikelyRegVar) +{ + int costEx; + int costSz; + if (isLikelyRegVar) + { + costEx = 1; + costSz = 1; + /* Sign-extend and zero-extend are more expensive to load */ + if (lvaGetDesc(node)->lvNormalizeOnLoad()) + { + costEx += 1; + costSz += 1; + } + } + else + { + costEx = IND_COST_EX; + costSz = 2; + + // Some types are more expensive to load than others. + if (varTypeIsSmall(node)) + { + costEx += 1; + costSz += 1; + } + else if (node->TypeIs(TYP_STRUCT)) + { + costEx += 2 * IND_COST_EX; + costSz += 2 * 2; + } + } +#if defined(TARGET_AMD64) + // increase costSz for floating point locals + if (varTypeIsFloating(node)) + { + costSz += 1; + if (!isLikelyRegVar) + { + costSz += 1; + } + } +#endif + + *pCostEx = costEx; + *pCostSz = costSz; +} + +//------------------------------------------------------------------------ +// gtGetLclFldNodeCost: Calculate the cost for a local field node. +// +// Used for both uses and defs. Only the node's own cost is calculated. +// +// Arguments: +// node - The node in question +// pCostEx - [out] parameter for the execution cost +// pCostSz - [out] parameter for the size cost +// +void Compiler::gtGetLclFldNodeCost(GenTreeLclFld* node, int* pCostEx, int* pCostSz) +{ + int costEx = IND_COST_EX; + int costSz = 4; + if (varTypeIsSmall(node->TypeGet())) + { + costEx += 1; + costSz += 1; + } + else if (node->TypeIs(TYP_STRUCT)) + { + costEx += 2 * IND_COST_EX; + costSz += 2 * 2; + } + + *pCostEx = costEx; + *pCostSz = costSz; +} + +//------------------------------------------------------------------------ +// gtGetLclFldNodeCost: Calculate the cost for a primitive indir node. +// +// Used for both loads and stores. +// +// Arguments: +// node - The node in question +// pCostEx - [out] parameter for the execution cost +// pCostSz - [out] parameter for the size cost +// +// Return Value: +// Whether the cost calculated includes that of the node's address. +// +bool Compiler::gtGetIndNodeCost(GenTreeIndir* node, int* pCostEx, int* pCostSz) +{ + assert(node->isIndir()); + + // Indirections have a costEx of IND_COST_EX. + int costEx = IND_COST_EX; + int costSz = 2; + bool includesAddrCost = false; + + // If we have to sign-extend or zero-extend, bump the cost. + if (varTypeIsSmall(node)) + { + costEx += 1; + costSz += 1; + } + +#ifdef TARGET_ARM + if (varTypeIsFloating(node)) + { + costSz += 2; + } +#endif // TARGET_ARM + + // Can we form an addressing mode with this indirection? + GenTree* addr = node->Addr(); + + if (addr->gtEffectiveVal()->OperIs(GT_ADD)) + { + // See if we can form a complex addressing mode. + bool doAddrMode = true; + + // TODO-1stClassStructs: delete once IND nodes are no more. + if (node->TypeGet() == TYP_STRUCT) + { + doAddrMode = false; + } +#ifdef TARGET_ARM64 + if (node->IsVolatile()) + { + // For volatile store/loads when address is contained we always emit `dmb` + // if it's not - we emit one-way barriers i.e. ldar/stlr + doAddrMode = false; + } +#endif // TARGET_ARM64 + if (doAddrMode && gtMarkAddrMode(addr, &costEx, &costSz, node->TypeGet())) + { + includesAddrCost = true; + } + } + else if (gtIsLikelyRegVar(addr)) + { + // Indirection of an enregister LCL_VAR, don't increase costEx/costSz. + includesAddrCost = true; + } +#ifdef TARGET_XARCH + else if (addr->IsCnsIntOrI()) + { + // Indirection of a CNS_INT, subtract 1 from costEx makes costEx 3 for x86 and 4 for amd64. + costEx += (addr->GetCostEx() - 1); + costSz += addr->GetCostSz(); + includesAddrCost = true; + } +#endif + + *pCostEx = costEx; + *pCostSz = costSz; + return includesAddrCost; +} + //------------------------------------------------------------------------ // gtCanSwapOrder: Returns true iff the secondNode can be swapped with firstNode. // @@ -4978,61 +5216,12 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) case GT_LCL_VAR: level = 1; - if (gtIsLikelyRegVar(tree)) - { - costEx = 1; - costSz = 1; - /* Sign-extend and zero-extend are more expensive to load */ - if (lvaTable[tree->AsLclVar()->GetLclNum()].lvNormalizeOnLoad()) - { - costEx += 1; - costSz += 1; - } - } - else - { - costEx = IND_COST_EX; - costSz = 2; - - // Some types are more expensive to load than others. - if (varTypeIsSmall(tree->TypeGet())) - { - costEx += 1; - costSz += 1; - } - else if (tree->TypeIs(TYP_STRUCT)) - { - costEx += 2 * IND_COST_EX; - costSz += 2 * 2; - } - } -#if defined(TARGET_AMD64) - // increase costSz for floating point locals - if (isflt) - { - costSz += 1; - if (!gtIsLikelyRegVar(tree)) - { - costSz += 1; - } - } -#endif + gtGetLclVarNodeCost(tree->AsLclVar(), &costEx, &costSz, gtIsLikelyRegVar(tree)); break; case GT_LCL_FLD: - level = 1; - costEx = IND_COST_EX; - costSz = 4; - if (varTypeIsSmall(tree->TypeGet())) - { - costEx += 1; - costSz += 1; - } - else if (tree->TypeIs(TYP_STRUCT)) - { - costEx += 2 * IND_COST_EX; - costSz += 2 * 2; - } + level = 1; + gtGetLclFldNodeCost(tree->AsLclFld(), &costEx, &costSz); break; case GT_LCL_ADDR: @@ -5060,9 +5249,6 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) if (kind & GTK_SMPOP) { - int lvlb; // preference for op2 - unsigned lvl2; // scratch variable - GenTree* op1 = tree->AsOp()->gtOp1; GenTree* op2 = tree->gtGetOp2IfPresent(); @@ -5313,78 +5499,52 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) break; case GT_IND: - { - /* An indirection should always have a non-zero level. - * Only constant leaf nodes have level 0. - */ - + // An indirection should always have a non-zero level. + // Only constant leaf nodes have level 0. if (level == 0) { level = 1; } - /* Indirections have a costEx of IND_COST_EX */ - costEx = IND_COST_EX; - costSz = 2; - - /* If we have to sign-extend or zero-extend, bump the cost */ - if (varTypeIsSmall(tree->TypeGet())) + if (gtGetIndNodeCost(tree->AsIndir(), &costEx, &costSz)) { - costEx += 1; - costSz += 1; + goto DONE; } + break; -#ifdef TARGET_ARM - if (isflt) + case GT_STORE_LCL_VAR: + if (gtIsLikelyRegVar(tree)) { - costSz += 2; + // Store to an enregistered local. + costEx = op1->GetCostEx(); + costSz = max(3, op1->GetCostSz()); // 3 is an estimate for a reg-reg move. + goto DONE; } -#endif // TARGET_ARM - // Can we form an addressing mode with this indirection? - GenTree* addr = op1->gtEffectiveVal(); + gtGetLclVarNodeCost(tree->AsLclVar(), &costEx, &costSz, /* isLikelyRegVar */ false); + goto SET_LCL_STORE_COSTS; - if (addr->OperIs(GT_ADD)) - { - // See if we can form a complex addressing mode. - bool doAddrMode = true; + case GT_STORE_LCL_FLD: + gtGetLclFldNodeCost(tree->AsLclFld(), &costEx, &costSz); - // TODO-1stClassStructs: Always do this, but first make sure it's done in Lowering as well. - if (tree->TypeGet() == TYP_STRUCT) - { - doAddrMode = false; - } -#ifdef TARGET_ARM64 - if (tree->AsIndir()->IsVolatile()) - { - // For volatile store/loads when address is contained we always emit `dmb` - // if it's not - we emit one-way barriers i.e. ldar/stlr - doAddrMode = false; - } -#endif // TARGET_ARM64 - if (doAddrMode && gtMarkAddrMode(op1, &costEx, &costSz, tree->TypeGet())) - { - goto DONE; - } - } - else if (gtIsLikelyRegVar(op1)) + SET_LCL_STORE_COSTS: + costEx += 1; + costSz += 1; +#ifdef TARGET_ARM + if (isflt) { - /* Indirection of an enregister LCL_VAR, don't increase costEx/costSz */ - goto DONE; + costSz += 2; } -#ifdef TARGET_XARCH - else if (op1->IsCnsIntOrI()) +#endif // TARGET_ARM +#ifndef TARGET_64BIT + if (tree->TypeIs(TYP_LONG)) { - // Indirection of a CNS_INT, subtract 1 from costEx - // makes costEx 3 for x86 and 4 for amd64 - // - costEx += (op1->GetCostEx() - 1); - costSz += op1->GetCostSz(); - goto DONE; + // Operations on longs are more expensive. + costEx += 3; + costSz += 3; } -#endif - } - break; +#endif // !TARGET_64BIT + break; default: break; @@ -5395,8 +5555,9 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) } /* Binary operator - check for certain special cases */ - - lvlb = 0; + bool includeOp1Cost = true; + bool includeOp2Cost = true; + bool allowReversal = true; /* Default Binary ops have a cost of 1,1 */ costEx = 1; @@ -5416,6 +5577,9 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) costSz += 3; } #endif + level = gtSetEvalOrder(op1); + unsigned lvl2 = gtSetEvalOrder(op2); + switch (oper) { case GT_MOD: @@ -5451,7 +5615,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) costSz += 2; // Encourage the first operand to be evaluated (into EAX/EDX) first */ - lvlb -= 3; + level += 3; } break; @@ -5481,7 +5645,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) { /* We use imulEAX for TYP_LONG and overflow multiplications */ // Encourage the first operand to be evaluated (into EAX/EDX) first */ - lvlb -= 4; + level += 4; /* The 64-bit imul instruction costs more */ costEx += 4; @@ -5508,193 +5672,238 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) } break; - case GT_BOUNDS_CHECK: - costEx = 4; // cmp reg,reg and jae throw (not taken) - costSz = 7; // jump to cold section - break; - - case GT_COMMA: - - /* Comma tosses the result of the left operand */ - gtSetEvalOrder(op1); - level = gtSetEvalOrder(op2); + case GT_LSH: + case GT_RSH: + case GT_RSZ: + case GT_ROL: + case GT_ROR: + /* Variable sized shifts are more expensive and use REG_SHIFT */ - /* GT_COMMA cost is the sum of op1 and op2 costs */ - costEx = (op1->GetCostEx() + op2->GetCostEx()); - costSz = (op1->GetCostSz() + op2->GetCostSz()); + if (!op2->IsCnsIntOrI()) + { + costEx += 3; +#ifndef TARGET_64BIT + // Variable sized LONG shifts require the use of a helper call + // + if (tree->gtType == TYP_LONG) + { + level += 5; + lvl2 += 5; + costEx += 3 * IND_COST_EX; + costSz += 4; + } +#endif // !TARGET_64BIT + } + break; - goto DONE; + case GT_EQ: + case GT_NE: + case GT_LT: + case GT_LE: + case GT_GE: + case GT_GT: + /* Float compares remove both operands from the FP stack */ + /* Also FP comparison uses EAX for flags */ - case GT_INDEX_ADDR: - costEx = 6; // cmp reg,reg; jae throw; mov reg, [addrmode] (not taken) - costSz = 9; // jump to cold section + if (varTypeIsFloating(op1->TypeGet())) + { + level++; + lvl2++; + } + if ((tree->gtFlags & GTF_RELOP_JMP_USED) == 0) + { + /* Using a setcc instruction is more expensive */ + costEx += 3; + } break; - case GT_ASG: - /* Assignments need a bit of special handling */ - /* Process the target */ - level = gtSetEvalOrder(op1); + case GT_BOUNDS_CHECK: + costEx = 4; // cmp reg,reg and jae throw (not taken) + costSz = 7; // jump to cold section + // Bounds check nodes used to not be binary, thus GTF_REVERSE_OPS was not enabled for them. This + // condition preserves that behavior. Additionally, CQ analysis shows that enabling GTF_REVERSE_OPS + // for these nodes leads to mixed results at best. + allowReversal = false; + break; - if (gtIsLikelyRegVar(op1)) + case GT_INTRINSIC: + // We do not swap operand execution order for intrinsics that are implemented by user calls because + // of trickiness around ensuring the execution order does not change during rationalization. + if (IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicName)) { - assert(lvlb == 0); - lvl2 = gtSetEvalOrder(op2); - - /* Assignment to an enregistered LCL_VAR */ - costEx = op2->GetCostEx(); - costSz = max(3, op2->GetCostSz()); // 3 is an estimate for a reg-reg assignment - goto DONE_OP1_AFTER_COST; + allowReversal = false; } - goto DONE_OP1; - default: - break; - } + switch (tree->AsIntrinsic()->gtIntrinsicName) + { + case NI_System_Math_Atan2: + case NI_System_Math_Pow: + // These math intrinsics are actually implemented by user calls. Increase the + // Sethi 'complexity' by two to reflect the argument register requirement. + level += 2; + break; - /* Process the sub-operands */ + case NI_System_Math_Max: + case NI_System_Math_Min: + level++; + break; - level = gtSetEvalOrder(op1); - if (lvlb < 0) - { - level -= lvlb; // lvlb is negative, so this increases level - lvlb = 0; - } + default: + assert(!"Unknown binary GT_INTRINSIC operator"); + break; + } + break; - DONE_OP1: - assert(lvlb >= 0); - lvl2 = gtSetEvalOrder(op2) + lvlb; + case GT_COMMA: + /* Comma tosses the result of the left operand */ + level = lvl2; + /* GT_COMMA cost is the sum of op1 and op2 costs */ + costEx = (op1->GetCostEx() + op2->GetCostEx()); + costSz = (op1->GetCostSz() + op2->GetCostSz()); + goto DONE; - costEx += (op1->GetCostEx() + op2->GetCostEx()); - costSz += (op1->GetCostSz() + op2->GetCostSz()); + case GT_INDEX_ADDR: + costEx = 6; // cmp reg,reg; jae throw; mov reg, [addrmode] (not taken) + costSz = 9; // jump to cold section + break; - DONE_OP1_AFTER_COST: + case GT_STORE_BLK: + // We estimate the cost of a GT_STORE_BLK to be two stores. + costEx += 2 * IND_COST_EX; + costSz += 2 * 2; + goto SET_INDIRECT_STORE_ORDER; - bool bReverseInAssignment = false; - if (oper == GT_ASG && (!optValnumCSE_phase || optCSE_canSwap(op1, op2))) - { - switch (op1->OperGet()) - { - case GT_IND: - case GT_BLK: + case GT_STOREIND: + if (gtGetIndNodeCost(tree->AsIndir(), &costEx, &costSz)) { - // In an ASG(IND(addr), ...), the "IND" is a pure syntactical element, - // the actual indirection will only be realized at the point of the ASG - // itself. As such, we can discard any side effects "induced" by it in - // this logic. - // - GenTree* op1Addr = op1->AsIndir()->Addr(); + includeOp1Cost = false; + } + + costEx += 1; + costSz += 1; +#ifndef TARGET_64BIT + if (tree->TypeIs(TYP_LONG)) + { + // Operations on longs are more expensive. + costEx += 3; + costSz += 3; + } +#endif // !TARGET_64BIT - if (op1Addr->IsInvariant()) + SET_INDIRECT_STORE_ORDER: + // TODO-ASG-Cleanup: this logic emulates the ASG case below. See how of much of it can be deleted. + if (!optValnumCSE_phase || optCSE_canSwap(op1, op2)) + { + if (op1->IsInvariant()) { - bReverseInAssignment = true; - tree->gtFlags |= GTF_REVERSE_OPS; + allowReversal = false; + tree->SetReverseOp(); break; } - if (op1Addr->gtFlags & GTF_ALL_EFFECT) + if ((op1->gtFlags & GTF_ALL_EFFECT) != 0) { break; } // In case op2 assigns to a local var that is used in op1, we have to evaluate op1 first. - if (op2->gtFlags & GTF_ASG) + if ((op2->gtFlags & GTF_ASG) != 0) { + // TODO-ASG-Cleanup: move this guard to "gtCanSwapOrder". + allowReversal = false; break; } // If op2 is simple then evaluate op1 first - if (op2->OperKind() & GTK_LEAF) + if (op2->OperIsLeaf()) { break; } - } - // fall through and set GTF_REVERSE_OPS - FALLTHROUGH; - - case GT_LCL_VAR: - case GT_LCL_FLD: - // Note that for local stores, liveness depends on seeing the defs and - // uses in correct order, and so we MUST reverse the ASG in that case. - bReverseInAssignment = true; - tree->gtFlags |= GTF_REVERSE_OPS; - break; - - default: - break; - } - } - else if (GenTree::OperIsCompare(oper)) - { - /* Float compares remove both operands from the FP stack */ - /* Also FP comparison uses EAX for flags */ - if (varTypeIsFloating(op1->TypeGet())) - { - level++; - lvl2++; - } - if ((tree->gtFlags & GTF_RELOP_JMP_USED) == 0) - { - /* Using a setcc instruction is more expensive */ - costEx += 3; - } - } - - /* Check for other interesting cases */ - - switch (oper) - { - case GT_LSH: - case GT_RSH: - case GT_RSZ: - case GT_ROL: - case GT_ROR: - /* Variable sized shifts are more expensive and use REG_SHIFT */ - - if (!op2->IsCnsIntOrI()) - { - costEx += 3; -#ifndef TARGET_64BIT - // Variable sized LONG shifts require the use of a helper call - // - if (tree->gtType == TYP_LONG) - { - level += 5; - lvl2 += 5; - costEx += 3 * IND_COST_EX; - costSz += 4; - } -#endif // !TARGET_64BIT + allowReversal = false; + tree->SetReverseOp(); } break; - case GT_INTRINSIC: + case GT_ASG: + /* Assignments need a bit of special handling */ + if (gtIsLikelyRegVar(op1)) + { + /* Assignment to an enregistered LCL_VAR */ + costEx = op2->GetCostEx(); + costSz = max(3, op2->GetCostSz()); // 3 is an estimate for a reg-reg assignment + includeOp1Cost = false; + includeOp2Cost = false; + } - switch (tree->AsIntrinsic()->gtIntrinsicName) + if (!optValnumCSE_phase || optCSE_canSwap(op1, op2)) { - case NI_System_Math_Atan2: - case NI_System_Math_Pow: - // These math intrinsics are actually implemented by user calls. - // Increase the Sethi 'complexity' by two to reflect the argument - // register requirement. - level += 2; - break; + switch (op1->OperGet()) + { + case GT_IND: + case GT_BLK: + { + // In an ASG(IND(addr), ...), the "IND" is a pure syntactical element, + // the actual indirection will only be realized at the point of the ASG + // itself. As such, we can discard any side effects "induced" by it in + // this logic. + // + GenTree* op1Addr = op1->AsIndir()->Addr(); + + if (op1Addr->IsInvariant()) + { + allowReversal = false; + tree->gtFlags |= GTF_REVERSE_OPS; + break; + } + if (op1Addr->gtFlags & GTF_ALL_EFFECT) + { + break; + } - case NI_System_Math_Max: - case NI_System_Math_Min: - level++; - break; + // In case op2 assigns to a local var that is used in op1, we have to evaluate op1 first. + if (op2->gtFlags & GTF_ASG) + { + break; + } - default: - assert(!"Unknown binary GT_INTRINSIC operator"); - break; - } + // If op2 is simple then evaluate op1 first + if (op2->OperKind() & GTK_LEAF) + { + break; + } + } + // fall through and set GTF_REVERSE_OPS + FALLTHROUGH; + + case GT_LCL_VAR: + case GT_LCL_FLD: + // Note that for local stores, liveness depends on seeing the defs and + // uses in correct order, and so we MUST reverse the ASG in that case. + allowReversal = false; + tree->gtFlags |= GTF_REVERSE_OPS; + break; + default: + break; + } + } break; default: break; } + if (includeOp1Cost) + { + costEx += op1->GetCostEx(); + costSz += op1->GetCostSz(); + } + if (includeOp2Cost) + { + costEx += op2->GetCostEx(); + costSz += op2->GetCostSz(); + } + /* We need to evaluate constants later as many places in codegen can't handle op1 being a constant. This is normally naturally enforced as constants have the least level of 0. However, @@ -5708,50 +5917,12 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) lvl2++; } - /* We try to swap operands if the second one is more expensive */ - bool tryToSwap; - GenTree* opA; - GenTree* opB; - - if (tree->gtFlags & GTF_REVERSE_OPS) - { - opA = op2; - opB = op1; - } - else - { - opA = op1; - opB = op2; - } - - if (fgOrder == FGOrderLinear) - { - // Don't swap anything if we're in linear order; we're really just interested in the costs. - tryToSwap = false; - } - else if (bReverseInAssignment) + // We try to swap operands if the second one is more expensive. + // Don't swap anything if we're in linear order; we're really just interested in the costs. + bool tryToSwap = false; + if (allowReversal && (fgOrder != FGOrderLinear)) { - // Assignments are special, we want the reverseops flags - // so if possible it was set above. - tryToSwap = false; - } - else if ((oper == GT_INTRINSIC) && IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicName)) - { - // We do not swap operand execution order for intrinsics that are implemented by user calls - // because of trickiness around ensuring the execution order does not change during rationalization. - tryToSwap = false; - } - else if (oper == GT_BOUNDS_CHECK) - { - // Bounds check nodes used to not be binary, thus GTF_REVERSE_OPS was - // not enabled for them. This condition preserves that behavior. - // Additionally, CQ analysis shows that enabling GTF_REVERSE_OPS - // for these nodes leads to mixed results at best. - tryToSwap = false; - } - else - { - if (tree->gtFlags & GTF_REVERSE_OPS) + if (tree->IsReverseOp()) { tryToSwap = (level > lvl2); } @@ -5761,8 +5932,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) } // Try to force extra swapping when in the stress mode: - if (compStressCompile(STRESS_REVERSE_FLAG, 60) && ((tree->gtFlags & GTF_REVERSE_OPS) == 0) && - !op2->OperIsConst()) + if (compStressCompile(STRESS_REVERSE_FLAG, 60) && !tree->IsReverseOp() && !op2->OperIsConst()) { tryToSwap = true; } @@ -5770,7 +5940,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) if (tryToSwap) { - bool canSwap = gtCanSwapOrder(opA, opB); + bool canSwap = tree->IsReverseOp() ? gtCanSwapOrder(op2, op1) : gtCanSwapOrder(op1, op2); if (canSwap) { @@ -5810,30 +5980,17 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) break; default: - - /* Mark the operand's evaluation order to be swapped */ - if (tree->gtFlags & GTF_REVERSE_OPS) - { - tree->gtFlags &= ~GTF_REVERSE_OPS; - } - else - { - tree->gtFlags |= GTF_REVERSE_OPS; - } - + // Mark the operand's evaluation order to be swapped. + tree->gtFlags ^= GTF_REVERSE_OPS; break; } } } /* Swap the level counts */ - if (tree->gtFlags & GTF_REVERSE_OPS) + if (tree->IsReverseOp()) { - unsigned tmpl; - - tmpl = level; - level = lvl2; - lvl2 = tmpl; + std::swap(level, lvl2); } /* Compute the sethi number for this binary operator */ @@ -6580,26 +6737,37 @@ GenTree* GenTree::gtGetParent(GenTree*** pUse) 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)) + switch (OperGet()) { - return true; - } + case GT_STORE_LCL_VAR: + case GT_STORE_LCL_FLD: + case GT_STOREIND: + case GT_STORE_BLK: + case GT_STORE_DYN_BLK: + case GT_ASG: + case GT_XADD: + case GT_XORR: + case GT_XAND: + case GT_XCHG: + case GT_LOCKADD: + case GT_CMPXCHG: + case GT_MEMORYBARRIER: + return true; + + // If the call has return buffer argument, it produced a definition and hence + // should be marked with assignment. + case GT_CALL: + return AsCall()->IsOptimizingRetBufAsLocal(); #ifdef FEATURE_HW_INTRINSICS - if (gtOper == GT_HWINTRINSIC) - { - return AsHWIntrinsic()->OperRequiresAsgFlag(); - } + case GT_HWINTRINSIC: + return AsHWIntrinsic()->OperRequiresAsgFlag(); #endif // FEATURE_HW_INTRINSICS - if (gtOper == GT_CALL) - { - // If the call has return buffer argument, it produced a definition and hence - // should be marked with assignment. - return AsCall()->IsOptimizingRetBufAsLocal(); + default: + assert(!OperIsStore() && !OperIsAtomicOp()); + return false; } - return false; } //------------------------------------------------------------------------------ @@ -6648,6 +6816,21 @@ bool GenTree::OperRequiresCallFlag(Compiler* comp) } } +//------------------------------------------------------------------------ +// IndirMayFault: May this indirection-like node throw an NRE? +// +// Arguments: +// compiler - the compiler instance +// +// Return Value: +// Whether this node's address may be null. +// +bool GenTree::IndirMayFault(Compiler* compiler) +{ + assert(OperIsIndirOrArrMetaData()); + return ((gtFlags & GTF_IND_NONFAULTING) == 0) && compiler->fgAddrCouldBeNull(GetIndirOrArrMetaDataAddr()); +} + //------------------------------------------------------------------------------ // OperIsImplicitIndir : Check whether the operation contains an implicit indirection. // @@ -6712,6 +6895,16 @@ ExceptionSetFlags GenTree::OperExceptions(Compiler* comp) { switch (gtOper) { + case GT_ADD: + case GT_SUB: + case GT_MUL: + case GT_CAST: +#ifndef TARGET_64BIT + case GT_ADD_HI: + case GT_SUB_HI: +#endif // !TARGET_64BIT + return gtOverflow() ? ExceptionSetFlags::OverflowException : ExceptionSetFlags::None; + case GT_MOD: case GT_DIV: case GT_UMOD: @@ -6755,26 +6948,15 @@ ExceptionSetFlags GenTree::OperExceptions(Compiler* comp) return ExceptionSetFlags::All; case GT_IND: + case GT_STOREIND: case GT_BLK: case GT_NULLCHECK: case GT_STORE_BLK: case GT_STORE_DYN_BLK: - if (((this->gtFlags & GTF_IND_NONFAULTING) == 0) && comp->fgAddrCouldBeNull(this->AsIndir()->Addr())) - { - return ExceptionSetFlags::NullReferenceException; - } - - return ExceptionSetFlags::None; - case GT_ARR_LENGTH: case GT_MDARR_LENGTH: case GT_MDARR_LOWER_BOUND: - if (((this->gtFlags & GTF_IND_NONFAULTING) == 0) && comp->fgAddrCouldBeNull(this->AsArrCommon()->ArrRef())) - { - return ExceptionSetFlags::NullReferenceException; - } - - return ExceptionSetFlags::None; + return IndirMayFault(comp) ? ExceptionSetFlags::NullReferenceException : ExceptionSetFlags::None; case GT_ARR_ELEM: if (comp->fgAddrCouldBeNull(this->AsArrElem()->gtArrObj)) @@ -6784,9 +6966,8 @@ ExceptionSetFlags GenTree::OperExceptions(Compiler* comp) return ExceptionSetFlags::IndexOutOfRangeException; - case GT_FIELD: case GT_FIELD_ADDR: - if (AsField()->IsInstance() && comp->fgAddrCouldBeNull(AsField()->GetFldObj())) + if (AsFieldAddr()->IsInstance() && comp->fgAddrCouldBeNull(AsFieldAddr()->GetFldObj())) { return ExceptionSetFlags::NullReferenceException; } @@ -6794,9 +6975,11 @@ ExceptionSetFlags GenTree::OperExceptions(Compiler* comp) return ExceptionSetFlags::None; case GT_BOUNDS_CHECK: - case GT_INDEX_ADDR: return ExceptionSetFlags::IndexOutOfRangeException; + case GT_INDEX_ADDR: + return ExceptionSetFlags::NullReferenceException | ExceptionSetFlags::IndexOutOfRangeException; + case GT_ARR_INDEX: case GT_ARR_OFFSET: return ExceptionSetFlags::NullReferenceException; @@ -6827,11 +7010,7 @@ ExceptionSetFlags GenTree::OperExceptions(Compiler* comp) #endif // FEATURE_HW_INTRINSICS default: - if (gtOverflowEx()) - { - return ExceptionSetFlags::OverflowException; - } - + assert(!OperMayOverflow() && !OperIsIndirOrArrMetaData()); return ExceptionSetFlags::None; } } @@ -7149,12 +7328,8 @@ GenTreeFlags Compiler::gtTokenToIconFlags(unsigned token) GenTree* Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenTreeFlags iconFlags, bool isInvariant) { - GenTree* addrNode = gtNewIconHandleNode(addr, iconFlags); - GenTree* indNode = gtNewOperNode(GT_IND, indType, addrNode); - - // This indirection won't cause an exception. - // - indNode->gtFlags |= GTF_IND_NONFAULTING; + GenTree* addrNode = gtNewIconHandleNode(addr, iconFlags); + GenTreeFlags indirFlags = GTF_IND_NONFAULTING; // This indirection won't cause an exception. if (isInvariant) { @@ -7163,21 +7338,16 @@ GenTree* Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenT assert(iconFlags != GTF_ICON_GLOBAL_PTR); // Pointer to mutable data from the VM state // This indirection also is invariant. - indNode->gtFlags |= GTF_IND_INVARIANT; + indirFlags |= GTF_IND_INVARIANT; if (iconFlags == GTF_ICON_STR_HDL) { // String literals are never null - indNode->gtFlags |= GTF_IND_NONNULL; + indirFlags |= GTF_IND_NONNULL; } } - else - { - // GLOB_REF needs to be set for indirections returning values from mutable - // locations, so that e. g. args sorting does not reorder them with calls. - indNode->gtFlags |= GTF_GLOB_REF; - } + GenTree* indNode = gtNewIndir(indType, addrNode, indirFlags); return indNode; } @@ -7213,16 +7383,8 @@ GenTree* Compiler::gtNewIconEmbHndNode(void* value, void* pValue, GenTreeFlags i // use 'pValue' to construct an integer constant node iconNode = gtNewIconHandleNode((size_t)pValue, iconFlags); - // 'pValue' is an address of a location that contains the handle - - // construct the indirection of 'pValue' - handleNode = gtNewOperNode(GT_IND, TYP_I_IMPL, iconNode); - - // This indirection won't cause an exception. - handleNode->gtFlags |= GTF_IND_NONFAULTING; - - // This indirection also is invariant. - handleNode->gtFlags |= GTF_IND_INVARIANT; + // 'pValue' is an address of a location that contains the handle, construct the indirection of 'pValue'. + handleNode = gtNewIndir(TYP_I_IMPL, iconNode, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); } iconNode->gtCompileTimeHandle = (size_t)compileTimeHandle; @@ -7261,20 +7423,13 @@ GenTree* Compiler::gtNewStringLiteralNode(InfoAccessType iat, void* pValue) break; case IAT_PPVALUE: // The value needs to be accessed via a double indirection - // Create the first indirection + // Create the first indirection. tree = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pValue, GTF_ICON_CONST_PTR, true); #ifdef DEBUG tree->gtGetOp1()->AsIntCon()->gtTargetHandle = (size_t)pValue; #endif - - // Create the second indirection - tree = gtNewOperNode(GT_IND, TYP_REF, tree); - // This indirection won't cause an exception. - tree->gtFlags |= GTF_IND_NONFAULTING; - // String literal objects are also ok to model as invariant. - tree->gtFlags |= GTF_IND_INVARIANT; - // ..and they are never null. - tree->gtFlags |= GTF_IND_NONNULL; + // Create the second indirection. + tree = gtNewIndir(TYP_REF, tree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT | GTF_IND_NONNULL); break; default: @@ -7529,12 +7684,36 @@ GenTree* Compiler::gtNewOneConNode(var_types type, var_types simdBaseType /* = T } } -GenTreeLclVar* Compiler::gtNewStoreLclVar(unsigned dstLclNum, GenTree* src) +GenTreeLclVar* Compiler::gtNewStoreLclVarNode(unsigned lclNum, GenTree* data) +{ + LclVarDsc* varDsc = lvaGetDesc(lclNum); + var_types type = varDsc->lvNormalizeOnLoad() ? varDsc->TypeGet() : genActualType(varDsc); + GenTreeLclVar* store = new (this, GT_STORE_LCL_VAR) GenTreeLclVar(type, lclNum, data); + store->gtFlags |= (GTF_VAR_DEF | GTF_ASG); + if (varDsc->IsAddressExposed()) + { + store->gtFlags |= GTF_GLOB_REF; + } + + return store; +} + +GenTreeLclFld* Compiler::gtNewStoreLclFldNode(unsigned lclNum, var_types type, unsigned offset, GenTree* data) { - GenTreeLclVar* store = new (this, GT_STORE_LCL_VAR) GenTreeLclVar(GT_STORE_LCL_VAR, src->TypeGet(), dstLclNum); - store->gtOp1 = src; - store->gtFlags = (src->gtFlags & GTF_COMMON_MASK); - store->gtFlags |= GTF_VAR_DEF | GTF_ASG; + assert((genActualType(type) == genActualType(data)) || ((type == TYP_STRUCT) && data->TypeIs(TYP_INT))); + + ClassLayout* layout = (type == TYP_STRUCT) ? data->GetLayout(this) : nullptr; + GenTreeLclFld* store = new (this, GT_STORE_LCL_FLD) GenTreeLclFld(type, lclNum, offset, data, layout); + store->gtFlags |= (GTF_VAR_DEF | GTF_ASG); + if (store->IsPartialLclFld(this)) + { + store->gtFlags |= GTF_VAR_USEASG; + } + if (lvaGetDesc(lclNum)->IsAddressExposed()) + { + store->gtFlags |= GTF_GLOB_REF; + } + return store; } @@ -7660,6 +7839,23 @@ GenTreeLclVar* Compiler::gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL return node; } +GenTreeLclVar* Compiler::gtNewLclVarNode(unsigned lclNum, var_types type) +{ + LclVarDsc* varDsc = lvaGetDesc(lclNum); + if (type == TYP_UNDEF) + { + type = varDsc->lvNormalizeOnLoad() ? varDsc->TypeGet() : genActualType(varDsc); + } + + GenTreeLclVar* lclVar = gtNewLclvNode(lclNum, type); + if (varDsc->IsAddressExposed()) + { + lclVar->gtFlags |= GTF_GLOB_REF; + } + + return lclVar; +} + GenTreeLclVar* Compiler::gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSET offs)) { // We need to ensure that all struct values are normalized. @@ -7704,7 +7900,7 @@ GenTreeConditional* Compiler::gtNewConditionalNode( GenTreeLclFld* Compiler::gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset) { - GenTreeLclFld* node = new (this, GT_LCL_FLD) GenTreeLclFld(GT_LCL_FLD, type, lnum, offset); + GenTreeLclFld* node = new (this, GT_LCL_FLD) GenTreeLclFld(GT_LCL_FLD, type, lnum, offset, nullptr); return node; } @@ -7728,13 +7924,14 @@ GenTreeRetExpr* Compiler::gtNewInlineCandidateReturnExpr(GenTreeCall* inlineCand } //------------------------------------------------------------------------ -// gtNewFieldRef: Create a new GT_FIELD node. +// gtNewFieldAddrNode: Create a new GT_FIELD_ADDR node. // -// Normalizes struct types (for SIMD vectors). Sets GTF_GLOB_REF for fields -// that may be pointing into globally visible memory. +// TODO-ADDR: consider creating a variant of this which would skip various +// no-op constructs (such as struct fields with zero offsets), and fold +// others (LCL_VAR_ADDR + FIELD_ADDR => LCL_FLD_ADDR). // // Arguments: -// type - type for the field node +// type - type for the address node // fldHnd - the field handle // obj - the instance, an address // offset - the field offset @@ -7742,31 +7939,18 @@ GenTreeRetExpr* Compiler::gtNewInlineCandidateReturnExpr(GenTreeCall* inlineCand // Return Value: // The created node. // -GenTreeField* Compiler::gtNewFieldRef(var_types type, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj, DWORD offset) +GenTreeFieldAddr* Compiler::gtNewFieldAddrNode(var_types type, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj, DWORD offset) { - // GT_FIELD nodes are transformed into GT_IND nodes. - assert(GenTree::s_gtNodeSizes[GT_IND] <= GenTree::s_gtNodeSizes[GT_FIELD]); - - if (type == TYP_STRUCT) - { - CORINFO_CLASS_HANDLE structHnd; - eeGetFieldType(fldHnd, &structHnd); - type = impNormStructType(structHnd); - } + assert(varTypeIsI(genActualType(type))); - GenTreeField* fieldNode = new (this, GT_FIELD) GenTreeField(GT_FIELD, type, obj, fldHnd, offset); + GenTreeFieldAddr* fieldNode = new (this, GT_FIELD_ADDR) GenTreeFieldAddr(type, obj, fldHnd, offset); // If "obj" is the address of a local, note that a field of that struct local has been accessed. if ((obj != nullptr) && obj->IsLclVarAddr()) { - LclVarDsc* varDsc = lvaGetDesc(obj->AsLclVarCommon()); - + LclVarDsc* varDsc = lvaGetDesc(obj->AsLclVarCommon()); varDsc->lvFieldAccessed = 1; } - else - { - fieldNode->gtFlags |= GTF_GLOB_REF; - } if ((obj != nullptr) && fgAddrCouldBeNull(obj)) { @@ -7777,40 +7961,101 @@ GenTreeField* Compiler::gtNewFieldRef(var_types type, CORINFO_FIELD_HANDLE fldHn } //------------------------------------------------------------------------ -// gtNewFieldAddrNode: Create a new GT_FIELD_ADDR node. -// -// TODO-ADDR: consider creating a variant of this which would skip various -// no-op constructs (such as struct fields with zero offsets), and fold -// others (LCL_VAR_ADDR + FIELD_ADDR => LCL_FLD_ADDR). +// gtNewFieldIndirNode: Create a new field indirection node. // // Arguments: -// type - type for the address node -// fldHnd - the field handle -// obj - the instance, an address -// offset - the field offset +// type - Indirection's type +// layout - Indirection's struct layout +// add - The field address // // Return Value: // The created node. // -GenTreeField* Compiler::gtNewFieldAddrNode(var_types type, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj, DWORD offset) +// Notes: +// This method exists to preserve previous behavior. New code should +// use "gtNewIndir"/"gtNewBlkIndir" directly. +// +GenTreeIndir* Compiler::gtNewFieldIndirNode(var_types type, ClassLayout* layout, GenTreeFieldAddr* addr) { - assert(varTypeIsI(genActualType(type))); + GenTreeIndir* indir = (type == TYP_STRUCT) ? gtNewBlkIndir(layout, addr, GTF_IND_NONFAULTING) + : gtNewIndir(type, addr, GTF_IND_NONFAULTING); - GenTreeField* fieldNode = new (this, GT_FIELD_ADDR) GenTreeField(GT_FIELD_ADDR, type, obj, fldHnd, offset); - - // If "obj" is the address of a local, note that a field of that struct local has been accessed. - if ((obj != nullptr) && obj->IsLclVarAddr()) + if (addr->IsInstance() && addr->GetFldObj()->OperIs(GT_LCL_ADDR)) { - LclVarDsc* varDsc = lvaGetDesc(obj->AsLclVarCommon()); - varDsc->lvFieldAccessed = 1; + indir->gtFlags &= ~GTF_GLOB_REF; + } + else + { + indir->gtFlags |= GTF_GLOB_REF; } - if ((obj != nullptr) && fgAddrCouldBeNull(obj)) + addr->gtFlags |= GTF_FLD_DEREFERENCED; + + return indir; +} + +//------------------------------------------------------------------------ +// gtInitializeIndirNode: Initialize an indirection node. +// +// Sets side effect flags based on the passed-in indirection flags. +// +// Arguments: +// indir - The indirection node +// indirFlags - The indirection flags +// +void Compiler::gtInitializeIndirNode(GenTreeIndir* indir, GenTreeFlags indirFlags) +{ + assert((indirFlags & ~GTF_IND_FLAGS) == GTF_EMPTY); + indir->gtFlags |= indirFlags; + indir->SetIndirExceptionFlags(this); + + if ((indirFlags & GTF_IND_INVARIANT) == 0) { - fieldNode->gtFlags |= GTF_EXCEPT; + indir->gtFlags |= GTF_GLOB_REF; } + if ((indirFlags & GTF_IND_VOLATILE) != 0) + { + indir->gtFlags |= GTF_ORDER_SIDEEFF; + } +} - return fieldNode; +//------------------------------------------------------------------------ +// gtNewBlkIndir: Create a struct indirection node. +// +// Arguments: +// layout - The struct layout +// addr - Address of the indirection +// indirFlags - Indirection flags +// +// Return Value: +// The created GT_BLK node. +// +GenTreeBlk* Compiler::gtNewBlkIndir(ClassLayout* layout, GenTree* addr, GenTreeFlags indirFlags) +{ + assert(layout->GetType() == TYP_STRUCT); + GenTreeBlk* blkNode = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, addr, layout); + gtInitializeIndirNode(blkNode, indirFlags); + + return blkNode; +} + +//------------------------------------------------------------------------------ +// gtNewIndir : Create an indirection node. +// +// Arguments: +// typ - Type of the node +// addr - Address of the indirection +// indirFlags - Indirection flags +// +// Return Value: +// The created GT_IND node. +// +GenTreeIndir* Compiler::gtNewIndir(var_types typ, GenTree* addr, GenTreeFlags indirFlags) +{ + GenTreeIndir* indir = new (this, GT_IND) GenTreeIndir(GT_IND, typ, addr, nullptr); + gtInitializeIndirNode(indir, indirFlags); + + return indir; } //------------------------------------------------------------------------ @@ -7840,77 +8085,98 @@ GenTree* Compiler::gtNewLoadValueNode(var_types type, ClassLayout* layout, GenTr } } - GenTree* node; - if (type == TYP_STRUCT) - { - node = gtNewBlkIndir(layout, addr, indirFlags); - } - else - { - node = gtNewIndir(type, addr, indirFlags); - node->gtFlags |= GTF_GLOB_REF; - } - - return node; + return (type == TYP_STRUCT) ? gtNewBlkIndir(layout, addr, indirFlags) : gtNewIndir(type, addr, indirFlags); } -//------------------------------------------------------------------------ -// gtNewBlkIndir: Create a struct indirection node. +//------------------------------------------------------------------------------ +// gtNewStoreBlkNode : Create an indirect struct store node. // // Arguments: // layout - The struct layout -// addr - Address of the indirection +// addr - Destionation address +// data - Value to store // indirFlags - Indirection flags // // Return Value: -// The created GT_BLK node. +// The created GT_STORE_BLK node. // -GenTreeBlk* Compiler::gtNewBlkIndir(ClassLayout* layout, GenTree* addr, GenTreeFlags indirFlags) +GenTreeBlk* Compiler::gtNewStoreBlkNode(ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags) { - assert((indirFlags & ~GTF_IND_FLAGS) == GTF_EMPTY); + assert((indirFlags & GTF_IND_INVARIANT) == 0); + assert(data->IsInitVal() || ClassLayout::AreCompatible(layout, data->GetLayout(this))); - GenTreeBlk* blkNode = new (this, GT_BLK) GenTreeBlk(GT_BLK, layout->GetType(), addr, layout); - blkNode->gtFlags |= indirFlags; - blkNode->SetIndirExceptionFlags(this); + GenTreeBlk* store = new (this, GT_STORE_BLK) GenTreeBlk(GT_STORE_BLK, TYP_STRUCT, addr, data, layout); + store->gtFlags |= GTF_ASG; + gtInitializeIndirNode(store, indirFlags); - if ((indirFlags & GTF_IND_INVARIANT) == 0) - { - blkNode->gtFlags |= GTF_GLOB_REF; - } + return store; +} - if ((indirFlags & GTF_IND_VOLATILE) != 0) - { - blkNode->gtFlags |= GTF_ORDER_SIDEEFF; - } +//------------------------------------------------------------------------------ +// gtNewStoreIndNode : Create an indirect store node. +// +// Arguments: +// type - Type of the store +// addr - Destionation address +// data - Value to store +// indirFlags - Indirection flags +// +// Return Value: +// The created GT_STOREIND node. +// +GenTreeStoreInd* Compiler::gtNewStoreIndNode(var_types type, GenTree* addr, GenTree* data, GenTreeFlags indirFlags) +{ + assert((indirFlags & GTF_IND_INVARIANT) == 0); + assert((type != TYP_STRUCT) && (genActualType(type) == genActualType(data))); - return blkNode; + GenTreeStoreInd* store = new (this, GT_STOREIND) GenTreeStoreInd(type, addr, data); + store->gtFlags |= GTF_ASG; + gtInitializeIndirNode(store, indirFlags); + + return store; } -//------------------------------------------------------------------------------ -// gtNewIndir : Create an indirection node. +//------------------------------------------------------------------------ +// gtNewStoreValueNode: Return a node that represents a store. // // Arguments: -// typ - Type of the node -// addr - Address of the indirection +// type - Type to store +// layout - Struct layout for the store +// addr - Destination address +// data - Value to store // indirFlags - Indirection flags // // Return Value: -// The created GT_IND node. +// A "STORE_BLK/STORE_IND" node, or "STORE_LCL_VAR" if "addr" points to +// a compatible local. // -GenTreeIndir* Compiler::gtNewIndir(var_types typ, GenTree* addr, GenTreeFlags indirFlags) +GenTree* Compiler::gtNewStoreValueNode( + var_types type, ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags) { - assert((indirFlags & ~GTF_IND_FLAGS) == GTF_EMPTY); + assert((type != TYP_STRUCT) || (layout != nullptr)); - GenTree* indir = gtNewOperNode(GT_IND, typ, addr); - indir->gtFlags |= indirFlags; - indir->SetIndirExceptionFlags(this); + if (((indirFlags & GTF_IND_VOLATILE) == 0) && addr->IsLclVarAddr()) + { + unsigned lclNum = addr->AsLclFld()->GetLclNum(); + LclVarDsc* varDsc = lvaGetDesc(lclNum); + if ((varDsc->TypeGet() == type) && + ((type != TYP_STRUCT) || ClassLayout::AreCompatible(layout, varDsc->GetLayout()))) + { + return gtNewStoreLclVarNode(lclNum, data); + } + } - if ((indirFlags & GTF_IND_VOLATILE) != 0) + GenTree* store; + if (type == TYP_STRUCT) { - indir->gtFlags |= GTF_ORDER_SIDEEFF; + store = gtNewStoreBlkNode(layout, addr, data, indirFlags); + } + else + { + store = gtNewStoreIndNode(type, addr, data, indirFlags); } - return indir->AsIndir(); + return store; } /***************************************************************************** @@ -7920,7 +8186,7 @@ GenTreeIndir* Compiler::gtNewIndir(var_types typ, GenTree* addr, GenTreeFlags in GenTreeOp* Compiler::gtNewAssignNode(GenTree* dst, GenTree* src) { - assert(!src->TypeIs(TYP_VOID)); + assert(!src->TypeIs(TYP_VOID) && !compAssignmentRationalized); /* Mark the target as being assigned */ if ((dst->gtOper == GT_LCL_VAR) || (dst->OperGet() == GT_LCL_FLD)) @@ -8184,7 +8450,7 @@ void GenTreeOp::CheckDivideByConstOptimized(Compiler* comp) // GenTree* Compiler::gtNewBlkOpNode(GenTree* dst, GenTree* srcOrFillVal, bool isVolatile) { - assert(varTypeIsStruct(dst) && (dst->OperIsIndir() || dst->OperIsLocal() || dst->OperIs(GT_FIELD))); + assert(varTypeIsStruct(dst) && (dst->OperIsIndir() || dst->OperIsLocal())); bool isCopyBlock = srcOrFillVal->TypeGet() == dst->TypeGet(); if (!isCopyBlock) // InitBlk @@ -8475,29 +8741,28 @@ GenTree* Compiler::gtClone(GenTree* tree, bool complexOK) return nullptr; } - if (tree->OperIs(GT_FIELD)) + if (tree->OperIs(GT_IND, GT_BLK) && tree->AsIndir()->Addr()->OperIs(GT_FIELD_ADDR)) { - GenTree* objp = nullptr; + GenTree* objp = nullptr; + GenTreeFieldAddr* addr = tree->AsIndir()->Addr()->AsFieldAddr(); - if (tree->AsField()->GetFldObj() != nullptr) + if (addr->IsInstance()) { - objp = gtClone(tree->AsField()->GetFldObj(), false); + objp = gtClone(addr->GetFldObj(), false); if (objp == nullptr) { return nullptr; } } - copy = gtNewFieldRef(tree->TypeGet(), tree->AsField()->gtFldHnd, objp, tree->AsField()->gtFldOffset); - copy->AsField()->gtFldMayOverlap = tree->AsField()->gtFldMayOverlap; + copy = gtNewFieldAddrNode(addr->TypeGet(), addr->gtFldHnd, objp, addr->gtFldOffset); + copy->AsFieldAddr()->gtFldMayOverlap = addr->gtFldMayOverlap; + copy->AsFieldAddr()->SetIsSpanLength(addr->IsSpanLength()); #ifdef FEATURE_READYTORUN - copy->AsField()->gtFieldLookup = tree->AsField()->gtFieldLookup; + copy->AsFieldAddr()->gtFieldLookup = addr->gtFieldLookup; #endif - - if (tree->AsField()->IsSpanLength()) - { - copy->AsField()->SetIsSpanLength(true); - } + ClassLayout* layout = tree->OperIs(GT_BLK) ? tree->AsBlk()->GetLayout() : nullptr; + copy = gtNewFieldIndirNode(tree->TypeGet(), layout, copy->AsFieldAddr()); } else if (tree->OperIs(GT_ADD, GT_SUB)) { @@ -8714,6 +8979,17 @@ GenTree* Compiler::gtCloneExpr( switch (oper) { + case GT_STORE_LCL_VAR: + copy = new (this, GT_STORE_LCL_VAR) + GenTreeLclVar(tree->TypeGet(), tree->AsLclVar()->GetLclNum(), tree->AsLclVar()->Data()); + break; + + case GT_STORE_LCL_FLD: + copy = new (this, GT_STORE_LCL_FLD) + GenTreeLclFld(tree->TypeGet(), tree->AsLclFld()->GetLclNum(), tree->AsLclFld()->GetLclOffs(), + tree->AsLclFld()->Data(), tree->AsLclFld()->GetLayout()); + break; + /* These nodes sometimes get bashed to "fat" ones */ case GT_MUL: @@ -8784,6 +9060,17 @@ GenTree* Compiler::gtCloneExpr( } break; + case GT_STOREIND: + copy = new (this, GT_STOREIND) + GenTreeStoreInd(tree->TypeGet(), tree->AsIndir()->Addr(), tree->AsIndir()->Data()); + copy->AsStoreInd()->SetRMWStatus(tree->AsStoreInd()->GetRMWStatus()); + break; + + case GT_STORE_BLK: + copy = new (this, GT_STORE_BLK) GenTreeBlk(GT_STORE_BLK, tree->TypeGet(), tree->AsBlk()->Addr(), + tree->AsBlk()->Data(), tree->AsBlk()->GetLayout()); + break; + case GT_ARR_ADDR: copy = new (this, GT_ARR_ADDR) GenTreeArrAddr(tree->AsArrAddr()->Addr(), tree->AsArrAddr()->GetElemType(), @@ -8821,20 +9108,15 @@ GenTree* Compiler::gtCloneExpr( GenTreeBlk(GT_BLK, tree->TypeGet(), tree->AsBlk()->Addr(), tree->AsBlk()->GetLayout()); break; - case GT_FIELD: case GT_FIELD_ADDR: - copy = new (this, tree->OperGet()) - GenTreeField(tree->OperGet(), tree->TypeGet(), tree->AsField()->GetFldObj(), - tree->AsField()->gtFldHnd, tree->AsField()->gtFldOffset); - copy->AsField()->gtFldMayOverlap = tree->AsField()->gtFldMayOverlap; + copy = new (this, GT_FIELD_ADDR) + GenTreeFieldAddr(tree->TypeGet(), tree->AsFieldAddr()->GetFldObj(), tree->AsFieldAddr()->gtFldHnd, + tree->AsFieldAddr()->gtFldOffset); + copy->AsFieldAddr()->gtFldMayOverlap = tree->AsFieldAddr()->gtFldMayOverlap; #ifdef FEATURE_READYTORUN - copy->AsField()->gtFieldLookup = tree->AsField()->gtFieldLookup; + copy->AsFieldAddr()->gtFieldLookup = tree->AsFieldAddr()->gtFieldLookup; #endif - - if ((oper == GT_FIELD) && tree->AsField()->IsSpanLength()) - { - copy->AsField()->SetIsSpanLength(true); - } + copy->AsFieldAddr()->SetIsSpanLength(tree->AsFieldAddr()->IsSpanLength()); break; case GT_BOX: @@ -9620,7 +9902,6 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node) // Unary operators with an optional operand case GT_NOP: - case GT_FIELD: case GT_FIELD_ADDR: case GT_RETURN: case GT_RETFILT: @@ -10150,9 +10431,9 @@ bool GenTree::Precedes(GenTree* other) // void GenTree::SetIndirExceptionFlags(Compiler* comp) { - assert(OperIsIndirOrArrMetaData() && OperIsUnary()); + assert(OperIsIndirOrArrMetaData() && OperIsSimple()); - if (OperMayThrow(comp)) + if (IndirMayFault(comp)) { gtFlags |= GTF_EXCEPT; return; @@ -10163,6 +10444,10 @@ void GenTree::SetIndirExceptionFlags(Compiler* comp) gtFlags |= GTF_IND_NONFAULTING; gtFlags &= ~GTF_EXCEPT; gtFlags |= addr->gtFlags & GTF_EXCEPT; + if (OperIsBinary()) + { + gtFlags |= gtGetOp2()->gtFlags & GTF_EXCEPT; + } } #ifdef DEBUG @@ -10554,12 +10839,11 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_ /* First print the flags associated with the node */ switch (tree->gtOper) { - case GT_LEA: case GT_BLK: + case GT_IND: + case GT_STOREIND: case GT_STORE_BLK: case GT_STORE_DYN_BLK: - - case GT_IND: // We prefer printing V or U if ((tree->gtFlags & (GTF_IND_VOLATILE | GTF_IND_UNALIGNED)) == 0) { @@ -10575,6 +10859,12 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_ --msgLength; break; } + if (tree->gtFlags & GTF_IND_INITCLASS) + { + printf("I"); + --msgLength; + break; + } if (tree->gtFlags & GTF_IND_INVARIANT) { printf("#"); @@ -10602,21 +10892,6 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_ } FALLTHROUGH; - case GT_FIELD: - if (tree->gtFlags & GTF_IND_VOLATILE) - { - printf("V"); - --msgLength; - break; - } - if (tree->gtFlags & GTF_IND_UNALIGNED) - { - printf("U"); - --msgLength; - break; - } - goto DASH; - case GT_ASG: if (tree->OperIsInitBlkOp()) { @@ -10740,27 +11015,12 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_ } goto DASH; - case GT_JCMP: - printf((tree->gtFlags & GTF_JCMP_TST) ? "T" : "C"); - printf((tree->gtFlags & GTF_JCMP_EQ) ? "EQ" : "NE"); - goto DASH; - case GT_CNS_INT: if (tree->IsIconHandle()) { - if ((tree->gtFlags & GTF_ICON_INITCLASS) != 0) - { - printf("I"); // Static Field handle with INITCLASS requirement - --msgLength; - break; - } - else - { - // Some other handle - printf("H"); - --msgLength; - break; - } + printf("H"); + --msgLength; + break; } goto DASH; @@ -11807,8 +12067,8 @@ void Compiler::gtDispLeaf(GenTree* tree, IndentStack* indentStack) printf(" cond=%s", tree->AsCC()->gtCondition.Name()); break; case GT_JCMP: - printf(" cond=%s%s", (tree->gtFlags & GTF_JCMP_TST) ? "TEST_" : "", - (tree->gtFlags & GTF_JCMP_EQ) ? "EQ" : "NE"); + case GT_JTEST: + printf(" cond=%s", tree->AsOpCC()->gtCondition.Name()); break; default: @@ -12046,11 +12306,11 @@ void Compiler::gtDispTree(GenTree* tree, #endif // FEATURE_ARG_SPLIT #endif // FEATURE_PUT_STRUCT_ARG_STK - if (tree->OperIs(GT_FIELD, GT_FIELD_ADDR)) + if (tree->OperIs(GT_FIELD_ADDR)) { auto disp = [&]() { char buffer[256]; - printf(" %s", eeGetFieldName(tree->AsField()->gtFldHnd, true, buffer, sizeof(buffer))); + printf(" %s", eeGetFieldName(tree->AsFieldAddr()->gtFldHnd, true, buffer, sizeof(buffer))); }; disp(); } @@ -13219,8 +13479,6 @@ GenTree* Compiler::gtFoldExprConditional(GenTree* tree) DISPTREE(tree); assert(cond->TypeIs(TYP_INT)); - assert((tree->gtFlags & GTF_SIDE_EFFECT & ~GTF_ASG) == 0); - assert((tree->gtFlags & GTF_ORDER_SIDEEFF) == 0); GenTree* replacement = nullptr; if (cond->IsIntegralConst(0)) @@ -13298,47 +13556,6 @@ GenTree* Compiler::gtFoldExprConditional(GenTree* tree) return replacement; } -//------------------------------------------------------------------------ -// gtCreateHandleCompare: generate a type handle comparison -// -// Arguments: -// oper -- comparison operation (equal/not equal) -// op1 -- first operand -// op2 -- second operand -// typeCheckInliningResult -- indicates how the comparison should happen -// -// Returns: -// Type comparison tree -// - -GenTree* Compiler::gtCreateHandleCompare(genTreeOps oper, - GenTree* op1, - GenTree* op2, - CorInfoInlineTypeCheck typeCheckInliningResult) -{ - // If we can compare pointers directly, just emit the binary operation - if (typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS) - { - return gtNewOperNode(oper, TYP_INT, op1, op2); - } - - assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_USE_HELPER); - - // Emit a call to a runtime helper - GenTree* ret = gtNewHelperCallNode(CORINFO_HELP_ARE_TYPES_EQUIVALENT, TYP_INT, op1, op2); - if (oper == GT_EQ) - { - ret = gtNewOperNode(GT_NE, TYP_INT, ret, gtNewIconNode(0, TYP_INT)); - } - else - { - assert(oper == GT_NE); - ret = gtNewOperNode(GT_EQ, TYP_INT, ret, gtNewIconNode(0, TYP_INT)); - } - - return ret; -} - //------------------------------------------------------------------------ // gtFoldTypeCompare: see if a type comparison can be further simplified // @@ -13451,9 +13668,9 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) inliningKind = info.compCompHnd->canInlineTypeCheck(cls2Hnd, CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN); } - assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS || inliningKind == CORINFO_INLINE_TYPECHECK_USE_HELPER); + assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS); - GenTree* compare = gtCreateHandleCompare(oper, op1ClassFromHandle, op2ClassFromHandle, inliningKind); + GenTree* compare = gtNewOperNode(oper, TYP_INT, op1ClassFromHandle, op2ClassFromHandle); // Drop any now-irrelevant flags compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE); @@ -13489,11 +13706,10 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) arg2 = gtNewMethodTableLookup(arg2); - CorInfoInlineTypeCheck inliningKind = - info.compCompHnd->canInlineTypeCheck(nullptr, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE); - assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS || inliningKind == CORINFO_INLINE_TYPECHECK_USE_HELPER); + assert(info.compCompHnd->canInlineTypeCheck(nullptr, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) == + CORINFO_INLINE_TYPECHECK_PASS); - GenTree* compare = gtCreateHandleCompare(oper, arg1, arg2, inliningKind); + GenTree* compare = gtNewOperNode(oper, TYP_INT, arg1, arg2); // Drop any now-irrelevant flags compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE); @@ -13591,7 +13807,8 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) GenTree* const objMT = gtNewMethodTableLookup(objOp); // Compare the two method tables - GenTree* const compare = gtCreateHandleCompare(oper, objMT, knownMT, typeCheckInliningResult); + assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS); + GenTree* const compare = gtNewOperNode(oper, TYP_INT, objMT, knownMT); // Drop any now irrelevant flags compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE); @@ -14097,20 +14314,17 @@ GenTree* Compiler::gtFoldBoxNullable(GenTree* tree) JITDUMP("\nReplacing BOX_NULLABLE(&x) %s null [%06u] with x.hasValue\n", GenTree::OpName(oper), dspTreeID(tree)); - GenTree* nullableHndNode = call->gtArgs.GetArgByIndex(0)->GetNode(); - CORINFO_CLASS_HANDLE nullableClassHnd = gtGetHelperArgClassHandle(nullableHndNode); - CORINFO_FIELD_HANDLE hasValueFieldHnd = info.compCompHnd->getFieldInClass(nullableClassHnd, 0); - - GenTree* srcAddr = call->gtArgs.GetArgByIndex(1)->GetNode(); - GenTree* fieldNode = gtNewFieldRef(TYP_BOOL, hasValueFieldHnd, srcAddr, OFFSETOF__CORINFO_NullableOfT__hasValue); + static_assert_no_msg(OFFSETOF__CORINFO_NullableOfT__hasValue == 0); + GenTree* srcAddr = call->gtArgs.GetArgByIndex(1)->GetNode(); + GenTree* hasValueNode = gtNewIndir(TYP_BOOL, srcAddr); if (op == op1) { - tree->AsOp()->gtOp1 = fieldNode; + tree->AsOp()->gtOp1 = hasValueNode; } else { - tree->AsOp()->gtOp2 = fieldNode; + tree->AsOp()->gtOp2 = hasValueNode; } cons->gtType = TYP_INT; @@ -14338,7 +14552,7 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions { isStructCopy = true; - if ((copySrc->gtOper != GT_BLK) && (copySrc->gtOper != GT_IND) && (copySrc->gtOper != GT_FIELD)) + if (!copySrc->OperIs(GT_IND, GT_BLK)) { // We don't know how to handle other cases, yet. JITDUMP(" bailing; unexpected copy source struct op with side effect %s\n", @@ -14387,10 +14601,9 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions } else { - // For struct types read the first byte of the - // source struct; there's no need to read the - // entire thing, and no place to put it. - assert(copySrc->OperIs(GT_BLK, GT_IND, GT_FIELD)); + // For struct types read the first byte of the source struct; there's + // no need to read the entire thing, and no place to put it. + assert(copySrc->OperIs(GT_BLK, GT_IND)); copyStmt->SetRootNode(copySrc); if (options == BR_REMOVE_AND_NARROW || options == BR_REMOVE_AND_NARROW_WANT_TYPE_HANDLE) @@ -14619,17 +14832,10 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree) return tree; } - if (tree->OperIs(GT_NOP, GT_ALLOCOBJ, GT_RUNTIMELOOKUP)) - { - return tree; - } - -#ifdef FEATURE_HW_INTRINSICS - if (tree->OperIs(GT_HWINTRINSIC)) + if (tree->OperIs(GT_NOP, GT_ALLOCOBJ, GT_RUNTIMELOOKUP) || tree->OperIsStore() || tree->OperIsHWIntrinsic()) { return tree; } -#endif if (tree->OperIsUnary()) { @@ -15781,7 +15987,7 @@ GenTree* Compiler::gtFoldIndirConst(GenTreeIndir* indir) // May update the type of the temp, if it was previously unknown. // // May set compFloatingPointUsed. - +// GenTree* Compiler::gtNewTempAssign( unsigned tmp, GenTree* val, Statement** pAfterStmt, const DebugInfo& di, BasicBlock* block) { @@ -15868,31 +16074,21 @@ GenTree* Compiler::gtNewTempAssign( compFloatingPointUsed = true; } - /* Create the assignment node */ - - GenTree* asg; - GenTree* dest = gtNewLclvNode(tmp, dstTyp); - - if (val->IsInitVal()) + GenTree* store; + if (compAssignmentRationalized) { - asg = gtNewAssignNode(dest, val); + store = gtNewStoreLclVarNode(tmp, val); } - else if (varTypeIsStruct(varDsc)) + else if (varTypeIsStruct(varDsc) && !val->IsInitVal()) { - asg = impAssignStruct(dest, val, CHECK_SPILL_NONE, pAfterStmt, di, block); + store = impAssignStruct(gtNewLclvNode(tmp, dstTyp), val, CHECK_SPILL_NONE, pAfterStmt, di, block); } else { - assert(!varTypeIsStruct(valTyp)); - asg = gtNewAssignNode(dest, val); - } - - if (compRationalIRForm) - { - Rationalizer::RewriteAssignmentIntoStoreLcl(asg->AsOp()); + store = gtNewAssignNode(gtNewLclvNode(tmp, dstTyp), val); } - return asg; + return store; } /***************************************************************************** @@ -16004,7 +16200,7 @@ GenTree* Compiler::gtNewRefCOMfield(GenTree* objPtr, { // get the result as primitive type result = impGetStructAddr(result, structType, CHECK_SPILL_ALL, true); - result = gtNewOperNode(GT_IND, lclTyp, result); + result = gtNewIndir(lclTyp, result); } } else if (varTypeIsIntegral(lclTyp) && genTypeSize(lclTyp) < genTypeSize(TYP_INT)) @@ -16021,15 +16217,7 @@ GenTree* Compiler::gtNewRefCOMfield(GenTree* objPtr, { ClassLayout* layout; lclTyp = TypeHandleToVarType(pFieldInfo->fieldType, structType, &layout); - if (lclTyp == TYP_STRUCT) - { - result = gtNewBlkIndir(layout, result); - } - else - { - result = gtNewOperNode(GT_IND, lclTyp, result); - } - result->gtFlags |= (GTF_EXCEPT | GTF_GLOB_REF); + result = (lclTyp == TYP_STRUCT) ? gtNewBlkIndir(layout, result) : gtNewIndir(lclTyp, result); } else if (access & CORINFO_ACCESS_SET) { @@ -16039,8 +16227,7 @@ GenTree* Compiler::gtNewRefCOMfield(GenTree* objPtr, } else { - result = gtNewOperNode(GT_IND, lclTyp, result); - result->gtFlags |= (GTF_EXCEPT | GTF_GLOB_REF); + result = gtNewIndir(lclTyp, result); result = gtNewAssignNode(result, assg); } } @@ -16063,14 +16250,7 @@ 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 - // (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->OperRequiresAsgFlag()) { return true; } @@ -16117,6 +16297,17 @@ bool Compiler::gtNodeHasSideEffects(GenTree* tree, GenTreeFlags flags) { return true; } + + // TODO-FIELD: delete this zero-diff quirk. + if (tree->OperIsIndir() && tree->AsIndir()->Addr()->OperIs(GT_FIELD_ADDR)) + { + GenTreeFieldAddr* addr = tree->AsIndir()->Addr()->AsFieldAddr(); + if (addr->IsInstance() && ((addr->gtFlags & GTF_FLD_DEREFERENCED) != 0) && + fgAddrCouldBeNull(addr->GetFldObj())) + { + return true; + } + } } // Expressions declared as CSE by (e.g.) hoisting code are considered to have relevant side @@ -16353,7 +16544,17 @@ bool Compiler::gtSplitTree( bool IsValue(const UseInfo& useInf) { - GenTree* node = (*useInf.Use)->gtEffectiveVal(); + GenTree* node = *useInf.Use; + + // Some places create void-typed commas that wrap actual values + // (e.g. VN-based dead store removal), so we need the double check + // here. + if (!node->IsValue()) + { + return false; + } + + node = node->gtEffectiveVal(); if (!node->IsValue()) { return false; @@ -16556,34 +16757,10 @@ void Compiler::gtExtractSideEffList(GenTree* expr, { if (node->OperIsBlk() && !node->OperIsStoreBlk()) { - // Check for a guaranteed non-faulting IND, and create a NOP node instead of a NULLCHECK in that - // case. - if (m_compiler->fgAddrCouldBeNull(node->AsBlk()->Addr())) - { - Append(node); - JITDUMP("Replace an unused OBJ/BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); - m_compiler->gtChangeOperToNullCheck(node, m_compiler->compCurBB); - } - else - { - JITDUMP("Dropping non-faulting OBJ/BLK node [%06d]\n", dspTreeID(node)); - } - } - else - { - Append(node); + JITDUMP("Replace an unused BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); + m_compiler->gtChangeOperToNullCheck(node, m_compiler->compCurBB); } - return Compiler::WALK_SKIP_SUBTREES; - } - // TODO-Cleanup: These have GTF_ASG set but for some reason gtNodeHasSideEffects ignores - // them. See the related gtNodeHasSideEffects comment as well. - // Also, these nodes must always be preserved, no matter what side effect flags are passed - // in. But then it should never be the case that gtExtractSideEffList gets called without - // specifying GTF_ASG so there doesn't seem to be any reason to be inconsistent with - // gtNodeHasSideEffects and make this check unconditionally. - if (node->OperIsAtomicOp()) - { Append(node); return Compiler::WALK_SKIP_SUBTREES; } @@ -17162,9 +17339,15 @@ bool GenTree::IsPhiNode() bool GenTree::IsPhiDefn() { - bool res = OperIs(GT_ASG) && AsOp()->gtOp2->OperIs(GT_PHI); - assert(!res || AsOp()->gtOp1->OperIs(GT_LCL_VAR)); - return res; + if (OperIs(GT_ASG)) + { + return AsOp()->gtOp2->OperIs(GT_PHI); + } + if (OperIs(GT_STORE_LCL_VAR)) + { + return AsLclVar()->Data()->OperIs(GT_PHI); + } + return false; } bool GenTree::IsLclVarAddr() const @@ -17747,7 +17930,7 @@ unsigned GenTreeVecCon::ElementCount(unsigned simdSize, var_types simdBaseType) // field, or to "nullptr", in which case the handle for the field is the primary // selector. 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". +// is added, see "impImportStaticFieldAccess" and "fgMorphFieldAddr". // bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeq** pFldSeq, ssize_t* pOffset) { @@ -17940,19 +18123,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b break; } - case GT_FIELD: - { - // For fields, get the type from the field handle. - CORINFO_FIELD_HANDLE fieldHnd = obj->AsField()->gtFldHnd; - - if (fieldHnd != nullptr) - { - objClass = gtGetFieldClassHandle(fieldHnd, pIsExact, pIsNonNull); - } - - break; - } - case GT_CNS_INT: { if (tree->IsIconHandle(GTF_ICON_OBJ_HDL)) @@ -18167,6 +18337,10 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = gtGetFieldClassHandle(fldHandle, pIsExact, pIsNonNull); } } + else if (base->OperIs(GT_FIELD_ADDR)) + { + objClass = gtGetFieldClassHandle(base->AsFieldAddr()->gtFldHnd, pIsExact, pIsNonNull); + } break; } @@ -18301,6 +18475,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetHelperCallClassHandle(GenTreeCall* call, boo } case CORINFO_HELP_NEWARR_1_DIRECT: + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: @@ -19061,6 +19236,18 @@ bool GenTree::isContainableHWIntrinsic() const return true; } + case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32WithSaturation: + { + if (varTypeIsFloating(AsHWIntrinsic()->GetSimdBaseType())) + { + return false; + } + FALLTHROUGH; + } + case NI_Vector128_GetElement: case NI_SSE2_ConvertToInt32: case NI_SSE2_ConvertToUInt32: @@ -19075,18 +19262,40 @@ bool GenTree::isContainableHWIntrinsic() const case NI_AVX2_ExtractVector128: case NI_AVX512F_ExtractVector128: case NI_AVX512F_ExtractVector256: + case NI_AVX512F_ConvertToVector128Byte: + case NI_AVX512F_ConvertToVector128ByteWithSaturation: case NI_AVX512F_ConvertToVector128Int16: - case NI_AVX512F_ConvertToVector128Int32: + case NI_AVX512F_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector128SByteWithSaturation: case NI_AVX512F_ConvertToVector128UInt16: - case NI_AVX512F_ConvertToVector128UInt32: + case NI_AVX512F_ConvertToVector128UInt16WithSaturation: case NI_AVX512F_ConvertToVector256Int16: - case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256Int16WithSaturation: + case NI_AVX512F_ConvertToVector256Int32WithSaturation: case NI_AVX512F_ConvertToVector256UInt16: - case NI_AVX512F_ConvertToVector256UInt32: - case NI_AVX512BW_ConvertToVector128Byte: - case NI_AVX512BW_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector256UInt16WithSaturation: + case NI_AVX512F_ConvertToVector256UInt32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Byte: + case NI_AVX512F_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int16: + case NI_AVX512F_VL_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int32: + case NI_AVX512F_VL_ConvertToVector128Int32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128SByte: + case NI_AVX512F_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128UInt16: + case NI_AVX512F_VL_ConvertToVector128UInt16WithSaturation: case NI_AVX512BW_ConvertToVector256Byte: + case NI_AVX512BW_ConvertToVector256ByteWithSaturation: case NI_AVX512BW_ConvertToVector256SByte: + case NI_AVX512BW_ConvertToVector256SByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128Byte: + case NI_AVX512BW_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128SByte: + case NI_AVX512BW_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512DQ_ExtractVector128: + case NI_AVX512DQ_ExtractVector256: { // These HWIntrinsic operations are contained as part of a store return true; @@ -19123,15 +19332,24 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp) assert(comp != nullptr); #if defined(TARGET_XARCH) + GenTreeHWIntrinsic* hwintrinsic = AsHWIntrinsic(); + NamedIntrinsic intrinsicId = hwintrinsic->GetHWIntrinsicId(); + if (!comp->canUseVexEncoding()) { - return HWIntrinsicInfo::HasRMWSemantics(AsHWIntrinsic()->GetHWIntrinsicId()); + return HWIntrinsicInfo::HasRMWSemantics(intrinsicId); } - switch (AsHWIntrinsic()->GetHWIntrinsicId()) + switch (intrinsicId) { // TODO-XArch-Cleanup: Move this switch block to be table driven. + case NI_AVX512F_FusedMultiplyAdd: + case NI_AVX512F_FusedMultiplyAddNegated: + case NI_AVX512F_FusedMultiplyAddSubtract: + case NI_AVX512F_FusedMultiplySubtract: + case NI_AVX512F_FusedMultiplySubtractAdd: + case NI_AVX512F_FusedMultiplySubtractNegated: case NI_SSE42_Crc32: case NI_SSE42_X64_Crc32: case NI_FMA_MultiplyAdd: @@ -19150,6 +19368,50 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp) return true; } + case NI_AVX512F_Fixup: + case NI_AVX512F_FixupScalar: + case NI_AVX512F_VL_Fixup: + { + // We are actually only RMW in the case where the lookup table + // has any value that could result in `op1` being picked. So + // in the case `op3` is a constant and none of the nibbles are + // `0`, then we don't have to be RMW and can actually "drop" `op1` + + GenTree* op3 = hwintrinsic->Op(3); + + if (!op3->IsCnsVec()) + { + return true; + } + + GenTreeVecCon* vecCon = op3->AsVecCon(); + + var_types simdBaseType = hwintrinsic->GetSimdBaseType(); + unsigned simdSize = hwintrinsic->GetSimdSize(); + uint32_t count = simdSize / sizeof(uint32_t); + uint32_t incSize = (simdBaseType == TYP_FLOAT) ? 1 : 2; + + if (intrinsicId == NI_AVX512F_FixupScalar) + { + // Upper elements come from op2 + count = 1; + } + + for (uint32_t i = 0; i < count; i += incSize) + { + uint32_t tbl = vecCon->gtSimdVal.u32[i]; + + if (((tbl & 0x0000000F) == 0) || ((tbl & 0x000000F0) == 0) || ((tbl & 0x00000F00) == 0) || + ((tbl & 0x0000F000) == 0) || ((tbl & 0x000F0000) == 0) || ((tbl & 0x00F00000) == 0) || + ((tbl & 0x0F000000) == 0) || ((tbl & 0xF0000000) == 0)) + { + return true; + } + } + + return false; + } + default: { return false; @@ -19338,7 +19600,12 @@ GenTree* Compiler::gtNewSimdAbsNode(var_types type, GenTree* op1, CorInfoType si if (simdBaseType == TYP_LONG) { - if (compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) + if (simdSize == 64) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + intrinsic = NI_AVX512F_Abs; + } + else if (compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) { intrinsic = NI_AVX512F_VL_Abs; } @@ -19348,6 +19615,20 @@ GenTree* Compiler::gtNewSimdAbsNode(var_types type, GenTree* op1, CorInfoType si assert(compIsaSupportedDebugOnly(InstructionSet_AVX2)); intrinsic = NI_AVX2_Abs; } + else if (simdSize == 64) + { + if (simdBaseType == TYP_INT) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + intrinsic = NI_AVX512F_Abs; + } + else + { + assert(varTypeIsSmall(simdBaseType)); + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512BW)); + intrinsic = NI_AVX512BW_Abs; + } + } else if (compOpportunisticallyDependsOn(InstructionSet_SSSE3)) { intrinsic = NI_SSSE3_Abs; @@ -20348,6 +20629,12 @@ GenTree* Compiler::gtNewSimdCeilNode(var_types type, GenTree* op1, CorInfoType s assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); intrinsic = NI_AVX_Ceiling; } + else if (simdSize == 64) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + GenTree* op2 = gtNewIconNode(static_cast(FloatRoundingMode::ToPositiveInfinity)); + return gtNewSimdHWIntrinsicNode(type, op1, op2, NI_AVX512F_RoundScale, simdBaseJitType, simdSize); + } else { assert(compIsaSupportedDebugOnly(InstructionSet_SSE41)); @@ -21914,6 +22201,12 @@ GenTree* Compiler::gtNewSimdFloorNode(var_types type, GenTree* op1, CorInfoType { intrinsic = NI_AVX_Floor; } + else if (simdSize == 64) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + GenTree* op2 = gtNewIconNode(static_cast(FloatRoundingMode::ToNegativeInfinity)); + return gtNewSimdHWIntrinsicNode(type, op1, op2, NI_AVX512F_RoundScale, simdBaseJitType, simdSize); + } else { assert(compIsaSupportedDebugOnly(InstructionSet_SSE41)); @@ -22288,6 +22581,19 @@ GenTree* Compiler::gtNewSimdMaxNode( } } } + else if (simdSize == 64) + { + if (varTypeIsSmall(simdBaseType)) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512BW)); + intrinsic = NI_AVX512BW_Max; + } + else + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + intrinsic = NI_AVX512F_Max; + } + } else { switch (simdBaseType) @@ -22482,6 +22788,19 @@ GenTree* Compiler::gtNewSimdMinNode( } } } + else if (simdSize == 64) + { + if (varTypeIsSmall(simdBaseType)) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512BW)); + intrinsic = NI_AVX512BW_Min; + } + else + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + intrinsic = NI_AVX512F_Min; + } + } else { switch (simdBaseType) @@ -22675,7 +22994,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( } else { - intrinsicId = NI_AVX512BW_ConvertToVector128SByte; + intrinsicId = NI_AVX512BW_VL_ConvertToVector128SByte; } opBaseJitType = CORINFO_TYPE_SHORT; @@ -22690,7 +23009,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( } else { - intrinsicId = NI_AVX512BW_ConvertToVector128Byte; + intrinsicId = NI_AVX512BW_VL_ConvertToVector128Byte; } opBaseJitType = CORINFO_TYPE_USHORT; @@ -22705,7 +23024,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( } else { - intrinsicId = NI_AVX512F_ConvertToVector128Int16; + intrinsicId = NI_AVX512F_VL_ConvertToVector128Int16; } opBaseJitType = CORINFO_TYPE_INT; @@ -22720,7 +23039,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( } else { - intrinsicId = NI_AVX512F_ConvertToVector128UInt16; + intrinsicId = NI_AVX512F_VL_ConvertToVector128UInt16; } opBaseJitType = CORINFO_TYPE_UINT; @@ -22735,7 +23054,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( } else { - intrinsicId = NI_AVX512F_ConvertToVector128Int32; + intrinsicId = NI_AVX512F_VL_ConvertToVector128Int32; } opBaseJitType = CORINFO_TYPE_LONG; @@ -22750,7 +23069,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( } else { - intrinsicId = NI_AVX512F_ConvertToVector128UInt32; + intrinsicId = NI_AVX512F_VL_ConvertToVector128UInt32; } opBaseJitType = CORINFO_TYPE_ULONG; @@ -23176,7 +23495,7 @@ GenTree* Compiler::gtNewSimdShuffleNode( #if defined(TARGET_XARCH) uint8_t control = 0; bool crossLane = false; - bool needsZero = varTypeIsSmallInt(simdBaseType); + bool needsZero = varTypeIsSmallInt(simdBaseType) && (simdSize != 64); uint64_t value = 0; simd_t vecCns = {}; simd_t mskCns = {}; @@ -23310,6 +23629,61 @@ GenTree* Compiler::gtNewSimdShuffleNode( retNode = gtNewSimdHWIntrinsicNode(type, op1, cnsNode, NI_AVX2_Permute4x64, simdBaseJitType, simdSize); } } + else if (simdSize == 64) + { + if (elementSize == 4) + { + for (uint32_t i = 0; i < elementCount; i++) + { + vecCns.u32[i] = (uint8_t)(vecCns.u8[i * elementSize] / elementSize); + } + + op2 = gtNewVconNode(type); + op2->AsVecCon()->gtSimdVal = vecCns; + + // swap the operands to match the encoding requirements + retNode = gtNewSimdHWIntrinsicNode(type, op2, op1, NI_AVX512F_PermuteVar16x32, simdBaseJitType, simdSize); + } + else if (elementSize == 2) + { + for (uint32_t i = 0; i < elementCount; i++) + { + vecCns.u16[i] = (uint8_t)(vecCns.u8[i * elementSize] / elementSize); + } + + op2 = gtNewVconNode(type); + op2->AsVecCon()->gtSimdVal = vecCns; + + // swap the operands to match the encoding requirements + retNode = gtNewSimdHWIntrinsicNode(type, op2, op1, NI_AVX512BW_PermuteVar32x16, simdBaseJitType, simdSize); + } + else + { + assert(elementSize == 8); + + for (uint32_t i = 0; i < elementCount; i++) + { + vecCns.u64[i] = (uint8_t)(vecCns.u8[i * elementSize] / elementSize); + } + + op2 = gtNewVconNode(type); + op2->AsVecCon()->gtSimdVal = vecCns; + + // swap the operands to match the encoding requirements + retNode = gtNewSimdHWIntrinsicNode(type, op2, op1, NI_AVX512F_PermuteVar8x64, simdBaseJitType, simdSize); + } + assert(retNode != nullptr); + + // TODO-XArch-AVX512: Switch to VPERMI2* + if (needsZero) + { + op2 = gtNewVconNode(type); + op2->AsVecCon()->gtSimdVal = mskCns; + retNode = gtNewSimdBinOpNode(GT_AND, type, op2, retNode, simdBaseJitType, simdSize); + } + + return retNode; + } else { if (needsZero && compOpportunisticallyDependsOn(InstructionSet_SSSE3)) @@ -23356,13 +23730,11 @@ GenTree* Compiler::gtNewSimdShuffleNode( if (needsZero) { - assert(!compIsaSupportedDebugOnly(InstructionSet_SSSE3)); + assert((simdSize == 32) || !compIsaSupportedDebugOnly(InstructionSet_SSSE3)); - op2 = gtNewVconNode(type); - op2->AsVecCon()->gtSimd16Val = mskCns.v128[0]; - - GenTree* zero = gtNewZeroConNode(type); - retNode = gtNewSimdCndSelNode(type, op2, retNode, zero, simdBaseJitType, simdSize); + op2 = gtNewVconNode(type); + op2->AsVecCon()->gtSimdVal = mskCns; + retNode = gtNewSimdBinOpNode(GT_AND, type, op2, retNode, simdBaseJitType, simdSize); } return retNode; @@ -23432,6 +23804,11 @@ GenTree* Compiler::gtNewSimdSqrtNode(var_types type, GenTree* op1, CorInfoType s assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); intrinsic = NI_AVX_Sqrt; } + else if (simdSize == 64) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + intrinsic = NI_AVX512F_Sqrt; + } else if (simdBaseType == TYP_FLOAT) { intrinsic = NI_SSE_Sqrt; @@ -23772,6 +24149,10 @@ GenTree* Compiler::gtNewSimdUnOpNode( assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2)); } + else if (simdSize == 64) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + } op2 = gtNewZeroConNode(type); // Zero - op1 @@ -25638,8 +26019,16 @@ bool GenTreeLclVar::IsNeverNegative(Compiler* comp) const // unsigned GenTreeHWIntrinsic::GetResultOpNumForFMA(GenTree* use, GenTree* op1, GenTree* op2, GenTree* op3) { +#if defined(DEBUG) // only FMA intrinsic node should call into this function - assert(HWIntrinsicInfo::lookupIsa(gtHWIntrinsicId) == InstructionSet_FMA); + if (HWIntrinsicInfo::lookupIsa(gtHWIntrinsicId) != InstructionSet_FMA) + { + assert((gtHWIntrinsicId >= NI_AVX512F_FusedMultiplyAdd) && + (gtHWIntrinsicId <= NI_AVX512F_FusedMultiplySubtractNegated)); + assert((NI_AVX512F_FusedMultiplySubtractNegated - NI_AVX512F_FusedMultiplyAdd) + 1 == 6); + } +#endif // DEBUG + if (use != nullptr && use->OperIs(GT_STORE_LCL_VAR)) { // For store_lcl_var, check if any op is overwritten @@ -25698,7 +26087,7 @@ bool GenTreeLclFld::IsOffsetMisaligned() const bool GenTree::IsInvariant() const { - return OperIsConst() || OperIs(GT_LCL_ADDR); + return OperIsConst() || OperIs(GT_LCL_ADDR) || OperIs(GT_FTN_ADDR); } //------------------------------------------------------------------------ @@ -25729,14 +26118,6 @@ bool GenTree::IsNeverNegative(Compiler* comp) const return true; } } - else if (OperIs(GT_FIELD)) - { - if (AsField()->IsSpanLength()) - { - // This is an early exit, it doesn't cover all cases - return true; - } - } // TODO-Casts: extend IntegralRange to handle constants return IntegralRange::ForNode(const_cast(this), comp).IsNonNegative(); diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 0a0669b0cec203..8f5d0ea0723454 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -82,6 +82,7 @@ enum GenTreeOperKind GTK_EXOP = 0x10, // Indicates that an oper for a node type that extends GenTreeOp (or GenTreeUnOp) // by adding non-node fields to unary or binary operator. GTK_NOVALUE = 0x20, // node does not produce a value + GTK_STORE = 0x40, // node represents a store GTK_MASK = 0xFF }; @@ -242,7 +243,7 @@ class AssertionInfo } }; -// GT_FIELD nodes will be lowered into more "code-gen-able" representations, like GT_IND's of addresses. +// GT_FIELD_ADDR nodes will be lowered into more "code-gen-able" representations, like ADD's of addresses. // For value numbering, we would like to preserve the aliasing information for class and static fields, // and so will annotate such lowered addresses with "field sequences", representing the "base" static or // class field and any additional struct fields. We only need to preserve the handle for the first field, @@ -475,9 +476,7 @@ enum GenTreeFlags : unsigned int GTF_MEMORYBARRIER_LOAD = 0x40000000, // GT_MEMORYBARRIER -- Load barrier GTF_FLD_TLS = 0x80000000, // GT_FIELD_ADDR -- field address is a Windows x86 TLS reference - GTF_FLD_VOLATILE = 0x40000000, // GT_FIELD -- same as GTF_IND_VOLATILE - GTF_FLD_INITCLASS = 0x20000000, // GT_FIELD/GT_FIELD_ADDR -- field access requires preceding class/static init helper - GTF_FLD_TGT_HEAP = 0x10000000, // GT_FIELD -- same as GTF_IND_TGT_HEAP + GTF_FLD_DEREFERENCED = 0x40000000, // GT_FIELD_ADDR -- used to preserve previous behavior GTF_INX_RNGCHK = 0x80000000, // GT_INDEX_ADDR -- this array address should be range-checked GTF_INX_ADDR_NONNULL = 0x40000000, // GT_INDEX_ADDR -- this array address is not null @@ -494,9 +493,10 @@ enum GenTreeFlags : unsigned int GTF_IND_UNALIGNED = 0x02000000, // OperIsIndir() -- the load or store is unaligned (we assume worst case alignment of 1 byte) GTF_IND_INVARIANT = 0x01000000, // GT_IND -- the target is invariant (a prejit indirection) GTF_IND_NONNULL = 0x00400000, // GT_IND -- the indirection never returns null (zero) + GTF_IND_INITCLASS = 0x00200000, // OperIsIndir() -- the indirection requires preceding static cctor GTF_IND_FLAGS = GTF_IND_VOLATILE | GTF_IND_NONFAULTING | GTF_IND_UNALIGNED | GTF_IND_INVARIANT | - GTF_IND_NONNULL | GTF_IND_TGT_NOT_HEAP | GTF_IND_TGT_HEAP, + GTF_IND_NONNULL | GTF_IND_TGT_NOT_HEAP | GTF_IND_TGT_HEAP | GTF_IND_INITCLASS, GTF_ADDRMODE_NO_CSE = 0x80000000, // GT_ADD/GT_MUL/GT_LSH -- Do not CSE this node only, forms complex // addressing mode @@ -508,12 +508,6 @@ enum GenTreeFlags : unsigned int GTF_RELOP_ZTT = 0x08000000, // GT_ -- Loop test cloned for converting while-loops into do-while // with explicit "loop test" in the header block. - GTF_JCMP_EQ = 0x80000000, // GTF_JCMP_EQ -- Branch on equal rather than not equal - GTF_JCMP_TST = 0x40000000, // GTF_JCMP_TST -- Use bit test instruction rather than compare against zero instruction -#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - GTF_JCMP_MASK = 0x3E000000, // For LoongArch64 and RISCV64, Using the five bits[29:25] to encoding the GenCondition:code. -#endif // TARGET_LOONGARCH64 || TARGET_RISCV64 - GTF_RET_MERGED = 0x80000000, // GT_RETURN -- This is a return generated during epilog merging. GTF_QMARK_CAST_INSTOF = 0x80000000, // GT_QMARK -- Is this a top (not nested) level qmark created for @@ -547,13 +541,6 @@ enum GenTreeFlags : unsigned int // GTF_ICON_REUSE_REG_VAL = 0x00800000 // GT_CNS_INT -- GTF_REUSE_REG_VAL, defined above GTF_ICON_SIMD_COUNT = 0x00200000, // GT_CNS_INT -- constant is Vector.Count - GTF_ICON_INITCLASS = 0x00100000, // GT_CNS_INT -- Constant is used to access a static that requires preceding - // class/static init helper. In some cases, the constant is - // the address of the static field itself, and in other cases - // there's an extra layer of indirection and it is the address - // of the cell that the runtime will fill in with the address - // of the static field; in both of those cases, the constant - // is what gets flagged. GTF_OVERFLOW = 0x10000000, // Supported for: GT_ADD, GT_SUB, GT_MUL and GT_CAST. // Requires an overflow check. Use gtOverflow(Ex)() to check this flag. @@ -1603,6 +1590,8 @@ struct GenTree // Helper function to return the address of an indir or array meta-data node. GenTree* GetIndirOrArrMetaDataAddr(); + bool IndirMayFault(Compiler* compiler); + bool OperIsImplicitIndir() const; static bool OperIsAtomicOp(genTreeOps gtOper) @@ -1626,15 +1615,14 @@ struct GenTree return OperIsAtomicOp(gtOper); } - bool OperIsStore() const + static bool OperIsStore(genTreeOps gtOper) { - return OperIsStore(gtOper); + return (OperKind(gtOper) & GTK_STORE) != 0; } - static bool OperIsStore(genTreeOps gtOper) + bool OperIsStore() const { - return (gtOper == GT_STOREIND || gtOper == GT_STORE_LCL_VAR || gtOper == GT_STORE_LCL_FLD || - OperIsStoreBlk(gtOper) || OperIsAtomicOp(gtOper)); + return OperIsStore(gtOper); } static bool OperIsMultiOp(genTreeOps gtOper) @@ -1683,7 +1671,7 @@ struct GenTree bool OperIsConditionalJump() const { - return OperIs(GT_JTRUE, GT_JCMP, GT_JCC); + return OperIs(GT_JTRUE, GT_JCMP, GT_JTEST, GT_JCC); } bool OperConsumesFlags() const @@ -1703,6 +1691,9 @@ struct GenTree return OperIs(GT_JCC, GT_SETCC, GT_SELECTCC); } + bool OperIsStoreLclVar(unsigned* pLclNum); + bool OperIsStoreLcl(unsigned* pLclNum); + #ifdef DEBUG static const GenTreeDebugOperKind gtDebugOperKindTable[]; @@ -1726,7 +1717,6 @@ struct GenTree case GT_LEA: case GT_RETFILT: case GT_NOP: - case GT_FIELD: case GT_FIELD_ADDR: return true; case GT_RETURN: @@ -1797,6 +1787,8 @@ struct GenTree // The returned pointer might be nullptr if the node is not binary, or if non-null op2 is not required. inline GenTree* gtGetOp2IfPresent() const; + inline GenTree* GetStoreDestination(); + inline GenTree*& Data(); bool TryGetUse(GenTree* operand, GenTree*** pUse); @@ -3461,6 +3453,13 @@ struct GenTreeLclVarCommon : public GenTreeUnOp SetLclNum(lclNum); } + GenTreeLclVarCommon(genTreeOps oper, var_types type, unsigned lclNum, GenTree* data) + : GenTreeUnOp(oper, type, data DEBUGARG(/* largeNode */ false)) + { + assert(OperIsLocalStore()); + SetLclNum(lclNum); + } + GenTree*& Data() { assert(OperIsLocalStore()); @@ -3605,7 +3604,7 @@ struct GenTreeLclVar : public GenTreeLclVarCommon MultiRegSpillFlags gtSpillFlags; public: - INDEBUG(IL_OFFSET gtLclILoffs;) // instr offset of ref (only for JIT dumps) + INDEBUG(IL_OFFSET gtLclILoffs = BAD_IL_OFFSET;) // instr offset of ref (only for JIT dumps) // Multireg support bool IsMultiReg() const @@ -3684,6 +3683,13 @@ struct GenTreeLclVar : public GenTreeLclVarCommon this->gtSpillFlags = from->gtSpillFlags; } +#ifdef DEBUG + void ResetLclILoffs() + { + gtLclILoffs = BAD_IL_OFFSET; + } +#endif + GenTreeLclVar(genTreeOps oper, var_types type, unsigned lclNum DEBUGARG(IL_OFFSET ilOffs = BAD_IL_OFFSET) DEBUGARG(bool largeNode = false)) @@ -3692,6 +3698,11 @@ struct GenTreeLclVar : public GenTreeLclVarCommon assert(OperIsScalarLocal(oper)); } + GenTreeLclVar(var_types type, unsigned lclNum, GenTree* data) + : GenTreeLclVarCommon(GT_STORE_LCL_VAR, type, lclNum, data) + { + } + #if DEBUGGABLE_GENTREE GenTreeLclVar() : GenTreeLclVarCommon() { @@ -3715,6 +3726,13 @@ struct GenTreeLclFld : public GenTreeLclVarCommon SetLayout(layout); } + GenTreeLclFld(var_types type, unsigned lclNum, unsigned lclOffs, GenTree* data, ClassLayout* layout) + : GenTreeLclVarCommon(GT_STORE_LCL_FLD, type, lclNum, data), m_lclOffs(static_cast(lclOffs)) + { + assert(lclOffs <= UINT16_MAX); + SetLayout(layout); + } + uint16_t GetLclOffs() const { return m_lclOffs; @@ -3861,8 +3879,8 @@ struct GenTreeBox : public GenTreeUnOp } }; -// GenTreeField -- data member ref (GT_FIELD) -struct GenTreeField : public GenTreeUnOp +// GenTreeFieldAddr -- data member address (GT_FIELD_ADDR) +struct GenTreeFieldAddr : public GenTreeUnOp { CORINFO_FIELD_HANDLE gtFldHnd; DWORD gtFldOffset; @@ -3876,8 +3894,8 @@ struct GenTreeField : public GenTreeUnOp CORINFO_CONST_LOOKUP gtFieldLookup; #endif - GenTreeField(genTreeOps oper, var_types type, GenTree* obj, CORINFO_FIELD_HANDLE fldHnd, DWORD offs) - : GenTreeUnOp(oper, type, obj) + GenTreeFieldAddr(var_types type, GenTree* obj, CORINFO_FIELD_HANDLE fldHnd, DWORD offs) + : GenTreeUnOp(GT_FIELD_ADDR, type, obj) , gtFldHnd(fldHnd) , gtFldOffset(offs) , gtFldMayOverlap(false) @@ -3889,7 +3907,7 @@ struct GenTreeField : public GenTreeUnOp } #if DEBUGGABLE_GENTREE - GenTreeField() : GenTreeUnOp() + GenTreeFieldAddr() : GenTreeUnOp() { } #endif @@ -3901,13 +3919,6 @@ struct GenTreeField : public GenTreeUnOp return gtOp1; } - // True if this field is a volatile memory operation. - bool IsVolatile() const - { - assert(((gtFlags & GTF_FLD_VOLATILE) == 0) || OperIs(GT_FIELD)); - return (gtFlags & GTF_FLD_VOLATILE) != 0; - } - bool IsSpanLength() const { // This is limited to span length today rather than a more general "IsNeverNegative" @@ -3916,8 +3927,6 @@ struct GenTreeField : public GenTreeUnOp // Extending this support more in the future will require additional work and // considerations to help ensure it is correctly used since people may want // or intend to use this as more of a "point in time" feature like GTF_IND_NONNULL - - assert(OperIs(GT_FIELD)); return gtFldIsSpanLength; } @@ -5561,6 +5570,8 @@ struct GenTreeCall final : public GenTree bool IsHelperCall(Compiler* compiler, unsigned helper) const; + CorInfoHelpFunc GetHelperNum() const; + bool AreArgsComplete() const; CorInfoCallConvExtension GetUnmanagedCallConv() const @@ -8801,7 +8812,16 @@ struct GenTreeCCMP final : public GenTreeOpCC inline bool GenTree::OperIsBlkOp() { - return ((gtOper == GT_ASG) && varTypeIsStruct(AsOp()->gtOp1)) || OperIsStoreBlk(); + if (OperIs(GT_STORE_DYN_BLK)) + { + return true; + } + if (OperIs(GT_ASG) || OperIsStore()) + { + return varTypeIsStruct(this); + } + + return false; } inline bool GenTree::OperIsInitBlkOp() @@ -8810,21 +8830,50 @@ inline bool GenTree::OperIsInitBlkOp() { return false; } - GenTree* src; - if (gtOper == GT_ASG) + GenTree* src = Data(); + bool isInitBlk = src->TypeIs(TYP_INT); + assert(isInitBlk == src->gtSkipReloadOrCopy()->IsInitVal()); + + return isInitBlk; +} + +inline bool GenTree::OperIsCopyBlkOp() +{ + return OperIsBlkOp() && !OperIsInitBlkOp(); +} + +inline bool GenTree::OperIsStoreLclVar(unsigned* pLclNum) // TODO-ASG: delete. +{ + if (OperIs(GT_STORE_LCL_VAR)) { - src = gtGetOp2(); + *pLclNum = AsLclVar()->GetLclNum(); + return true; } - else + if (OperIs(GT_ASG) && gtGetOp1()->OperIs(GT_LCL_VAR)) { - src = AsBlk()->Data()->gtSkipReloadOrCopy(); + *pLclNum = gtGetOp1()->AsLclVar()->GetLclNum(); + return true; } - return src->OperIsInitVal() || src->IsIntegralConst(); + + *pLclNum = BAD_VAR_NUM; + return false; } -inline bool GenTree::OperIsCopyBlkOp() +inline bool GenTree::OperIsStoreLcl(unsigned* pLclNum) // TODO-ASG: delete. { - return OperIsBlkOp() && !OperIsInitBlkOp(); + if (OperIsLocalStore()) + { + *pLclNum = AsLclVarCommon()->GetLclNum(); + return true; + } + if (OperIs(GT_ASG) && gtGetOp1()->OperIsLocal()) + { + *pLclNum = gtGetOp1()->AsLclVarCommon()->GetLclNum(); + return true; + } + + *pLclNum = BAD_VAR_NUM; + return false; } //------------------------------------------------------------------------ @@ -9208,10 +9257,16 @@ inline GenTree* GenTree::gtGetOp2IfPresent() const return op2; } +inline GenTree* GenTree::GetStoreDestination() // TODO-ASG: delete. +{ + assert(OperIs(GT_ASG) || OperIsStore()); + return OperIs(GT_ASG) ? gtGetOp1() : this; +} + inline GenTree*& GenTree::Data() { - assert(OperIsStore() && (OperIsIndir() || OperIsLocal())); - return OperIsLocalStore() ? AsLclVarCommon()->Data() : AsIndir()->Data(); + assert(OperIsStore() || OperIs(GT_STORE_DYN_BLK, GT_ASG)); + return OperIsLocalStore() ? AsLclVarCommon()->Data() : static_cast(this)->gtOp2; } inline GenTree* GenTree::gtEffectiveVal(bool commaOnly /* = false */) diff --git a/src/coreclr/jit/gschecks.cpp b/src/coreclr/jit/gschecks.cpp index d4f5cb497b3f0b..17443fc6ab2d2c 100644 --- a/src/coreclr/jit/gschecks.cpp +++ b/src/coreclr/jit/gschecks.cpp @@ -167,7 +167,6 @@ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTree** pTree, fgWa case GT_ARR_OFFSET: case GT_MDARR_LENGTH: case GT_MDARR_LOWER_BOUND: - case GT_FIELD: newState.isUnderIndir = true; { @@ -493,7 +492,7 @@ void Compiler::gsParamsToShadows() { GenTree* tree = *use; - if (tree->OperIsLocal() || tree->OperIs(GT_LCL_ADDR)) + if (tree->OperIsAnyLocal()) { unsigned int lclNum = tree->AsLclVarCommon()->GetLclNum(); unsigned int shadowLclNum = m_compiler->gsShadowVarInfo[lclNum].shadowCopy; diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index 7d754e6be11e49..dc4451faefd3d5 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -23,8 +23,8 @@ GTNODE(PHI , GenTreePhi ,0,GTK_SPECIAL) // phi nod GTNODE(PHI_ARG , GenTreePhiArg ,0,GTK_LEAF) // phi(phiarg, phiarg, phiarg) GTNODE(LCL_VAR , GenTreeLclVar ,0,GTK_LEAF) // local variable GTNODE(LCL_FLD , GenTreeLclFld ,0,GTK_LEAF) // field in a non-primitive variable -GTNODE(STORE_LCL_VAR , GenTreeLclVar ,0,GTK_UNOP|GTK_NOVALUE) // store to local variable -GTNODE(STORE_LCL_FLD , GenTreeLclFld ,0,GTK_UNOP|GTK_NOVALUE) // store to a part of the variable +GTNODE(STORE_LCL_VAR , GenTreeLclVar ,0,GTK_UNOP|GTK_EXOP|GTK_NOVALUE|GTK_STORE) // store to local variable +GTNODE(STORE_LCL_FLD , GenTreeLclFld ,0,GTK_UNOP|GTK_EXOP|GTK_NOVALUE|GTK_STORE) // store to a part of the variable GTNODE(LCL_ADDR , GenTreeLclFld ,0,GTK_LEAF) // local address //----------------------------------------------------------------------------- @@ -57,6 +57,7 @@ GTNODE(NEG , GenTreeOp ,0,GTK_UNOP) GTNODE(INTRINSIC , GenTreeIntrinsic ,0,GTK_BINOP|GTK_EXOP) +GTNODE(ASG , GenTreeOp ,0,GTK_BINOP|DBK_NOTLIR) GTNODE(LOCKADD , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE|DBK_NOTHIR) GTNODE(XAND , GenTreeOp ,0,GTK_BINOP) GTNODE(XORR , GenTreeOp ,0,GTK_BINOP) @@ -78,18 +79,17 @@ GTNODE(LCLHEAP , GenTreeOp ,0,GTK_UNOP|DBK_NOCONTAIN) // alloc GTNODE(BOUNDS_CHECK , GenTreeBoundsChk ,0,GTK_BINOP|GTK_EXOP|GTK_NOVALUE) // a bounds check - for arrays/spans/SIMDs/HWINTRINSICs -GTNODE(IND , GenTreeIndir ,0,GTK_UNOP) // Load indirection -GTNODE(STOREIND , GenTreeStoreInd ,0,GTK_BINOP|GTK_NOVALUE) // Store indirection -GTNODE(BLK , GenTreeBlk ,0,GTK_UNOP|GTK_EXOP) // Struct load -GTNODE(STORE_BLK , GenTreeBlk ,0,GTK_BINOP|GTK_EXOP|GTK_NOVALUE) // Struct store -GTNODE(STORE_DYN_BLK , GenTreeStoreDynBlk ,0,GTK_SPECIAL|GTK_NOVALUE) // Dynamically sized block store, with native uint size -GTNODE(NULLCHECK , GenTreeIndir ,0,GTK_UNOP|GTK_NOVALUE) // Null checks the source +GTNODE(IND , GenTreeIndir ,0,GTK_UNOP) // Load indirection +GTNODE(STOREIND , GenTreeStoreInd ,0,GTK_BINOP|GTK_EXOP|GTK_NOVALUE|GTK_STORE) // Store indirection +GTNODE(BLK , GenTreeBlk ,0,GTK_UNOP|GTK_EXOP) // Struct load +GTNODE(STORE_BLK , GenTreeBlk ,0,GTK_BINOP|GTK_EXOP|GTK_NOVALUE|GTK_STORE) // Struct store +GTNODE(STORE_DYN_BLK , GenTreeStoreDynBlk ,0,GTK_SPECIAL|GTK_NOVALUE) // Dynamically sized block store, with native uint size +GTNODE(NULLCHECK , GenTreeIndir ,0,GTK_UNOP|GTK_NOVALUE) // Null checks the source GTNODE(ARR_LENGTH , GenTreeArrLen ,0,GTK_UNOP|GTK_EXOP) // single-dimension (SZ) array length GTNODE(MDARR_LENGTH , GenTreeMDArr ,0,GTK_UNOP|GTK_EXOP) // multi-dimension (MD) array length of a specific dimension GTNODE(MDARR_LOWER_BOUND, GenTreeMDArr ,0,GTK_UNOP|GTK_EXOP) // multi-dimension (MD) array lower bound of a specific dimension -GTNODE(FIELD , GenTreeField ,0,GTK_UNOP|GTK_EXOP|DBK_NOTLIR) // Field load -GTNODE(FIELD_ADDR , GenTreeField ,0,GTK_UNOP|GTK_EXOP|DBK_NOTLIR) // Field address +GTNODE(FIELD_ADDR , GenTreeFieldAddr ,0,GTK_UNOP|GTK_EXOP|DBK_NOTLIR) // Field address GTNODE(ALLOCOBJ , GenTreeAllocObj ,0,GTK_UNOP|GTK_EXOP|DBK_NOTLIR) // object allocator GTNODE(INIT_VAL , GenTreeOp ,0,GTK_UNOP) // Initialization value for an initBlk @@ -124,7 +124,6 @@ GTNODE(RSZ , GenTreeOp ,0,GTK_BINOP) GTNODE(ROL , GenTreeOp ,0,GTK_BINOP) GTNODE(ROR , GenTreeOp ,0,GTK_BINOP) -GTNODE(ASG , GenTreeOp ,0,GTK_BINOP|DBK_NOTLIR) GTNODE(EQ , GenTreeOp ,0,GTK_BINOP) GTNODE(NE , GenTreeOp ,0,GTK_BINOP) GTNODE(LT , GenTreeOp ,0,GTK_BINOP) @@ -231,8 +230,10 @@ GTNODE(TEST , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE|DBK_NOTHIR // The XARCH BT instruction. Like CMP, this sets the condition flags (CF to be precise) and does not produce a value. GTNODE(BT , GenTreeOp ,0,(GTK_BINOP|GTK_NOVALUE|DBK_NOTHIR)) #endif -// Makes a comparison and jump if the condition specified. Does not set flags. -GTNODE(JCMP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE|DBK_NOTHIR) +// Makes a comparison and jumps if the condition specified by gtCondition is true. Does not set flags. +GTNODE(JCMP , GenTreeOpCC ,0,GTK_BINOP|GTK_NOVALUE|DBK_NOTHIR) +// Do a bit test and jump if set/not set. +GTNODE(JTEST , GenTreeOpCC ,0,GTK_BINOP|GTK_NOVALUE|DBK_NOTHIR) // Checks the condition flags and branch if the condition specified by GenTreeCC::gtCondition is true. GTNODE(JCC , GenTreeCC ,0,GTK_LEAF|GTK_NOVALUE|DBK_NOTHIR) // Checks the condition flags and produces 1 if the condition specified by GenTreeCC::gtCondition is true and 0 otherwise. diff --git a/src/coreclr/jit/gtstructs.h b/src/coreclr/jit/gtstructs.h index 73127d0106af8d..11f6928b3e307d 100644 --- a/src/coreclr/jit/gtstructs.h +++ b/src/coreclr/jit/gtstructs.h @@ -66,7 +66,7 @@ GTSTRUCT_2(LclVar , GT_LCL_VAR, GT_STORE_LCL_VAR) GTSTRUCT_3(LclFld , GT_LCL_FLD, GT_STORE_LCL_FLD, GT_LCL_ADDR) GTSTRUCT_1(Cast , GT_CAST) GTSTRUCT_1(Box , GT_BOX) -GTSTRUCT_2(Field , GT_FIELD, GT_FIELD_ADDR) +GTSTRUCT_1(FieldAddr , GT_FIELD_ADDR) GTSTRUCT_1(Call , GT_CALL) GTSTRUCT_1(FieldList , GT_FIELD_LIST) GTSTRUCT_1(Colon , GT_COLON) @@ -113,9 +113,9 @@ GTSTRUCT_1(ArrAddr , GT_ARR_ADDR) GTSTRUCT_2(CC , GT_JCC, GT_SETCC) #ifdef TARGET_ARM64 GTSTRUCT_1(CCMP , GT_CCMP) -GTSTRUCT_2(OpCC , GT_SELECTCC, GT_CINCCC) +GTSTRUCT_4(OpCC , GT_SELECTCC, GT_CINCCC, GT_JCMP, GT_JTEST) #else -GTSTRUCT_1(OpCC , GT_SELECTCC) +GTSTRUCT_3(OpCC , GT_SELECTCC, GT_JCMP, GT_JTEST) #endif #if defined(TARGET_X86) GTSTRUCT_1(MultiRegOp , GT_MUL_LONG) diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 2f03327a8eeb39..e920e769e9c32a 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -93,8 +93,28 @@ PhaseStatus Compiler::fgExpandRuntimeLookups() return fgExpandHelper<&Compiler::fgExpandRuntimeLookupsForCall>(false); } -bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call) +//------------------------------------------------------------------------------ +// fgExpandRuntimeLookupsForCall : partially expand runtime lookups helper calls +// to add a nullcheck [+ size check] and a fast path +// +// Arguments: +// pBlock - Block containing the helper call to expand. If expansion is performed, +// this is updated to the new block that was an outcome of block splitting. +// stmt - Statement containing the helper call +// call - The helper call +// +// Returns: +// true if a runtime lookup was found and expanded. +// +// Notes: +// The runtime lookup itself is needed to access a handle in code shared between +// generic instantiations. The lookup depends on the typeContext which is only available at +// runtime, and not at compile - time. See ASCII block diagrams in comments below for +// better understanding how this phase expands runtime lookups. +// +bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call) { + BasicBlock* block = *pBlock; assert(call->IsHelperCall()); if (!call->IsExpRuntimeLookup()) @@ -150,6 +170,7 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, GenTree** callUse = nullptr; Statement* newFirstStmt = nullptr; block = fgSplitBlockBeforeTree(block, stmt, call, &newFirstStmt, &callUse); + *pBlock = block; assert(prevBb != nullptr && block != nullptr); // Block ops inserted by the split need to be morphed here since we are after morph. @@ -165,15 +186,10 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, // Mostly for Tier0: if the current statement is ASG(LCL, RuntimeLookup) // we can drop it and use that LCL as the destination - if (stmt->GetRootNode()->OperIs(GT_ASG)) + if (stmt->GetRootNode()->OperIs(GT_STORE_LCL_VAR) && (stmt->GetRootNode()->AsLclVar()->Data() == *callUse)) { - GenTree* lhs = stmt->GetRootNode()->gtGetOp1(); - GenTree* rhs = stmt->GetRootNode()->gtGetOp2(); - if (lhs->OperIs(GT_LCL_VAR) && rhs == *callUse) - { - rtLookupLcl = gtClone(lhs)->AsLclVar(); - fgRemoveStmt(block, stmt); - } + rtLookupLcl = gtNewLclVarNode(stmt->GetRootNode()->AsLclVar()->GetLclNum()); + fgRemoveStmt(block, stmt); } // Grab a temp to store result (it's assigned from either fastPathBb or fallbackBb) @@ -209,12 +225,12 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, const bool isLastIndirectionWithSizeCheck = (i == runtimeLookup.indirections - 1) && needsSizeCheck; if (i != 0) { - slotPtrTree = gtNewOperNode(GT_IND, TYP_I_IMPL, slotPtrTree); - slotPtrTree->gtFlags |= GTF_IND_NONFAULTING; + GenTreeFlags indirFlags = GTF_IND_NONFAULTING; if (!isLastIndirectionWithSizeCheck) { - slotPtrTree->gtFlags |= GTF_IND_INVARIANT; + indirFlags |= GTF_IND_INVARIANT; } + slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, indirFlags); } if ((i == 1 && runtimeLookup.indirectFirstOffset) || (i == 2 && runtimeLookup.indirectSecondOffset)) @@ -254,8 +270,7 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, // // null-check basic block - GenTree* fastPathValue = gtNewOperNode(GT_IND, TYP_I_IMPL, gtCloneExpr(slotPtrTree)); - fastPathValue->gtFlags |= GTF_IND_NONFAULTING; + GenTree* fastPathValue = gtNewIndir(TYP_I_IMPL, gtCloneExpr(slotPtrTree), GTF_IND_NONFAULTING); // Save dictionary slot to a local (to be used by fast path) GenTree* fastPathValueClone = opts.OptimizationEnabled() ? fgMakeMultiUse(&fastPathValue) : gtCloneExpr(fastPathValue); @@ -265,12 +280,12 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, fgNewBBFromTreeAfter(BBJ_COND, prevBb, gtNewOperNode(GT_JTRUE, TYP_VOID, nullcheckOp), debugInfo); // Fallback basic block - GenTree* asgFallbackValue = gtNewAssignNode(gtClone(rtLookupLcl), call); - BasicBlock* fallbackBb = fgNewBBFromTreeAfter(BBJ_NONE, nullcheckBb, asgFallbackValue, debugInfo, true); + GenTree* fallbackValueDef = gtNewStoreLclVarNode(rtLookupLcl->GetLclNum(), call); + BasicBlock* fallbackBb = fgNewBBFromTreeAfter(BBJ_NONE, nullcheckBb, fallbackValueDef, debugInfo, true); // Fast-path basic block - GenTree* asgFastpathValue = gtNewAssignNode(gtClone(rtLookupLcl), fastPathValueClone); - BasicBlock* fastPathBb = fgNewBBFromTreeAfter(BBJ_ALWAYS, nullcheckBb, asgFastpathValue, debugInfo); + GenTree* fastpathValueDef = gtNewStoreLclVarNode(rtLookupLcl->GetLclNum(), fastPathValueClone); + BasicBlock* fastPathBb = fgNewBBFromTreeAfter(BBJ_ALWAYS, nullcheckBb, fastpathValueDef, debugInfo); BasicBlock* sizeCheckBb = nullptr; if (needsSizeCheck) @@ -303,8 +318,7 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, GenTreeIntCon* sizeOffset = gtNewIconNode(runtimeLookup.sizeOffset, TYP_I_IMPL); assert(lastIndOfTree != nullptr); GenTree* sizeValueOffset = gtNewOperNode(GT_ADD, TYP_I_IMPL, lastIndOfTree, sizeOffset); - GenTree* sizeValue = gtNewOperNode(GT_IND, TYP_I_IMPL, sizeValueOffset); - sizeValue->gtFlags |= GTF_IND_NONFAULTING; + GenTree* sizeValue = gtNewIndir(TYP_I_IMPL, sizeValueOffset, GTF_IND_NONFAULTING); // sizeCheck fails if sizeValue <= pRuntimeLookup->offsets[i] GenTree* offsetValue = gtNewIconNode(runtimeLookup.offsets[runtimeLookup.indirections - 1], TYP_I_IMPL); @@ -435,9 +449,10 @@ PhaseStatus Compiler::fgExpandThreadLocalAccess() // that access fields marked with [ThreadLocal]. // // Arguments: -// block - Block containing the helper call to expand -// stmt - Statement containing the helper call -// call - The helper call +// pBlock - Block containing the helper call to expand. If expansion is performed, +// this is updated to the new block that was an outcome of block splitting. +// stmt - Statement containing the helper call +// call - The helper call // // // Returns: @@ -452,8 +467,9 @@ PhaseStatus Compiler::fgExpandThreadLocalAccess() // If the entry is not present, the helper is called, which would make an entry of current static block // in the cache. // -bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call) +bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call) { + BasicBlock* block = *pBlock; assert(call->IsHelperCall()); if (!call->IsExpTLSFieldAccess()) { @@ -491,6 +507,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st Statement* newFirstStmt = nullptr; DebugInfo debugInfo = stmt->GetDebugInfo(); block = fgSplitBlockBeforeTree(block, stmt, call, &newFirstStmt, &callUse); + *pBlock = block; assert(prevBb != nullptr && block != nullptr); // Block ops inserted by the split need to be morphed here since we are after morph. @@ -543,15 +560,14 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st // Cache the tls value unsigned tlsLclNum = lvaGrabTemp(true DEBUGARG("TLS access")); lvaTable[tlsLclNum].lvType = TYP_I_IMPL; - GenTree* defTlsLclValue = gtNewLclvNode(tlsLclNum, TYP_I_IMPL); - GenTree* useTlsLclValue = gtCloneExpr(defTlsLclValue); // Create a use for tlsLclValue - GenTree* asgTlsValue = gtNewAssignNode(defTlsLclValue, tlsValue); + GenTree* tlsValueDef = gtNewStoreLclVarNode(tlsLclNum, tlsValue); + GenTree* tlsLclValueUse = gtNewLclVarNode(tlsLclNum); // Create tree for "maxThreadStaticBlocks = tls[offsetOfMaxThreadStaticBlocks]" GenTree* offsetOfMaxThreadStaticBlocks = gtNewIconNode(threadStaticBlocksInfo.offsetOfMaxThreadStaticBlocks, TYP_I_IMPL); GenTree* maxThreadStaticBlocksRef = - gtNewOperNode(GT_ADD, TYP_I_IMPL, gtCloneExpr(useTlsLclValue), offsetOfMaxThreadStaticBlocks); + gtNewOperNode(GT_ADD, TYP_I_IMPL, gtCloneExpr(tlsLclValueUse), offsetOfMaxThreadStaticBlocks); GenTree* maxThreadStaticBlocksValue = gtNewIndir(TYP_INT, maxThreadStaticBlocksRef, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); @@ -563,7 +579,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st // Create tree for "threadStaticBlockBase = tls[offsetOfThreadStaticBlocks]" GenTree* offsetOfThreadStaticBlocks = gtNewIconNode(threadStaticBlocksInfo.offsetOfThreadStaticBlocks, TYP_I_IMPL); GenTree* threadStaticBlocksRef = - gtNewOperNode(GT_ADD, TYP_I_IMPL, gtCloneExpr(useTlsLclValue), offsetOfThreadStaticBlocks); + gtNewOperNode(GT_ADD, TYP_I_IMPL, gtCloneExpr(tlsLclValueUse), offsetOfThreadStaticBlocks); GenTree* threadStaticBlocksValue = gtNewIndir(TYP_I_IMPL, threadStaticBlocksRef, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); @@ -577,14 +593,12 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st // Cache the threadStaticBlock value unsigned threadStaticBlockBaseLclNum = lvaGrabTemp(true DEBUGARG("ThreadStaticBlockBase access")); lvaTable[threadStaticBlockBaseLclNum].lvType = TYP_I_IMPL; - GenTree* defThreadStaticBlockBaseLclValue = gtNewLclvNode(threadStaticBlockBaseLclNum, TYP_I_IMPL); - GenTree* useThreadStaticBlockBaseLclValue = - gtCloneExpr(defThreadStaticBlockBaseLclValue); // StaticBlockBaseLclValue that will be used - GenTree* asgThreadStaticBlockBase = gtNewAssignNode(defThreadStaticBlockBaseLclValue, typeThreadStaticBlockValue); + GenTree* threadStaticBlockBaseDef = gtNewStoreLclVarNode(threadStaticBlockBaseLclNum, typeThreadStaticBlockValue); + GenTree* threadStaticBlockBaseLclValueUse = gtNewLclVarNode(threadStaticBlockBaseLclNum); // Create tree for "if (threadStaticBlockValue != nullptr)" GenTree* threadStaticBlockNullCond = - gtNewOperNode(GT_NE, TYP_INT, useThreadStaticBlockBaseLclValue, gtNewIconNode(0, TYP_I_IMPL)); + gtNewOperNode(GT_NE, TYP_INT, threadStaticBlockBaseLclValueUse, gtNewIconNode(0, TYP_I_IMPL)); threadStaticBlockNullCond = gtNewOperNode(GT_JTRUE, TYP_VOID, threadStaticBlockNullCond); // prevBb (BBJ_NONE): [weight: 1.0] @@ -611,26 +625,26 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st // use(threadStaticBlockBase); // maxThreadStaticBlocksCondBB - BasicBlock* maxThreadStaticBlocksCondBB = fgNewBBFromTreeAfter(BBJ_COND, prevBb, asgTlsValue, debugInfo); + BasicBlock* maxThreadStaticBlocksCondBB = fgNewBBFromTreeAfter(BBJ_COND, prevBb, tlsValueDef, debugInfo); fgInsertStmtAfter(maxThreadStaticBlocksCondBB, maxThreadStaticBlocksCondBB->firstStmt(), fgNewStmtFromTree(maxThreadStaticBlocksCond)); // threadStaticBlockNullCondBB BasicBlock* threadStaticBlockNullCondBB = - fgNewBBFromTreeAfter(BBJ_COND, maxThreadStaticBlocksCondBB, asgThreadStaticBlockBase, debugInfo); + fgNewBBFromTreeAfter(BBJ_COND, maxThreadStaticBlocksCondBB, threadStaticBlockBaseDef, debugInfo); fgInsertStmtAfter(threadStaticBlockNullCondBB, threadStaticBlockNullCondBB->firstStmt(), fgNewStmtFromTree(threadStaticBlockNullCond)); // fallbackBb - GenTree* asgFallbackValue = gtNewAssignNode(gtClone(threadStaticBlockLcl), call); + GenTree* fallbackValueDef = gtNewStoreLclVarNode(threadStaticBlockLclNum, call); BasicBlock* fallbackBb = - fgNewBBFromTreeAfter(BBJ_ALWAYS, threadStaticBlockNullCondBB, asgFallbackValue, debugInfo, true); + fgNewBBFromTreeAfter(BBJ_ALWAYS, threadStaticBlockNullCondBB, fallbackValueDef, debugInfo, true); // fastPathBb - GenTree* asgFastPathValue = - gtNewAssignNode(gtClone(threadStaticBlockLcl), gtCloneExpr(useThreadStaticBlockBaseLclValue)); - BasicBlock* fastPathBb = fgNewBBFromTreeAfter(BBJ_ALWAYS, fallbackBb, asgFastPathValue, debugInfo, true); + GenTree* fastPathValueDef = + gtNewStoreLclVarNode(threadStaticBlockLclNum, gtCloneExpr(threadStaticBlockBaseLclValueUse)); + BasicBlock* fastPathBb = fgNewBBFromTreeAfter(BBJ_ALWAYS, fallbackBb, fastPathValueDef, debugInfo, true); // // Update preds in all new blocks @@ -684,7 +698,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st // Returns: // true if there was any helper that was expanded. // -template +template PhaseStatus Compiler::fgExpandHelper(bool skipRarelyRunBlocks) { PhaseStatus result = PhaseStatus::MODIFIED_NOTHING; @@ -697,9 +711,14 @@ PhaseStatus Compiler::fgExpandHelper(bool skipRarelyRunBlocks) } // Expand and visit the last block again to find more candidates - while (fgExpandHelperForBlock(block)) + INDEBUG(BasicBlock* origBlock = block); + while (fgExpandHelperForBlock(&block)) { result = PhaseStatus::MODIFIED_EVERYTHING; +#ifdef DEBUG + assert(origBlock != block); + origBlock = block; +#endif } } @@ -717,16 +736,17 @@ PhaseStatus Compiler::fgExpandHelper(bool skipRarelyRunBlocks) // invoke `fgExpand` if any of the tree node was a helper call. // // Arguments: -// block - block to scan for static initializations +// pBlock - Block containing the helper call to expand. If expansion is performed, +// this is updated to the new block that was an outcome of block splitting. // fgExpand - function that expands the helper call // // Returns: // true if a helper was expanded // -template -bool Compiler::fgExpandHelperForBlock(BasicBlock* block) +template +bool Compiler::fgExpandHelperForBlock(BasicBlock** pBlock) { - for (Statement* const stmt : block->NonPhiStatements()) + for (Statement* const stmt : (*pBlock)->NonPhiStatements()) { if ((stmt->GetRootNode()->gtFlags & GTF_CALL) == 0) { @@ -741,7 +761,7 @@ bool Compiler::fgExpandHelperForBlock(BasicBlock* block) continue; } - if ((this->*ExpansionFunction)(block, stmt, tree->AsCall())) + if ((this->*ExpansionFunction)(pBlock, stmt, tree->AsCall())) { return true; } @@ -798,15 +818,17 @@ PhaseStatus Compiler::fgExpandStaticInit() // Also, see fgExpandStaticInit's comments. // // Arguments: -// block - call's block -// stmt - call's statement -// call - call that represents a static initialization +// pBlock - Block containing the helper call to expand. If expansion is performed, +// this is updated to the new block that was an outcome of block splitting. +// stmt - Statement containing the helper call +// call - The helper call // // Returns: // true if a static initialization was expanded // -bool Compiler::fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call) +bool Compiler::fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call) { + BasicBlock* block = *pBlock; assert(call->IsHelperCall()); bool isGc = false; @@ -850,6 +872,7 @@ bool Compiler::fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, Gen GenTree** callUse = nullptr; Statement* newFirstStmt = nullptr; block = fgSplitBlockBeforeTree(block, stmt, call, &newFirstStmt, &callUse); + *pBlock = block; assert(prevBb != nullptr && block != nullptr); // Block ops inserted by the split need to be morphed here since we are after morph. @@ -914,7 +937,6 @@ bool Compiler::fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, Gen // Don't fold ADD(CNS1, CNS2) here since the result won't be reloc-friendly for AOT GenTree* offsetNode = gtNewOperNode(GT_ADD, TYP_I_IMPL, baseAddr, gtNewIconNode(isInitOffset)); isInitedActualValueNode = gtNewIndir(TYP_I_IMPL, offsetNode, GTF_IND_NONFAULTING); - isInitedActualValueNode->gtFlags |= GTF_GLOB_REF; // 0 means "initialized" on NativeAOT isInitedExpectedValue = gtNewIconNode(0, TYP_I_IMPL); diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 92449c74b3610c..920e6bb9846db1 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1009,11 +1009,14 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, switch (numArgs) { case 0: + { assert(!isScalar); retNode = gtNewSimdHWIntrinsicNode(retType, intrinsic, simdBaseJitType, simdSize); break; + } case 1: + { op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); if ((category == HW_Category_MemoryLoad) && op1->OperIs(GT_CAST)) @@ -1067,8 +1070,10 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, #endif // TARGET_XARCH break; + } case 2: + { op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand, immLowerBound, immUpperBound); op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); @@ -1121,8 +1126,10 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, } #endif break; + } case 3: + { op3 = getArgForHWIntrinsic(sigReader.GetOp3Type(), sigReader.op3ClsHnd); op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); @@ -1164,9 +1171,10 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, } #endif break; + } -#ifdef TARGET_ARM64 case 4: + { op4 = getArgForHWIntrinsic(sigReader.GetOp4Type(), sigReader.op4ClsHnd); op4 = addRangeCheckIfNeeded(intrinsic, op4, mustExpand, immLowerBound, immUpperBound); op3 = getArgForHWIntrinsic(sigReader.GetOp3Type(), sigReader.op3ClsHnd); @@ -1176,7 +1184,8 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, assert(!isScalar); retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, op4, intrinsic, simdBaseJitType, simdSize); break; -#endif + } + default: break; } diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index 4d0439ac076bd6..341bc02b508257 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -534,9 +534,13 @@ struct HWIntrinsicInfo case NI_SSE41_Ceiling: case NI_SSE41_CeilingScalar: + case NI_AVX_Ceiling: + { + FALLTHROUGH; + } + case NI_SSE41_RoundToPositiveInfinity: case NI_SSE41_RoundToPositiveInfinityScalar: - case NI_AVX_Ceiling: case NI_AVX_RoundToPositiveInfinity: { return static_cast(FloatRoundingMode::ToPositiveInfinity); @@ -544,9 +548,13 @@ struct HWIntrinsicInfo case NI_SSE41_Floor: case NI_SSE41_FloorScalar: + case NI_AVX_Floor: + { + FALLTHROUGH; + } + case NI_SSE41_RoundToNegativeInfinity: case NI_SSE41_RoundToNegativeInfinityScalar: - case NI_AVX_Floor: case NI_AVX_RoundToNegativeInfinity: { return static_cast(FloatRoundingMode::ToNegativeInfinity); diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 07821710e9acb6..66ad884abe3bcf 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -811,7 +811,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { op1 = nodeBuilder.GetOperand(0); GenTree* op1Address = CreateAddressNodeForSimdHWIntrinsicCreate(op1, simdBaseType, simdSize); - retNode = gtNewOperNode(GT_IND, retType, op1Address); + retNode = gtNewIndir(retType, op1Address); } else { @@ -1519,6 +1519,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector64_ShiftLeft: case NI_Vector128_ShiftLeft: + case NI_Vector64_op_LeftShift: + case NI_Vector128_op_LeftShift: { assert(sig->numArgs == 2); @@ -1531,6 +1533,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector64_ShiftRightArithmetic: case NI_Vector128_ShiftRightArithmetic: + case NI_Vector64_op_RightShift: + case NI_Vector128_op_RightShift: { assert(sig->numArgs == 2); genTreeOps op = varTypeIsUnsigned(simdBaseType) ? GT_RSZ : GT_RSH; @@ -1544,6 +1548,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector64_ShiftRightLogical: case NI_Vector128_ShiftRightLogical: + case NI_Vector64_op_UnsignedRightShift: + case NI_Vector128_op_UnsignedRightShift: { assert(sig->numArgs == 2); diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index a4c9fbd83eda25..69a581c912dee9 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -110,9 +110,12 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GenTree* op1 = nullptr; GenTree* op2 = nullptr; GenTree* op3 = nullptr; + GenTree* op4 = nullptr; regNumber op1Reg = REG_NA; regNumber op2Reg = REG_NA; + regNumber op3Reg = REG_NA; + regNumber op4Reg = REG_NA; emitter* emit = GetEmitter(); assert(numArgs >= 0); @@ -144,7 +147,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) if ((ival != -1) && varTypeIsFloating(baseType)) { assert((ival >= 0) && (ival <= 127)); - if ((category == HW_Category_SIMDScalar) && HWIntrinsicInfo::CopiesUpperBits(intrinsicId)) + if (HWIntrinsicInfo::CopiesUpperBits(intrinsicId)) { assert(!op1->isContained()); emit->emitIns_SIMD_R_R_R_I(ins, simdSize, targetReg, op1Reg, op1Reg, @@ -155,8 +158,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) genHWIntrinsic_R_RM_I(node, ins, simdSize, static_cast(ival)); } } - else if ((category == HW_Category_SIMDScalar) && HWIntrinsicInfo::CopiesUpperBits(intrinsicId)) + else if (HWIntrinsicInfo::CopiesUpperBits(intrinsicId)) { + assert(!op1->isContained()); emit->emitIns_SIMD_R_R_R(ins, simdSize, targetReg, op1Reg, op1Reg); } else @@ -232,7 +236,17 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) else if (HWIntrinsicInfo::isImmOp(intrinsicId, op2)) { assert(ival == -1); - auto emitSwCase = [&](int8_t i) { genHWIntrinsic_R_RM_I(node, ins, simdSize, i); }; + auto emitSwCase = [&](int8_t i) { + if (HWIntrinsicInfo::CopiesUpperBits(intrinsicId)) + { + assert(!op1->isContained()); + emit->emitIns_SIMD_R_R_R_I(ins, simdSize, targetReg, op1Reg, op1Reg, i); + } + else + { + genHWIntrinsic_R_RM_I(node, ins, simdSize, i); + } + }; if (op2->IsCnsIntOrI()) { @@ -242,9 +256,12 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } else { - // We emit a fallback case for the scenario when the imm-op is not a constant. This should - // normally happen when the intrinsic is called indirectly, such as via Reflection. However, it - // can also occur if the consumer calls it directly and just doesn't pass a constant value. + // We emit a fallback case for the scenario when the imm-op is not a constant. + // This should + // normally happen when the intrinsic is called indirectly, such as via + // Reflection. However, it + // can also occur if the consumer calls it directly and just doesn't pass a + // constant value. regNumber baseReg = node->ExtractTempReg(); regNumber offsReg = node->GetSingleTempReg(); genHWIntrinsicJumpTableFallback(intrinsicId, op2Reg, baseReg, offsReg, emitSwCase); @@ -274,7 +291,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) op2Reg = op2->GetRegNum(); genConsumeRegs(op3); - regNumber op3Reg = op3->GetRegNum(); + op3Reg = op3->GetRegNum(); if (HWIntrinsicInfo::isImmOp(intrinsicId, op3)) { @@ -348,6 +365,54 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; } + case 4: + { + op1 = node->Op(1); + op2 = node->Op(2); + op3 = node->Op(3); + op4 = node->Op(4); + + genConsumeRegs(op1); + op1Reg = op1->GetRegNum(); + + genConsumeRegs(op2); + op2Reg = op2->GetRegNum(); + + genConsumeRegs(op3); + op3Reg = op3->GetRegNum(); + + genConsumeRegs(op4); + op4Reg = op4->GetRegNum(); + + if (HWIntrinsicInfo::isImmOp(intrinsicId, op4)) + { + assert(ival == -1); + + auto emitSwCase = [&](int8_t i) { genHWIntrinsic_R_R_R_RM_I(node, ins, simdSize, i); }; + + if (op4->IsCnsIntOrI()) + { + ssize_t ival = op4->AsIntCon()->IconValue(); + assert((ival >= 0) && (ival <= 255)); + emitSwCase(static_cast(ival)); + } + else + { + // We emit a fallback case for the scenario when the imm-op is not a constant. This should + // normally happen when the intrinsic is called indirectly, such as via Reflection. However, it + // can also occur if the consumer calls it directly and just doesn't pass a constant value. + regNumber baseReg = node->ExtractTempReg(); + regNumber offsReg = node->GetSingleTempReg(); + genHWIntrinsicJumpTableFallback(intrinsicId, op4Reg, baseReg, offsReg, emitSwCase); + } + } + else + { + unreached(); + } + break; + } + default: unreached(); break; @@ -386,7 +451,10 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case InstructionSet_AVX: case InstructionSet_AVX2: case InstructionSet_AVX512F: + case InstructionSet_AVX512F_VL: + case InstructionSet_AVX512F_X64: case InstructionSet_AVX512BW: + case InstructionSet_AVX512BW_VL: genAvxFamilyIntrinsic(node); break; case InstructionSet_AES: @@ -476,27 +544,104 @@ void CodeGen::genHWIntrinsic_R_RM( } else { - if (varTypeIsIntegral(rmOp) && ((node->GetHWIntrinsicId() == NI_AVX2_BroadcastScalarToVector128) || - (node->GetHWIntrinsicId() == NI_AVX512F_BroadcastScalarToVector512) || - (node->GetHWIntrinsicId() == NI_AVX512BW_BroadcastScalarToVector512) || - (node->GetHWIntrinsicId() == NI_AVX2_BroadcastScalarToVector256))) + if (varTypeIsIntegral(rmOp)) { - // In lowering we had the special case of BroadcastScalarToVector(CreateScalarUnsafe(op1)) - // - // This is one of the only instructions where it supports taking integer types from - // a SIMD register or directly as a scalar from memory. Most other instructions, in - // comparison, take such values from general-purpose registers instead. - // - // Because of this, we removed the CreateScalarUnsafe and tried to contain op1 directly - // that failed and we either didn't get marked regOptional or we did and didn't get spilled - // - // As such, we need to emulate the removed CreateScalarUnsafe to ensure that op1 is in a - // SIMD register so the broadcast instruction can execute succesfully. We'll just move - // the value into the target register and then broadcast it out from that. + bool needsBroadcastFixup = false; + bool needsInstructionFixup = false; + + switch (node->GetHWIntrinsicId()) + { + case NI_AVX2_BroadcastScalarToVector128: + case NI_AVX2_BroadcastScalarToVector256: + { + if (varTypeIsSmall(node->GetSimdBaseType())) + { + if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX512BW_VL)) + { + needsInstructionFixup = true; + } + else + { + needsBroadcastFixup = true; + } + } + else if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) + { + needsInstructionFixup = true; + } + else + { + needsBroadcastFixup = true; + } + break; + } + + case NI_AVX512F_BroadcastScalarToVector512: + case NI_AVX512BW_BroadcastScalarToVector512: + { + needsInstructionFixup = true; + break; + } + + default: + { + break; + } + } - emitAttr movdAttr = emitActualTypeSize(node->GetSimdBaseType()); - emit->emitIns_Mov(INS_movd, movdAttr, reg, rmOpReg, /* canSkip */ false); - rmOpReg = reg; + if (needsBroadcastFixup) + { + // In lowering we had the special case of BroadcastScalarToVector(CreateScalarUnsafe(op1)) + // + // This is one of the only instructions where it supports taking integer types from + // a SIMD register or directly as a scalar from memory. Most other instructions, in + // comparison, take such values from general-purpose registers instead. + // + // Because of this, we removed the CreateScalarUnsafe and tried to contain op1 directly + // that failed and we either didn't get marked regOptional or we did and didn't get spilled + // + // As such, we need to emulate the removed CreateScalarUnsafe to ensure that op1 is in a + // SIMD register so the broadcast instruction can execute succesfully. We'll just move + // the value into the target register and then broadcast it out from that. + + emitAttr movdAttr = emitActualTypeSize(node->GetSimdBaseType()); + emit->emitIns_Mov(INS_movd, movdAttr, reg, rmOpReg, /* canSkip */ false); + rmOpReg = reg; + } + else if (needsInstructionFixup) + { + switch (ins) + { + case INS_vpbroadcastb: + { + ins = INS_vpbroadcastb_gpr; + break; + } + + case INS_vpbroadcastd: + { + ins = INS_vpbroadcastd_gpr; + break; + } + + case INS_vpbroadcastq: + { + ins = INS_vpbroadcastq_gpr; + break; + } + + case INS_vpbroadcastw: + { + ins = INS_vpbroadcastw_gpr; + break; + } + + default: + { + unreached(); + } + } + } } emit->emitIns_R_R(ins, attr, reg, rmOpReg); @@ -601,12 +746,15 @@ void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, regNumber targetReg = node->GetRegNum(); GenTree* op1 = node->Op(1); GenTree* op2 = node->Op(2); - emitter* emit = GetEmitter(); + regNumber op1Reg = op1->GetRegNum(); - // TODO-XArch-CQ: Commutative operations can have op1 be contained - // TODO-XArch-CQ: Non-VEX encoded instructions can have both ops contained + assert(targetReg != REG_NA); - regNumber op1Reg = op1->GetRegNum(); + if (op2->isContained() || op2->isUsedFromSpillTemp()) + { + assert(HWIntrinsicInfo::SupportsContainment(node->GetHWIntrinsicId())); + assertIsContainableHWIntrinsicOp(compiler->m_pLowering, node, op2); + } if (ins == INS_insertps) { @@ -622,68 +770,15 @@ void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, // insertps can also contain op2 when it is zero in which case // we just reuse op1Reg since ival specifies the entry to zero - emit->emitIns_SIMD_R_R_R_I(ins, simdSize, targetReg, op1Reg, op1Reg, ival); + GetEmitter()->emitIns_SIMD_R_R_R_I(ins, simdSize, targetReg, op1Reg, op1Reg, ival); return; } } - assert(targetReg != REG_NA); assert(op1Reg != REG_NA); - OperandDesc op2Desc = genOperandDesc(op2); - - if (op2Desc.IsContained()) - { - assert(HWIntrinsicInfo::SupportsContainment(node->GetHWIntrinsicId())); - assertIsContainableHWIntrinsicOp(compiler->m_pLowering, node, op2); - } - - switch (op2Desc.GetKind()) - { - case OperandKind::ClsVar: - emit->emitIns_SIMD_R_R_C_I(ins, simdSize, targetReg, op1Reg, op2Desc.GetFieldHnd(), 0, ival); - break; - - case OperandKind::Local: - emit->emitIns_SIMD_R_R_S_I(ins, simdSize, targetReg, op1Reg, op2Desc.GetVarNum(), op2Desc.GetLclOffset(), - ival); - break; - - case OperandKind::Indir: - { - // Until we improve the handling of addressing modes in the emitter, we'll create a - // temporary GT_IND to generate code with. - GenTreeIndir indirForm; - GenTreeIndir* indir = op2Desc.GetIndirForm(&indirForm); - emit->emitIns_SIMD_R_R_A_I(ins, simdSize, targetReg, op1Reg, indir, ival); - } - break; - - case OperandKind::Reg: - { - regNumber op2Reg = op2Desc.GetReg(); - - if ((op1Reg != targetReg) && (op2Reg == targetReg) && node->isRMWHWIntrinsic(compiler)) - { - // We have "reg2 = reg1 op reg2" where "reg1 != reg2" on a RMW intrinsic. - // - // For non-commutative intrinsics, we should have ensured that op2 was marked - // delay free in order to prevent it from getting assigned the same register - // as target. However, for commutative intrinsics, we can just swap the operands - // in order to have "reg2 = reg2 op reg1" which will end up producing the right code. - - noway_assert(node->OperIsCommutative()); - op2Reg = op1Reg; - op1Reg = targetReg; - } - - emit->emitIns_SIMD_R_R_R_I(ins, simdSize, targetReg, op1Reg, op2Reg, ival); - } - break; - - default: - unreached(); - } + bool isRMW = node->isRMWHWIntrinsic(compiler); + inst_RV_RV_TT_IV(ins, simdSize, targetReg, op1Reg, op2, ival, isRMW); } //------------------------------------------------------------------------ @@ -799,6 +894,78 @@ void CodeGen::genHWIntrinsic_R_R_R_RM( } } +//------------------------------------------------------------------------ +// genHWIntrinsic_R_R_R_RM_I: Generates the code for a hardware intrinsic node that takes two register operands, +// a register/memory operand, an immediate operand, and that returns a value in register +// +// Arguments: +// node - The hardware intrinsic node +// ins - The instruction being generated +// ival - The immediate value +// +void CodeGen::genHWIntrinsic_R_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, int8_t ival) +{ + regNumber targetReg = node->GetRegNum(); + GenTree* op1 = node->Op(1); + GenTree* op2 = node->Op(2); + GenTree* op3 = node->Op(3); + regNumber op1Reg = op1->GetRegNum(); + regNumber op2Reg = op2->GetRegNum(); + + if (op1->isContained()) + { + // op1 is never selected by the table so + // we can contain and ignore any register + // allocated to it resulting in better + // non-RMW based codegen. + + assert(!node->isRMWHWIntrinsic(compiler)); + op1Reg = targetReg; + } + + assert(targetReg != REG_NA); + assert(op1Reg != REG_NA); + assert(op2Reg != REG_NA); + + emitter* emit = GetEmitter(); + OperandDesc op3Desc = genOperandDesc(op3); + + switch (op3Desc.GetKind()) + { + case OperandKind::ClsVar: + { + emit->emitIns_SIMD_R_R_R_C_I(ins, attr, targetReg, op1Reg, op2Reg, op3Desc.GetFieldHnd(), 0, ival); + break; + } + + case OperandKind::Local: + { + emit->emitIns_SIMD_R_R_R_S_I(ins, attr, targetReg, op1Reg, op2Reg, op3Desc.GetVarNum(), + op3Desc.GetLclOffset(), ival); + break; + } + + case OperandKind::Indir: + { + // Until we improve the handling of addressing modes in the emitter, we'll create a + // temporary GT_IND to generate code with. + GenTreeIndir indirForm; + GenTreeIndir* indir = op3Desc.GetIndirForm(&indirForm); + emit->emitIns_SIMD_R_R_R_A_I(ins, attr, targetReg, op1Reg, op2Reg, indir, ival); + } + break; + + case OperandKind::Reg: + { + emit->emitIns_SIMD_R_R_R_R_I(ins, attr, targetReg, op1Reg, op2Reg, op3Desc.GetReg(), ival); + break; + } + + default: + unreached(); + } +} + // genHWIntrinsicJumpTableFallback : generate the jump-table fallback for imm-intrinsics // with non-constant argument // @@ -1560,15 +1727,23 @@ void CodeGen::genSSE42Intrinsic(GenTreeHWIntrinsic* node) void CodeGen::genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node) { NamedIntrinsic intrinsicId = node->GetHWIntrinsicId(); - var_types baseType = node->GetSimdBaseType(); - emitAttr attr = emitActualTypeSize(Compiler::getSIMDTypeForSize(node->GetSimdSize())); - var_types targetType = node->TypeGet(); - instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); - size_t numArgs = node->GetOperandCount(); - GenTree* op1 = node->Op(1); - regNumber op1Reg = REG_NA; - regNumber targetReg = node->GetRegNum(); - emitter* emit = GetEmitter(); + + if ((intrinsicId >= NI_AVX512F_FusedMultiplyAdd) && (intrinsicId <= NI_AVX512F_FusedMultiplySubtractNegated)) + { + assert((NI_AVX512F_FusedMultiplySubtractNegated - NI_AVX512F_FusedMultiplyAdd) + 1 == 6); + genFMAIntrinsic(node); + return; + } + + var_types baseType = node->GetSimdBaseType(); + emitAttr attr = emitActualTypeSize(Compiler::getSIMDTypeForSize(node->GetSimdSize())); + var_types targetType = node->TypeGet(); + instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); + size_t numArgs = node->GetOperandCount(); + GenTree* op1 = node->Op(1); + regNumber op1Reg = REG_NA; + regNumber targetReg = node->GetRegNum(); + emitter* emit = GetEmitter(); genConsumeMultiOpOperands(node); @@ -1789,6 +1964,7 @@ void CodeGen::genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node) emit->emitIns_R_R_R_I(compareIns, attr, targetReg, op1Reg, op2Reg, 6); break; } + case NI_AVX512F_CompareLessThanOrEqualSpecial: { GenTree* op2 = node->Op(2); @@ -1818,6 +1994,7 @@ void CodeGen::genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node) emit->emitIns_R_R_R_I(compareIns, attr, targetReg, op1Reg, op2Reg, 1); break; } + case NI_AVX512F_MoveMaskToVectorSpecial: { op1Reg = op1->GetRegNum(); @@ -1844,7 +2021,23 @@ void CodeGen::genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node) break; } + case NI_AVX512F_ConvertToUInt32: + case NI_AVX512F_ConvertToUInt32WithTruncation: + case NI_AVX512F_X64_ConvertToUInt64: + case NI_AVX512F_X64_ConvertToUInt64WithTruncation: + { + assert(baseType == TYP_DOUBLE || baseType == TYP_FLOAT); + emitAttr attr = emitTypeSize(targetType); + + instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); + genHWIntrinsic_R_RM(node, ins, attr, targetReg, node->Op(1)); + break; + } + case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32WithSaturation: { if (varTypeIsFloating(baseType)) { @@ -1855,17 +2048,38 @@ void CodeGen::genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node) FALLTHROUGH; } + case NI_AVX512F_ConvertToVector128Byte: + case NI_AVX512F_ConvertToVector128ByteWithSaturation: case NI_AVX512F_ConvertToVector128Int16: - case NI_AVX512F_ConvertToVector128Int32: + case NI_AVX512F_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector128SByteWithSaturation: case NI_AVX512F_ConvertToVector128UInt16: - case NI_AVX512F_ConvertToVector128UInt32: + case NI_AVX512F_ConvertToVector128UInt16WithSaturation: case NI_AVX512F_ConvertToVector256Int16: + case NI_AVX512F_ConvertToVector256Int16WithSaturation: + case NI_AVX512F_ConvertToVector256Int32WithSaturation: case NI_AVX512F_ConvertToVector256UInt16: - case NI_AVX512F_ConvertToVector256UInt32: - case NI_AVX512BW_ConvertToVector128Byte: - case NI_AVX512BW_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector256UInt16WithSaturation: + case NI_AVX512F_ConvertToVector256UInt32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Byte: + case NI_AVX512F_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int16: + case NI_AVX512F_VL_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int32: + case NI_AVX512F_VL_ConvertToVector128Int32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128SByte: + case NI_AVX512F_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128UInt16: + case NI_AVX512F_VL_ConvertToVector128UInt16WithSaturation: case NI_AVX512BW_ConvertToVector256Byte: + case NI_AVX512BW_ConvertToVector256ByteWithSaturation: case NI_AVX512BW_ConvertToVector256SByte: + case NI_AVX512BW_ConvertToVector256SByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128Byte: + case NI_AVX512BW_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128SByte: + case NI_AVX512BW_VL_ConvertToVector128SByteWithSaturation: { instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); @@ -1877,6 +2091,15 @@ void CodeGen::genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node) break; } + case NI_AVX512F_X64_ConvertScalarToVector128Double: + case NI_AVX512F_X64_ConvertScalarToVector128Single: + { + assert(baseType == TYP_ULONG); + instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); + genHWIntrinsic_R_R_RM(node, ins, EA_8BYTE); + break; + } + default: unreached(); break; diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index 3c9ac8f2d1ddb8..fd4fc497369f97 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -241,6 +241,7 @@ HARDWARE_INTRINSIC(Vector256, Xor, // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Vector512 Intrinsics +HARDWARE_INTRINSIC(Vector512, Abs, 64, 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(Vector512, Add, 64, 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(Vector512, AndNot, 64, 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(Vector512, As, 64, 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) @@ -261,6 +262,7 @@ HARDWARE_INTRINSIC(Vector512, AsVector512, HARDWARE_INTRINSIC(Vector512, BitwiseAnd, 64, 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(Vector512, ConditionalSelect, 64, 3, {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(Vector512, BitwiseOr, 64, 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(Vector512, Ceiling, 64, 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(Vector512, Create, 64, -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(Vector512, CreateScalar, 64, -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(Vector512, CreateScalarUnsafe, 64, 1, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) @@ -271,6 +273,7 @@ HARDWARE_INTRINSIC(Vector512, Equals, HARDWARE_INTRINSIC(Vector512, EqualsAll, 64, 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(Vector512, EqualsAny, 64, 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(Vector512, ExtractMostSignificantBits, 64, 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(Vector512, Floor, 64, 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(Vector512, get_AllBitsSet, 64, 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|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Vector512, get_One, 64, 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(Vector512, get_Zero, 64, 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|HW_Flag_ReturnsPerElementMask) @@ -294,8 +297,11 @@ HARDWARE_INTRINSIC(Vector512, Load, HARDWARE_INTRINSIC(Vector512, LoadAligned, 64, 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(Vector512, LoadAlignedNonTemporal, 64, 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(Vector512, LoadUnsafe, 64, -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(Vector512, Max, 64, 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(Vector512, Min, 64, 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(Vector512, Multiply, 64, 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(Vector512, Narrow, 64, 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(Vector512, Negate, 64, 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(Vector512, OnesComplement, 64, 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(Vector512, op_Addition, 64, 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(Vector512, op_BitwiseAnd, 64, 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|HW_Flag_Commutative) @@ -309,11 +315,14 @@ HARDWARE_INTRINSIC(Vector512, op_Multiply, HARDWARE_INTRINSIC(Vector512, op_OnesComplement, 64, 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(Vector512, op_RightShift, 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(Vector512, op_Subtraction, 64, 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(Vector512, op_UnaryNegation, 64, 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(Vector512, op_UnaryPlus, 64, 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(Vector512, op_UnsignedRightShift, 64, 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(Vector512, ShiftLeft, 64, 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(Vector512, ShiftRightArithmetic, 64, 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(Vector512, ShiftRightLogical, 64, 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(Vector512, Shuffle, 64, -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(Vector512, Sqrt, 64, 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(Vector512, Store, 64, 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(Vector512, StoreAligned, 64, 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(Vector512, StoreAlignedNonTemporal, 64, 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) @@ -604,16 +613,16 @@ HARDWARE_INTRINSIC(SSSE3, Sign, // SSE41 Intrinsics HARDWARE_INTRINSIC(SSE41, Blend, 16, 3, {INS_invalid, INS_invalid, INS_pblendw, INS_pblendw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blendps, INS_blendpd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(SSE41, BlendVariable, 16, 3, {INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_blendvps, INS_blendvpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics) -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|HW_Flag_NoEvexSemantics) -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|HW_Flag_NoEvexSemantics) +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|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) 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, 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|HW_Flag_NoEvexSemantics) 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, FloorScalar, 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|HW_Flag_NoEvexSemantics) +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) +HARDWARE_INTRINSIC(SSE41, FloorScalar, 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, Insert, 16, 3, {INS_pinsrb, INS_pinsrb, INS_invalid, INS_invalid, INS_pinsrd, INS_pinsrd, INS_invalid, INS_invalid, INS_insertps, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(SSE41, LoadAlignedVector128NonTemporal, 16, 1, {INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(SSE41, Max, 16, 2, {INS_pmaxsb, INS_invalid, INS_invalid, INS_pmaxuw, INS_pmaxsd, INS_pmaxud, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -623,16 +632,16 @@ HARDWARE_INTRINSIC(SSE41, MultipleSumAbsoluteDifferences, HARDWARE_INTRINSIC(SSE41, Multiply, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmuldq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(SSE41, MultiplyLow, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmulld, INS_pmulld, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(SSE41, PackUnsignedSaturate, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_packusdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(SSE41, RoundCurrentDirection, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundCurrentDirectionScalar, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToNearestInteger, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToNearestIntegerScalar, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToNegativeInfinity, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToNegativeInfinityScalar, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToPositiveInfinity, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToPositiveInfinityScalar, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToZero, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE41, RoundToZeroScalar, 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|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(SSE41, RoundCurrentDirection, 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, RoundCurrentDirectionScalar, 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, RoundToNearestInteger, 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, RoundToNearestIntegerScalar, 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, RoundToNegativeInfinity, 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, RoundToNegativeInfinityScalar, 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, RoundToPositiveInfinity, 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, RoundToPositiveInfinityScalar, 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, RoundToZero, 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, RoundToZeroScalar, 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, TestC, 16, 2, {INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(SSE41, TestNotZAndNotC, 16, 2, {INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(SSE41, TestZ, 16, 2, {INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoEvexSemantics) @@ -672,10 +681,10 @@ HARDWARE_INTRINSIC(AVX, And, HARDWARE_INTRINSIC(AVX, AndNot, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_andnps, INS_andnpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, Blend, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blendps, INS_blendpd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX, BlendVariable, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vblendvps, INS_vblendvpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, Ceiling, 32, 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|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX, Ceiling, 32, 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_NoFlag) HARDWARE_INTRINSIC(AVX, BroadcastScalarToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcastss, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, BroadcastScalarToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcastss, INS_vbroadcastsd}, HW_Category_MemoryLoad, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AVX, BroadcastVector128ToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcastf128, INS_vbroadcastf128}, HW_Category_MemoryLoad, HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX, BroadcastVector128ToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcastf128, INS_vbroadcastf128}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, Compare, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_IMM, HW_Flag_NoFlag|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(AVX, CompareEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(AVX, CompareGreaterThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag|HW_Flag_ReturnsPerElementMask) @@ -702,7 +711,7 @@ HARDWARE_INTRINSIC(AVX, DotProduct, HARDWARE_INTRINSIC(AVX, DuplicateEvenIndexed, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movsldup, INS_movddup}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX, DuplicateOddIndexed, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movshdup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX, ExtractVector128, 32, 2, {INS_vextractf128, INS_vextractf128, INS_vextractf128, INS_vextractf128, INS_vextractf128, INS_vextractf128, INS_vextractf128, INS_vextractf128, INS_vextractf128, INS_vextractf128}, HW_Category_IMM, HW_Flag_FullRangeIMM) -HARDWARE_INTRINSIC(AVX, Floor, 32, 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|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX, Floor, 32, 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_NoFlag) HARDWARE_INTRINSIC(AVX, HorizontalAdd, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_haddps, INS_haddpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX, HorizontalSubtract, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_hsubps, INS_hsubpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX, InsertVector128, 32, 3, {INS_vinsertf128, INS_vinsertf128, INS_vinsertf128, INS_vinsertf128, INS_vinsertf128, INS_vinsertf128, INS_vinsertf128, INS_vinsertf128, INS_vinsertf128, INS_vinsertf128}, HW_Category_IMM, HW_Flag_FullRangeIMM) @@ -721,11 +730,11 @@ HARDWARE_INTRINSIC(AVX, Permute2x128, HARDWARE_INTRINSIC(AVX, PermuteVar, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermilpsvar, INS_vpermilpdvar}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, Reciprocal, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rcpps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX, ReciprocalSqrt, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rsqrtps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, RoundCurrentDirection, 32, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, RoundToNearestInteger, 32, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, RoundToNegativeInfinity, 32, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, RoundToPositiveInfinity, 32, 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|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, RoundToZero, 32, 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|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX, RoundCurrentDirection, 32, 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_NoFlag) +HARDWARE_INTRINSIC(AVX, RoundToNearestInteger, 32, 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_NoFlag) +HARDWARE_INTRINSIC(AVX, RoundToNegativeInfinity, 32, 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_NoFlag) +HARDWARE_INTRINSIC(AVX, RoundToPositiveInfinity, 32, 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_NoFlag) +HARDWARE_INTRINSIC(AVX, RoundToZero, 32, 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_NoFlag) HARDWARE_INTRINSIC(AVX, Shuffle, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_shufps, INS_shufpd}, HW_Category_IMM, HW_Flag_NoRMWSemantics|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX, Sqrt, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqrtps, INS_sqrtpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX, Store, 32, 2, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromSecondArg|HW_Flag_NoCodeGen) @@ -755,7 +764,7 @@ HARDWARE_INTRINSIC(AVX2, Blend, HARDWARE_INTRINSIC(AVX2, BlendVariable, 32, 3, {INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX2, BroadcastScalarToVector128, 16, 1, {INS_vpbroadcastb, INS_vpbroadcastb, INS_vpbroadcastw, INS_vpbroadcastw, INS_vpbroadcastd, INS_vpbroadcastd, INS_vpbroadcastq, INS_vpbroadcastq, INS_vbroadcastss, INS_movddup}, HW_Category_SIMDScalar, HW_Flag_MaybeMemoryLoad) HARDWARE_INTRINSIC(AVX2, BroadcastScalarToVector256, 32, 1, {INS_vpbroadcastb, INS_vpbroadcastb, INS_vpbroadcastw, INS_vpbroadcastw, INS_vpbroadcastd, INS_vpbroadcastd, INS_vpbroadcastq, INS_vpbroadcastq, INS_vbroadcastss, INS_vbroadcastsd}, HW_Category_SIMDScalar, HW_Flag_MaybeMemoryLoad) -HARDWARE_INTRINSIC(AVX2, BroadcastVector128ToVector256, 32, 1, {INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX2, BroadcastVector128ToVector256, 32, 1, {INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_vbroadcasti128, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX2, CompareEqual, 32, 2, {INS_pcmpeqb, INS_pcmpeqb, INS_pcmpeqw, INS_pcmpeqw, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqq, INS_pcmpeqq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX2, CompareGreaterThan, 32, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX2, CompareLessThan, 32, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) @@ -820,29 +829,57 @@ HARDWARE_INTRINSIC(AVX512F, Abs, HARDWARE_INTRINSIC(AVX512F, Add, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_paddd, INS_paddd, INS_paddq, INS_paddq, INS_addps, INS_addpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F, And, 64, 2, {INS_pand, INS_pand, INS_pand, INS_pand, INS_pand, INS_pand, INS_vpandq, INS_vpandq, INS_andps, INS_andpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F, AndNot, 64, 2, {INS_pandn, INS_pandn, INS_pandn, INS_pandn, INS_pandn, INS_pandn, INS_vpandnq, INS_vpandnq, INS_andnps, INS_andnpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AVX512F, BroadcastScalarToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpbroadcastd, INS_vpbroadcastd, INS_vpbroadcastq, INS_vpbroadcastq, INS_vbroadcastss, INS_vbroadcastsd}, HW_Category_SIMDScalar, HW_Flag_MaybeMemoryLoad) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector128Int16, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdw, INS_vpmovdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector128Int32, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqd, INS_vpmovqd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector128UInt16, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdw, INS_vpmovdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector128UInt32, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqd, INS_vpmovqd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, BroadcastScalarToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpbroadcastd, INS_vpbroadcastd, INS_vpbroadcastq, INS_vpbroadcastq, INS_vbroadcastss, INS_vbroadcastsd}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, BroadcastVector128ToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti128, INS_vbroadcasti128, INS_invalid, INS_invalid, INS_vbroadcastf128, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, BroadcastVector256ToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti64x4, INS_vbroadcasti64x4, INS_invalid, INS_vbroadcastf64x4}, HW_Category_MemoryLoad, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, ConvertScalarToVector128Double, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtusi2sd32, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromSecondArg|HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, ConvertScalarToVector128Single, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtusi2ss32, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromSecondArg|HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, ConvertToUInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtss2usi, INS_vcvtsd2usi}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToUInt32WithTruncation, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttss2usi, INS_vcvttsd2usi}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128Byte, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdb, INS_vpmovdb, INS_vpmovqb, INS_vpmovqb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128ByteWithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovusdb, INS_invalid, INS_vpmovusqb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128Int16, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqw, INS_vpmovqw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128Int16WithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovsqw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128SByte, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdb, INS_vpmovdb, INS_vpmovqb, INS_vpmovqb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128SByteWithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovsdb, INS_invalid, INS_vpmovsqb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128UInt16, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqw, INS_vpmovqw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector128UInt16WithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovusqw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512F, ConvertToVector256Int16, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdw, INS_vpmovdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector256Int16WithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovsdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512F, ConvertToVector256Int32, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqd, INS_vpmovqd, INS_invalid, INS_cvtpd2dq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector256Int32WithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovsqd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512F, ConvertToVector256Int32WithTruncation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvttpd2dq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, ConvertToVector256Single, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtpd2ps}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, ConvertToVector256UInt16, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdw, INS_vpmovdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector256UInt32, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqd, INS_vpmovqd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector512Double, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtdq2pd, INS_invalid, INS_invalid, INS_invalid, INS_cvtps2pd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector256UInt16WithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovusdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector256UInt32, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqd, INS_vpmovqd, INS_invalid, INS_vcvtpd2udq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector256UInt32WithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovusqd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector256UInt32WithTruncation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttpd2udq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector512Double, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtdq2pd, INS_vcvtudq2pd, INS_invalid, INS_invalid, INS_cvtps2pd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, ConvertToVector512Int32, 64, 1, {INS_pmovsxbd, INS_pmovzxbd, INS_pmovsxwd, INS_pmovzxwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtps2dq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, ConvertToVector512Int32WithTruncation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvttps2dq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, ConvertToVector512Int64, 64, 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_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector512Single, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtdq2ps, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AVX512F, ConvertToVector512UInt32, 64, 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_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector512Single, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtdq2ps, INS_vcvtudq2ps, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector512UInt32, 64, 1, {INS_pmovsxbd, INS_pmovzxbd, INS_pmovsxwd, INS_pmovzxwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2udq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F, ConvertToVector512UInt32WithTruncation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2udq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, ConvertToVector512UInt64, 64, 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_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, Divide, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_divps, INS_divpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, DuplicateEvenIndexed, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movsldup, INS_movddup}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX512F, DuplicateOddIndexed, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movshdup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX512F, ExtractVector128, 64, 2, {INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextractf128, INS_vextractf128}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, ExtractVector256, 64, 2, {INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextractf64x4, INS_vextractf64x4}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, Fixup, 64, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmps, INS_vfixupimmpd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, FixupScalar, 16, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmss, INS_vfixupimmsd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, FusedMultiplyAdd, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfmadd213ps, INS_vfmadd213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, FusedMultiplyAddNegated, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfnmadd213ps, INS_vfnmadd213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, FusedMultiplyAddSubtract, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfmaddsub213ps, INS_vfmaddsub213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, FusedMultiplySubtract, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfmsub213ps, INS_vfmsub213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, FusedMultiplySubtractAdd, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfmsubadd213ps, INS_vfmsubadd213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, FusedMultiplySubtractNegated, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfnmsub213ps, INS_vfnmsub213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F, GetExponent, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetexpps, INS_vgetexppd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, GetExponentScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetexpss, INS_vgetexpsd}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, GetMantissa, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetmantps, INS_vgetmantpd}, HW_Category_IMM, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, GetMantissaScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetmantss, INS_vgetmantsd}, HW_Category_IMM, HW_Flag_CopyUpperBits) HARDWARE_INTRINSIC(AVX512F, InsertVector128, 64, 3, {INS_vinserti128, INS_vinserti128, INS_vinserti128, INS_vinserti128, INS_vinserti128, INS_vinserti128, INS_vinserti128, INS_vinserti128, INS_vinsertf128, INS_vinsertf128}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, InsertVector256, 64, 3, {INS_vinserti64x4, INS_vinserti64x4, INS_vinserti64x4, INS_vinserti64x4, INS_vinserti64x4, INS_vinserti64x4, INS_vinserti64x4, INS_vinserti64x4, INS_vinsertf64x4, INS_vinsertf64x4}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, LoadAlignedVector512, 64, 1, {INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_vmovdqa64, INS_vmovdqa64, INS_movaps, INS_movapd}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics) @@ -853,9 +890,27 @@ HARDWARE_INTRINSIC(AVX512F, Min, HARDWARE_INTRINSIC(AVX512F, Multiply, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmuldq, INS_pmuludq, INS_mulps, INS_mulpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F, MultiplyLow, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmulld, INS_pmulld, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F, Or, 64, 2, {INS_por, INS_por, INS_por, INS_por, INS_por, INS_por, INS_vporq, INS_vporq, INS_orps, INS_orpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512F, Permute2x64, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermilpd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, Permute4x32, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermilps, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, Permute4x64, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermq, INS_vpermq, INS_invalid, INS_vpermpd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, PermuteVar2x64, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermilpdvar}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, PermuteVar4x32, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermilpsvar, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, PermuteVar8x64, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermq_reg, INS_vpermq_reg, INS_invalid, INS_vpermpd_reg}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX512F, PermuteVar16x32, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermd, INS_vpermd, INS_invalid, INS_invalid, INS_vpermps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX512F, Reciprocal14, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrcp14ps, INS_vrcp14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, Reciprocal14Scalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrcp14ss, INS_vrcp14sd}, HW_Category_SimpleSIMD, HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, ReciprocalSqrt14, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ps, INS_vrsqrt14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, ReciprocalSqrt14Scalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ss, INS_vrsqrt14sd}, HW_Category_SimpleSIMD, HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, RoundScale, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaleps, INS_vrndscalepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, RoundScaleScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaless, INS_vrndscalesd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, Scale, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefps, INS_vscalefpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, ScaleScalar, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefss, INS_vscalefsd}, HW_Category_SimpleSIMD, HW_Flag_CopyUpperBits) HARDWARE_INTRINSIC(AVX512F, ShiftLeftLogical, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pslld, INS_pslld, INS_psllq, INS_psllq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, ShiftLeftLogicalVariable, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsllvd, INS_vpsllvd, INS_vpsllvq, INS_vpsllvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, ShiftRightArithmetic, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_psrad, INS_invalid, INS_vpsraq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, ShiftRightArithmeticVariable, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsravd, INS_invalid, INS_vpsravq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, ShiftRightLogical, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_psrld, INS_psrld, INS_psrlq, INS_psrlq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, ShiftRightLogicalVariable, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsrlvd, INS_vpsrlvd, INS_vpsrlvq, INS_vpsrlvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, Shuffle, 64, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pshufd, INS_pshufd, INS_invalid, INS_invalid, INS_shufps, INS_shufpd}, HW_Category_IMM, HW_Flag_NoRMWSemantics|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, Sqrt, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqrtps, INS_sqrtpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX512F, Store, 64, 2, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_vmovdqu64, INS_vmovdqu64, INS_movups, INS_movupd}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromSecondArg|HW_Flag_NoCodeGen) @@ -874,7 +929,45 @@ HARDWARE_INTRINSIC(AVX512F, Xor, HARDWARE_INTRINSIC(AVX512F_VL, Abs, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpabsq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F_VL, Max, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmaxsq, INS_vpmaxuq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F_VL, Min, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpminsq, INS_vpminuq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Byte, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdb, INS_vpmovdb, INS_vpmovqb, INS_vpmovqb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128ByteWithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovusdb, INS_invalid, INS_vpmovusqb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Double, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtudq2pd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Int16, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdw, INS_vpmovdw, INS_vpmovqw, INS_vpmovqw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Int16WithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovsdw, INS_invalid, INS_vpmovsqw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Int32, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqd, INS_vpmovqd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Int32WithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovsqd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128SByte, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdb, INS_vpmovdb, INS_vpmovqb, INS_vpmovqb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128SByteWithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovsdb, INS_invalid, INS_vpmovsqb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Single, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtudq2ps, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128UInt16, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdw, INS_vpmovdw, INS_vpmovqw, INS_vpmovqw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128UInt16WithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovusdw, INS_invalid, INS_vpmovusqw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128UInt32, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovqd, INS_vpmovqd, INS_vcvtps2udq, INS_vcvtpd2udq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128UInt32WithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovusqd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128UInt32WithTruncation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2udq, INS_vcvttpd2udq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256Double, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtudq2pd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256Single, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtudq2ps, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256UInt32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2udq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256UInt32WithTruncation, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2udq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, Fixup, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmps, INS_vfixupimmpd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, GetExponent, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetexpps, INS_vgetexppd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F_VL, GetMantissa, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetmantps, INS_vgetmantpd}, HW_Category_IMM, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F_VL, PermuteVar4x64, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermq_reg, INS_vpermq_reg, INS_invalid, INS_vpermpd_reg}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX512F_VL, Reciprocal14, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrcp14ps, INS_vrcp14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F_VL, ReciprocalSqrt14, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ps, INS_vrsqrt14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F_VL, RoundScale, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaleps, INS_vrndscalepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, Scale, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefps, INS_vscalefpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, ShiftRightArithmetic, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsraq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, ShiftRightArithmeticVariable, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsravq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) + +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX512F.X64 Intrinsics +HARDWARE_INTRINSIC(AVX512F_X64, ConvertScalarToVector128Double, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtusi2sd64, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromSecondArg|HW_Flag_CopyUpperBits|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_X64, ConvertScalarToVector128Single, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtusi2ss64, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromSecondArg|HW_Flag_CopyUpperBits|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_X64, ConvertToUInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtss2usi, INS_vcvtsd2usi}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512F_X64, ConvertToUInt64WithTruncation, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttss2usi, INS_vcvttsd2usi}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags @@ -887,10 +980,10 @@ HARDWARE_INTRINSIC(AVX512BW, AddSaturate, HARDWARE_INTRINSIC(AVX512BW, AlignRight, 64, 3, {INS_palignr, INS_palignr, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512BW, Average, 64, 2, {INS_invalid, INS_pavgb, INS_invalid, INS_pavgw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512BW, BroadcastScalarToVector512, 64, 1, {INS_vpbroadcastb, INS_vpbroadcastb, INS_vpbroadcastw, INS_vpbroadcastw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_MaybeMemoryLoad) -HARDWARE_INTRINSIC(AVX512BW, ConvertToVector128Byte, -1, 1, {INS_invalid, INS_invalid, INS_vpmovwb, INS_vpmovwb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AVX512BW, ConvertToVector128SByte, -1, 1, {INS_invalid, INS_invalid, INS_vpmovwb, INS_vpmovwb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512BW, ConvertToVector256Byte, 64, 1, {INS_invalid, INS_invalid, INS_vpmovwb, INS_vpmovwb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512BW, ConvertToVector256ByteWithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_vpmovuswb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512BW, ConvertToVector256SByte, 64, 1, {INS_invalid, INS_invalid, INS_vpmovwb, INS_vpmovwb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512BW, ConvertToVector256SByteWithSaturation, 64, 1, {INS_invalid, INS_invalid, INS_vpmovswb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512BW, ConvertToVector512Int16, 64, 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_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512BW, ConvertToVector512UInt16, 64, 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_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512BW, LoadVector512, 64, 1, {INS_vmovdqu8, INS_vmovdqu8, INS_vmovdqu16, INS_vmovdqu16, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) @@ -902,11 +995,15 @@ HARDWARE_INTRINSIC(AVX512BW, MultiplyHighRoundScale, HARDWARE_INTRINSIC(AVX512BW, MultiplyLow, 64, 2, {INS_invalid, INS_invalid, INS_pmullw, INS_pmullw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512BW, PackSignedSaturate, 64, 2, {INS_packsswb, INS_invalid, INS_packssdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, PackUnsignedSaturate, 64, 2, {INS_invalid, INS_packuswb, INS_invalid, INS_packusdw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512BW, PermuteVar32x16, 64, 2, {INS_invalid, INS_invalid, INS_vpermw, INS_vpermw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX512BW, ShiftLeftLogical, 64, 2, {INS_invalid, INS_invalid, INS_psllw, INS_psllw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512BW, ShiftLeftLogical128BitLane, 64, 2, {INS_pslldq, INS_pslldq, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512BW, ShiftLeftLogicalVariable, 64, 2, {INS_invalid, INS_invalid, INS_vpsllvw, INS_vpsllvw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, ShiftRightArithmetic, 64, 2, {INS_invalid, INS_invalid, INS_psraw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512BW, ShiftRightArithmeticVariable, 64, 2, {INS_invalid, INS_invalid, INS_vpsravw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, ShiftRightLogical, 64, 2, {INS_invalid, INS_invalid, INS_psrlw, INS_psrlw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512BW, ShiftRightLogical128BitLane, 64, 2, {INS_psrldq, INS_psrldq, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512BW, ShiftRightLogicalVariable, 64, 2, {INS_invalid, INS_invalid, INS_vpsrlvw, INS_vpsrlvw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, Shuffle, 64, 2, {INS_pshufb, INS_pshufb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, ShuffleHigh, 64, 2, {INS_invalid, INS_invalid, INS_pshufhw, INS_pshufhw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512BW, ShuffleLow, 64, 2, {INS_invalid, INS_invalid, INS_pshuflw, INS_pshuflw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) @@ -917,23 +1014,85 @@ HARDWARE_INTRINSIC(AVX512BW, SumAbsoluteDifferences, HARDWARE_INTRINSIC(AVX512BW, UnpackHigh, 64, 2, {INS_punpckhbw, INS_punpckhbw, INS_punpckhwd, INS_punpckhwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, UnpackLow, 64, 2, {INS_punpcklbw, INS_punpcklbw, INS_punpcklwd, INS_punpcklwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX512BW.VL Intrinsics +HARDWARE_INTRINSIC(AVX512BW_VL, ConvertToVector128Byte, -1, 1, {INS_invalid, INS_invalid, INS_vpmovwb, INS_vpmovwb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512BW_VL, ConvertToVector128ByteWithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_vpmovuswb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512BW_VL, ConvertToVector128SByte, -1, 1, {INS_invalid, INS_invalid, INS_vpmovwb, INS_vpmovwb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512BW_VL, ConvertToVector128SByteWithSaturation, -1, 1, {INS_invalid, INS_invalid, INS_vpmovswb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AVX512BW_VL, PermuteVar8x16 , 16, 2, {INS_invalid, INS_invalid, INS_vpermw, INS_vpermw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX512BW_VL, PermuteVar16x16, 32, 2, {INS_invalid, INS_invalid, INS_vpermw, INS_vpermw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX512BW_VL, ShiftLeftLogicalVariable, -1, 2, {INS_invalid, INS_invalid, INS_vpsllvw, INS_vpsllvw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512BW_VL, ShiftRightArithmeticVariable, -1, 2, {INS_invalid, INS_invalid, INS_vpsravw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512BW_VL, ShiftRightLogicalVariable, -1, 2, {INS_invalid, INS_invalid, INS_vpsrlvw, INS_vpsrlvw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) + // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // AVX512DQ Intrinsics -HARDWARE_INTRINSIC(AVX512DQ, And, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_andps, INS_andpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AVX512DQ, AndNot, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_andnps, INS_andnpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AVX512DQ, MultiplyLow, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmullq, INS_vpmullq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AVX512DQ, Or, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_orps, INS_orpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AVX512DQ, Xor, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_xorps, INS_xorpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512DQ, And, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_andps, INS_andpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512DQ, AndNot, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_andnps, INS_andnpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ, BroadcastPairScalarToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x2, INS_vbroadcasti32x2, INS_invalid, INS_invalid, INS_vbroadcastf32x2, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ, BroadcastVector128ToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti64x2, INS_vbroadcasti64x2, INS_invalid, INS_vbroadcastf64x2}, HW_Category_MemoryLoad, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ, BroadcastVector256ToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x8, INS_vbroadcasti32x8, INS_invalid, INS_invalid, INS_vbroadcastf32x8, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ, ConvertToVector256Single, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtqq2ps, INS_vcvtuqq2ps, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ, ConvertToVector512Double, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtqq2pd, INS_vcvtuqq2pd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ, ConvertToVector512Int64, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2qq, INS_vcvtpd2qq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ, ConvertToVector512Int64WithTruncation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2qq, INS_vcvttpd2qq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ, ConvertToVector512UInt64, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2uqq, INS_vcvtpd2uqq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ, ConvertToVector512UInt64WithTruncation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2uqq, INS_vcvttpd2uqq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ, ExtractVector128, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vextracti64x2, INS_vextracti64x2, INS_invalid, INS_vextractf64x2}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512DQ, ExtractVector256, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vextracti32x8, INS_vextracti32x8, INS_invalid, INS_invalid, INS_vextractf32x8, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512DQ, InsertVector128, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vinserti64x2, INS_vinserti64x2, INS_invalid, INS_vinsertf64x2}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512DQ, InsertVector256, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vinserti32x8, INS_vinserti32x8, INS_invalid, INS_invalid, INS_vinsertf32x8, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512DQ, MultiplyLow, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmullq, INS_vpmullq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512DQ, Or, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_orps, INS_orpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512DQ, Range, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrangeps, INS_vrangepd}, HW_Category_IMM, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ, RangeScalar, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrangess, INS_vrangesd}, HW_Category_IMM, HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512DQ, Reduce, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vreduceps, INS_vreducepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512DQ, ReduceScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vreducess, INS_vreducesd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512DQ, Xor, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_xorps, INS_xorpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // AVX512DQ.VL Intrinsics -HARDWARE_INTRINSIC(AVX512DQ_VL, MultiplyLow, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmullq, INS_vpmullq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512DQ_VL, BroadcastPairScalarToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x2, INS_vbroadcasti32x2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ_VL, BroadcastPairScalarToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x2, INS_vbroadcasti32x2, INS_invalid, INS_invalid, INS_vbroadcastf32x2, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector128Double, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtqq2pd, INS_vcvtuqq2pd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector128Int64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2qq, INS_vcvtpd2qq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector128Int64WithTruncation, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2qq, INS_vcvttpd2qq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector128Single, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtqq2ps, INS_vcvtuqq2ps, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector128UInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2uqq, INS_vcvtpd2uqq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector128UInt64WithTruncation, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2uqq, INS_vcvttpd2uqq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector256Double, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtqq2pd, INS_vcvtuqq2pd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector256Int64, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2qq, INS_vcvtpd2qq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector256Int64WithTruncation, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2qq, INS_vcvttpd2qq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector256UInt64, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2uqq, INS_vcvtpd2uqq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, ConvertToVector256UInt64WithTruncation, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2uqq, INS_vcvttpd2uqq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512DQ_VL, Range, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrangeps, INS_vrangepd}, HW_Category_IMM, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512DQ_VL, Reduce, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vreduceps, INS_vreducepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512DQ_VL, MultiplyLow, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmullq, INS_vpmullq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) + +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX512VBMI Intrinsics +HARDWARE_INTRINSIC(AVX512VBMI, PermuteVar64x8, 64, 2, {INS_vpermb, INS_vpermb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) + +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX512VBMI.VL Intrinsics +HARDWARE_INTRINSIC(AVX512VBMI_VL, PermuteVar16x8, 16, 2, {INS_vpermb, INS_vpermb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX512VBMI_VL, PermuteVar32x8, 32, 2, {INS_vpermb, INS_vpermb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags @@ -1071,11 +1230,11 @@ HARDWARE_INTRINSIC(SSE41, PTEST, HARDWARE_INTRINSIC(AVX, PTEST, 0, 2, {INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_ptest, INS_vtestps, INS_vtestpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX512F, MoveMaskSpecial, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(AVX512F, CompareEqualSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_cmpps, INS_cmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(AVX512F, CompareGreaterThanOrEqualSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_cmpps, INS_cmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(AVX512F, CompareGreaterThanSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_cmpps, INS_cmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(AVX512F, CompareLessThanOrEqualSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_cmpps, INS_cmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(AVX512F, CompareLessThanSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_cmpps, INS_cmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(AVX512F, CompareEqualSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_vcmpps, INS_vcmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(AVX512F, CompareGreaterThanOrEqualSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_vcmpps, INS_vcmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(AVX512F, CompareGreaterThanSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_vcmpps, INS_vcmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(AVX512F, CompareLessThanOrEqualSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_vcmpps, INS_vcmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(AVX512F, CompareLessThanSpecial, 64, 2, {INS_vpcmpb, INS_vpcmpub, INS_vpcmpw, INS_vpcmpuw, INS_vpcmpd, INS_vpcmpud, INS_vpcmpq, INS_vpcmpuq, INS_vcmpps, INS_vcmppd}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX512F, MoveMaskToVectorSpecial, 64, 1, {INS_vpmovm2b, INS_vpmovm2b, INS_vpmovm2w, INS_vpmovm2w, INS_vpmovm2d, INS_vpmovm2d, INS_vpmovm2q, INS_vpmovm2q, INS_vpmovm2d, INS_vpmovm2q}, HW_Category_Special, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoContainment|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX512F, KORTEST, 0, 1, {INS_kortestq, INS_kortestq, INS_kortestd, INS_kortestd, INS_kortestw, INS_kortestw, INS_kortestb, INS_kortestb, INS_kortestw, INS_kortestb}, HW_Category_Special, HW_Flag_NoRMWSemantics) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 5f80754bb55ea4..3f259b6b0100d0 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -52,6 +52,10 @@ static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa) return InstructionSet_AVX512F_X64; case InstructionSet_AVX512F_VL: return InstructionSet_AVX512F_VL_X64; + case InstructionSet_AVX512VBMI: + return InstructionSet_AVX512VBMI_X64; + case InstructionSet_AVX512VBMI_VL: + return InstructionSet_AVX512VBMI_VL_X64; case InstructionSet_AVXVNNI: return InstructionSet_AVXVNNI_X64; case InstructionSet_AES: @@ -95,6 +99,8 @@ static CORINFO_InstructionSet VLVersionOfIsa(CORINFO_InstructionSet isa) return InstructionSet_AVX512DQ_VL; case InstructionSet_AVX512F: return InstructionSet_AVX512F_VL; + case InstructionSet_AVX512VBMI: + return InstructionSet_AVX512VBMI_VL; default: return InstructionSet_NONE; } @@ -141,6 +147,10 @@ static CORINFO_InstructionSet lookupInstructionSet(const char* className) { return InstructionSet_AVX512F; } + if (strcmp(className, "Avx512Vbmi") == 0) + { + return InstructionSet_AVX512VBMI; + } if (strcmp(className, "AvxVnni") == 0) { return InstructionSet_AVXVNNI; @@ -290,7 +300,21 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic id) case NI_AVX2_GatherVector256: case NI_AVX2_GatherMaskVector128: case NI_AVX2_GatherMaskVector256: + { + assert(!HWIntrinsicInfo::HasFullRangeImm(id)); return 8; + } + + case NI_AVX512F_GetMantissa: + case NI_AVX512F_GetMantissaScalar: + case NI_AVX512F_VL_GetMantissa: + case NI_AVX512DQ_Range: + case NI_AVX512DQ_RangeScalar: + case NI_AVX512DQ_VL_Range: + { + assert(!HWIntrinsicInfo::HasFullRangeImm(id)); + return 15; + } default: { @@ -447,6 +471,10 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa) case InstructionSet_AVX512DQ_VL: case InstructionSet_AVX512DQ_VL_X64: case InstructionSet_AVX512DQ_X64: + case InstructionSet_AVX512VBMI: + case InstructionSet_AVX512VBMI_VL: + case InstructionSet_AVX512VBMI_VL_X64: + case InstructionSet_AVX512VBMI_X64: case InstructionSet_AVXVNNI: case InstructionSet_AVXVNNI_X64: case InstructionSet_BMI1: @@ -612,6 +640,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { case NI_Vector128_Abs: case NI_Vector256_Abs: + case NI_Vector512_Abs: { assert(sig->numArgs == 1); @@ -960,11 +989,12 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Ceiling: case NI_Vector256_Ceiling: + case NI_Vector512_Ceiling: { assert(sig->numArgs == 1); assert(varTypeIsFloating(simdBaseType)); - if ((simdSize != 32) && !compExactlyDependsOn(InstructionSet_SSE41)) + if ((simdSize < 32) && !compExactlyDependsOn(InstructionSet_SSE41)) { // Ceiling is only supported for floating-point types on SSE4.1 or later break; @@ -1253,7 +1283,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { op1 = nodeBuilder.GetOperand(0); GenTree* op1Address = CreateAddressNodeForSimdHWIntrinsicCreate(op1, simdBaseType, simdSize); - retNode = gtNewOperNode(GT_IND, retType, op1Address); + retNode = gtNewIndir(retType, op1Address); } else { @@ -1568,13 +1598,14 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Floor: case NI_Vector256_Floor: + case NI_Vector512_Floor: { assert(sig->numArgs == 1); assert(varTypeIsFloating(simdBaseType)); - if ((simdSize != 32) && !compExactlyDependsOn(InstructionSet_SSE41)) + if ((simdSize < 32) && !compExactlyDependsOn(InstructionSet_SSE41)) { - // Ceiling is only supported for floating-point types on SSE4.1 or later + // Floor is only supported for floating-point types on SSE4.1 or later break; } @@ -1935,6 +1966,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Max: case NI_Vector256_Max: + case NI_Vector512_Max: { assert(sig->numArgs == 2); @@ -1950,6 +1982,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Min: case NI_Vector256_Min: + case NI_Vector512_Min: { assert(sig->numArgs == 2); @@ -2036,8 +2069,10 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Negate: case NI_Vector256_Negate: + case NI_Vector512_Negate: case NI_Vector128_op_UnaryNegation: case NI_Vector256_op_UnaryNegation: + case NI_Vector512_op_UnaryNegation: { assert(sig->numArgs == 1); @@ -2098,6 +2133,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_op_UnaryPlus: case NI_Vector256_op_UnaryPlus: + case NI_Vector512_op_UnaryPlus: { assert(sig->numArgs == 1); retNode = impSIMDPopStack(); @@ -2211,9 +2247,10 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Shuffle: case NI_Vector256_Shuffle: + case NI_Vector512_Shuffle: { assert((sig->numArgs == 2) || (sig->numArgs == 3)); - assert((simdSize == 16) || (simdSize == 32)); + assert((simdSize == 16) || (simdSize == 32) || (simdSize == 64)); GenTree* indices = impStackTop(0).val; @@ -2269,6 +2306,14 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } } } + else if (simdSize == 64) + { + if (varTypeIsByte(simdBaseType)) + { + // TYP_BYTE, TYP_UBYTE need AVX512VBMI. + break; + } + } else { assert(simdSize == 16); @@ -2292,6 +2337,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Sqrt: case NI_Vector256_Sqrt: + case NI_Vector512_Sqrt: { assert(sig->numArgs == 1); @@ -2864,6 +2910,15 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } case NI_AVX2_PermuteVar8x32: + case NI_AVX512BW_PermuteVar32x16: + case NI_AVX512BW_VL_PermuteVar8x16: + case NI_AVX512BW_VL_PermuteVar16x16: + case NI_AVX512F_PermuteVar8x64: + case NI_AVX512F_PermuteVar16x32: + case NI_AVX512F_VL_PermuteVar4x64: + case NI_AVX512VBMI_PermuteVar64x8: + case NI_AVX512VBMI_VL_PermuteVar16x8: + case NI_AVX512VBMI_VL_PermuteVar32x8: { simdBaseJitType = getBaseJitTypeOfSIMDType(sig->retTypeSigClass); @@ -2871,11 +2926,10 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); // swap the two operands - GenTree* indexVector = impSIMDPopStack(); - GenTree* sourceVector = impSIMDPopStack(); + GenTree* idxVector = impSIMDPopStack(); + GenTree* srcVector = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD32, indexVector, sourceVector, NI_AVX2_PermuteVar8x32, - simdBaseJitType, 32); + retNode = gtNewSimdHWIntrinsicNode(retType, idxVector, srcVector, intrinsic, simdBaseJitType, simdSize); break; } diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index d7194d36c0df12..c7441458556bc4 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -144,7 +144,7 @@ bool OptIfConversionDsc::IfConvertCheckThenFlow() } else { - m_mainOper = GT_ASG; + m_mainOper = GT_STORE_LCL_VAR; } return true; } @@ -233,19 +233,16 @@ bool OptIfConversionDsc::IfConvertCheckStmts(BasicBlock* fromBlock, IfConvertOpe GenTree* tree = stmt->GetRootNode(); switch (tree->gtOper) { - case GT_ASG: + case GT_STORE_LCL_VAR: { - GenTree* op1 = tree->gtGetOp1(); - GenTree* op2 = tree->gtGetOp2(); - // Only one per operation per block can be conditionally executed. if (found) { return false; } - // Ensure the operarand is a local variable with integer type. - if (!op1->OperIs(GT_LCL_VAR) || !varTypeIsIntegralOrI(op1)) + // Ensure the local has integer type. + if (!varTypeIsIntegralOrI(tree)) { return false; } @@ -258,16 +255,16 @@ bool OptIfConversionDsc::IfConvertCheckStmts(BasicBlock* fromBlock, IfConvertOpe return false; } #endif + GenTree* op1 = tree->AsLclVar()->Data(); // Ensure it won't cause any additional side effects. - if ((op1->gtFlags & (GTF_SIDE_EFFECT | GTF_ORDER_SIDEEFF)) != 0 || - (op2->gtFlags & (GTF_SIDE_EFFECT | GTF_ORDER_SIDEEFF)) != 0) + if ((op1->gtFlags & (GTF_SIDE_EFFECT | GTF_ORDER_SIDEEFF)) != 0) { return false; } // Ensure the source isn't a phi. - if (op2->OperIs(GT_PHI)) + if (op1->OperIs(GT_PHI)) { return false; } @@ -276,7 +273,7 @@ bool OptIfConversionDsc::IfConvertCheckStmts(BasicBlock* fromBlock, IfConvertOpe // with the condition (for example, the condition could be an explicit bounds // check and the operand could read an array element). Disallow this except // for some common cases that we know are always side effect free. - if (((m_cond->gtFlags & GTF_ORDER_SIDEEFF) != 0) && !op2->IsInvariant() && !op2->OperIsLocal()) + if (((m_cond->gtFlags & GTF_ORDER_SIDEEFF) != 0) && !op1->IsInvariant() && !op1->OperIsLocal()) { return false; } @@ -424,7 +421,7 @@ void OptIfConversionDsc::IfConvertDump() // // This is represented in IR by two basic blocks. The first block (block) ends with // a JTRUE statement which conditionally jumps to the second block (thenBlock). -// The second block just contains a single assign statement. Both blocks then jump +// The second block just contains a single store statement. Both blocks then jump // to the same destination (finalBlock). Note that the first block may contain // additional statements prior to the JTRUE statement. // @@ -439,15 +436,14 @@ void OptIfConversionDsc::IfConvertDump() // // ------------ BB04 [00D..010), preds={BB03} succs={BB05} // STMT00005 -// * ASG int $VN.Void -// +--* LCL_VAR int V00 arg0 -// \--* CNS_INT int 5 $47 +// * STORE_LCL_VAR int V00 arg0 +// \--* CNS_INT int 5 $47 // // // This is optimised by conditionally executing the store and removing the conditional -// jumps. First the JTRUE is replaced with a NOP. The assignment is updated so that -// the source of the store is a SELECT node with the condition set to the inverse of -// the original JTRUE condition. If the condition passes the original assign happens, +// jumps. First the JTRUE is replaced with a NOP. The store is updated so that the +// source of the store is a SELECT node with the condition set to the inverse of the +// original JTRUE condition. If the condition passes the original store happens, // otherwise the existing source value is used. // // In the example above, local var 0 is set to 5 if the LT returns true, otherwise @@ -458,8 +454,7 @@ void OptIfConversionDsc::IfConvertDump() // * NOP void // // STMT00005 -// * ASG int $VN.Void -// +--* LCL_VAR int V00 arg0 +// * STORE_LCL_VAR int V00 arg0 // \--* SELECT int // +--* LT int $102 // | +--* LCL_VAR int V02 @@ -485,15 +480,13 @@ void OptIfConversionDsc::IfConvertDump() // // ------------ BB04 [00D..010), preds={BB03} succs={BB06} // STMT00005 -// * ASG int $VN.Void -// +--* LCL_VAR int V00 arg0 -// \--* CNS_INT int 5 $47 +// * STORE_LCL_VAR int V00 arg0 +// \--* CNS_INT int 5 $47 // // ------------ BB05 [00D..010), preds={BB03} succs={BB06} // STMT00006 -// * ASG int $VN.Void -// +--* LCL_VAR int V00 arg0 -// \--* CNS_INT int 9 $48 +// * STORE_LCL_VAR int V00 arg0 +// \--* CNS_INT int 9 $48 // // Again this is squashed into a single block, with the SELECT node handling both cases. // @@ -502,8 +495,7 @@ void OptIfConversionDsc::IfConvertDump() // * NOP void // // STMT00005 -// * ASG int $VN.Void -// +--* LCL_VAR int V00 arg0 +// * STORE_LCL_VAR int V00 arg0 // \--* SELECT int // +--* LT int $102 // | +--* LCL_VAR int V02 @@ -587,7 +579,7 @@ bool OptIfConversionDsc::optIfConvert() { return false; } - assert(m_thenOperation.node->gtOper == GT_ASG || m_thenOperation.node->gtOper == GT_RETURN); + assert(m_thenOperation.node->OperIs(GT_STORE_LCL_VAR, GT_RETURN)); if (m_doElseConversion) { if (!IfConvertCheckStmts(m_startBlock->bbJumpDest, &m_elseOperation)) @@ -596,16 +588,16 @@ bool OptIfConversionDsc::optIfConvert() } // Both operations must be the same node type. - if (m_thenOperation.node->gtOper != m_elseOperation.node->gtOper) + if (m_thenOperation.node->OperGet() != m_elseOperation.node->OperGet()) { return false; } - // Currently can only support Else Asg Blocks that have the same destination as the Then block. - if (m_thenOperation.node->gtOper == GT_ASG) + // Currently can only support Else Store Blocks that have the same destination as the Then block. + if (m_thenOperation.node->OperIs(GT_STORE_LCL_VAR)) { - unsigned lclNumThen = m_thenOperation.node->gtGetOp1()->AsLclVarCommon()->GetLclNum(); - unsigned lclNumElse = m_elseOperation.node->gtGetOp1()->AsLclVarCommon()->GetLclNum(); + unsigned lclNumThen = m_thenOperation.node->AsLclVarCommon()->GetLclNum(); + unsigned lclNumElse = m_elseOperation.node->AsLclVarCommon()->GetLclNum(); if (lclNumThen != lclNumElse) { return false; @@ -633,14 +625,14 @@ bool OptIfConversionDsc::optIfConvert() int thenCost = 0; int elseCost = 0; - if (m_mainOper == GT_ASG) + if (m_mainOper == GT_STORE_LCL_VAR) { - thenCost = m_thenOperation.node->gtGetOp2()->GetCostEx() + - (m_comp->gtIsLikelyRegVar(m_thenOperation.node->gtGetOp1()) ? 0 : 2); + thenCost = m_thenOperation.node->AsLclVar()->Data()->GetCostEx() + + (m_comp->gtIsLikelyRegVar(m_thenOperation.node) ? 0 : 2); if (m_doElseConversion) { - elseCost = m_elseOperation.node->gtGetOp2()->GetCostEx() + - (m_comp->gtIsLikelyRegVar(m_elseOperation.node->gtGetOp1()) ? 0 : 2); + elseCost = m_elseOperation.node->AsLclVar()->Data()->GetCostEx() + + (m_comp->gtIsLikelyRegVar(m_elseOperation.node) ? 0 : 2); } } else @@ -685,25 +677,22 @@ bool OptIfConversionDsc::optIfConvert() var_types selectType; GenTree* selectTrueInput; GenTree* selectFalseInput; - if (m_mainOper == GT_ASG) + if (m_mainOper == GT_STORE_LCL_VAR) { if (m_doElseConversion) { - selectTrueInput = m_elseOperation.node->gtGetOp2(); - selectFalseInput = m_thenOperation.node->gtGetOp2(); + selectTrueInput = m_elseOperation.node->AsLclVar()->Data(); + selectFalseInput = m_thenOperation.node->AsLclVar()->Data(); } - else + else // Duplicate the destination of the Then store. { - // Duplicate the destination of the Then assignment. - assert(m_thenOperation.node->gtGetOp1()->IsLocal()); - selectTrueInput = m_comp->gtCloneExpr(m_thenOperation.node->gtGetOp1()); - selectTrueInput->gtFlags &= GTF_EMPTY; - - selectFalseInput = m_thenOperation.node->gtGetOp2(); + GenTreeLclVar* store = m_thenOperation.node->AsLclVar(); + selectTrueInput = m_comp->gtNewLclVarNode(store->GetLclNum(), store->TypeGet()); + selectFalseInput = m_thenOperation.node->AsLclVar()->Data(); } // Pick the type as the type of the local, which should always be compatible even for implicit coercions. - selectType = genActualType(m_thenOperation.node->gtGetOp1()); + selectType = genActualType(m_thenOperation.node); } else { @@ -719,12 +708,12 @@ bool OptIfConversionDsc::optIfConvert() // Create a select node. GenTreeConditional* select = m_comp->gtNewConditionalNode(GT_SELECT, m_cond, selectTrueInput, selectFalseInput, selectType); - m_thenOperation.node->AsOp()->gtFlags |= (select->gtFlags & GTF_ALL_EFFECT); + m_thenOperation.node->AddAllEffectsFlags(select); // Use the select as the source of the Then operation. - if (m_mainOper == GT_ASG) + if (m_mainOper == GT_STORE_LCL_VAR) { - m_thenOperation.node->AsOp()->gtOp2 = select; + m_thenOperation.node->AsLclVar()->Data() = select; } else { @@ -734,12 +723,12 @@ bool OptIfConversionDsc::optIfConvert() m_comp->fgSetStmtSeq(m_thenOperation.stmt); // Remove statements. - last->ReplaceWith(m_comp->gtNewNothingNode(), m_comp); + last->gtBashToNOP(); m_comp->gtSetEvalOrder(last); m_comp->fgSetStmtSeq(m_startBlock->lastStmt()); if (m_doElseConversion) { - m_elseOperation.node->ReplaceWith(m_comp->gtNewNothingNode(), m_comp); + m_elseOperation.node->gtBashToNOP(); m_comp->gtSetEvalOrder(m_elseOperation.node); m_comp->fgSetStmtSeq(m_elseOperation.stmt); } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 719736da378720..513f2fc2bb2d15 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -930,7 +930,7 @@ GenTree* Compiler::impAssignStruct(GenTree* dest, BasicBlock* block /* = nullptr */ ) { - assert(varTypeIsStruct(dest) && (dest->OperIsLocal() || dest->OperIsIndir() || dest->OperIs(GT_FIELD))); + assert(varTypeIsStruct(dest) && (dest->OperIsLocal() || dest->OperIsIndir())); assert(dest->TypeGet() == src->TypeGet()); if (dest->TypeIs(TYP_STRUCT)) @@ -1084,11 +1084,11 @@ GenTree* Compiler::impAssignStruct(GenTree* dest, assert(OFFSETOF__CORINFO_TypedReference__dataPtr == 0); assert(destAddr->gtType == TYP_I_IMPL || destAddr->gtType == TYP_BYREF); - GenTree* ptrSlot = gtNewOperNode(GT_IND, TYP_I_IMPL, destAddr); + GenTree* ptrSlot = gtNewIndir(TYP_I_IMPL, destAddr); GenTreeIntCon* typeFieldOffset = gtNewIconNode(OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL); GenTree* typeSlot = - gtNewOperNode(GT_IND, TYP_I_IMPL, gtNewOperNode(GT_ADD, destAddr->gtType, destAddrClone, typeFieldOffset)); + gtNewIndir(TYP_I_IMPL, gtNewOperNode(GT_ADD, destAddr->gtType, destAddrClone, typeFieldOffset)); // append the assign of the pointer value GenTree* asg = gtNewAssignNode(ptrSlot, src->AsOp()->gtOp1); @@ -1207,7 +1207,14 @@ GenTree* Compiler::impGetStructAddr(GenTree* structVal, case GT_IND: if (willDeref) { - return structVal->AsIndir()->Addr(); + GenTree* addr = structVal->AsIndir()->Addr(); + if (addr->OperIs(GT_FIELD_ADDR)) + { + // TODO-FIELD: delete this zero-diff quirk. + addr->gtFlags &= ~GTF_FLD_DEREFERENCED; + } + + return addr; } break; @@ -1217,49 +1224,9 @@ GenTree* Compiler::impGetStructAddr(GenTree* structVal, case GT_LCL_FLD: return gtNewLclAddrNode(structVal->AsLclFld()->GetLclNum(), structVal->AsLclFld()->GetLclOffs(), TYP_BYREF); - case GT_FIELD: - { - GenTreeField* fieldNode = structVal->AsField(); - GenTreeField* fieldAddr = - new (this, GT_FIELD_ADDR) GenTreeField(GT_FIELD_ADDR, TYP_BYREF, fieldNode->GetFldObj(), - fieldNode->gtFldHnd, fieldNode->gtFldOffset); - fieldAddr->gtFldMayOverlap = fieldNode->gtFldMayOverlap; -#ifdef FEATURE_READYTORUN - fieldAddr->gtFieldLookup = fieldNode->gtFieldLookup; -#endif - return fieldAddr; - } - case GT_COMMA: - { - Statement* oldLastStmt = impLastStmt; - structVal->AsOp()->gtOp2 = impGetStructAddr(structVal->AsOp()->gtOp2, structHnd, curLevel, willDeref); - structVal->gtType = TYP_BYREF; - - if (oldLastStmt != impLastStmt) - { - // Some temp assignment statement was placed on the statement list - // for Op2, but that would be out of order with op1, so we need to - // spill op1 onto the statement list after whatever was last - // before we recursed on Op2 (i.e. before whatever Op2 appended). - Statement* beforeStmt; - if (oldLastStmt == nullptr) - { - // The op1 stmt should be the first in the list. - beforeStmt = impStmtList; - } - else - { - // Insert after the oldLastStmt before the first inserted for op2. - beforeStmt = oldLastStmt->GetNextStmt(); - } - - impInsertTreeBefore(structVal->AsOp()->gtOp1, impCurStmtDI, beforeStmt); - structVal->AsOp()->gtOp1 = gtNewNothingNode(); - } - - return structVal; - } + impAppendTree(structVal->AsOp()->gtGetOp1(), curLevel, impCurStmtDI); + return impGetStructAddr(structVal->AsOp()->gtGetOp2(), structHnd, curLevel, willDeref); default: break; @@ -1327,57 +1294,38 @@ var_types Compiler::impNormStructType(CORINFO_CLASS_HANDLE structHnd, CorInfoTyp } //------------------------------------------------------------------------ -// Compiler::impNormStructVal: Normalize a struct value +// impNormStructVal: Normalize a struct call argument // -// Arguments: -// structVal - the node we are going to normalize -// structHnd - the class handle for the node -// curLevel - the current stack level +// Spills call-like STRUCT arguments to temporaries. "Unwraps" commas. // -// Notes: -// Given struct value 'structVal', make sure it is 'canonical', that is -// it is either: -// - a known struct type (non-TYP_STRUCT, e.g. TYP_SIMD8) -// - a BLK or a MKREFANY node, or -// - a node (e.g. GT_FIELD) that will be morphed. -// If the node is a CALL or RET_EXPR, a copy will be made to a new temp. +// Arguments: +// structVal - The node to normalize +// structHnd - The struct type +// curLevel - The current stack level +// +// Return Value: +// The normalized "structVal". // GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE structHnd, unsigned curLevel) { assert(varTypeIsStruct(structVal)); - assert(structHnd != NO_CLASS_HANDLE); var_types structType = structVal->TypeGet(); - bool makeTemp = false; - if (structType == TYP_STRUCT) - { - structType = impNormStructType(structHnd); - } - GenTreeLclVarCommon* structLcl = nullptr; switch (structVal->OperGet()) { case GT_CALL: case GT_RET_EXPR: - makeTemp = true; - break; + { + unsigned lclNum = lvaGrabTemp(true DEBUGARG("spilled call-like call argument")); + impAssignTempGen(lclNum, structVal, curLevel); - case GT_LCL_VAR: - case GT_LCL_FLD: - case GT_IND: - case GT_BLK: - case GT_FIELD: - case GT_CNS_VEC: -#ifdef FEATURE_HW_INTRINSICS - case GT_HWINTRINSIC: -#endif - case GT_MKREFANY: - // These should already have the appropriate type. - assert(structVal->TypeGet() == structType); - break; + // The structVal is now the temp itself + structVal = gtNewLclvNode(lclNum, structType); + } + break; case GT_COMMA: { - // The second thing could either be a block node or a GT_FIELD or a GT_COMMA node. GenTree* blockNode = structVal->AsOp()->gtOp2; assert(blockNode->gtType == structType); @@ -1394,16 +1342,8 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str } while (blockNode->OperGet() == GT_COMMA); } -#ifdef FEATURE_SIMD - if (blockNode->OperIsHWIntrinsic() || blockNode->IsCnsVec()) - { - parent->AsOp()->gtOp2 = impNormStructVal(blockNode, structHnd, curLevel); - } - else -#endif + if (blockNode->OperIsBlk()) { - noway_assert(blockNode->OperIsIndir() || blockNode->OperIs(GT_FIELD)); - // Sink the GT_COMMA below the blockNode addr. // That is GT_COMMA(op1, op2=blockNode) is transformed into // blockNode(GT_COMMA(TYP_BYREF, op1, op2's op1)). @@ -1416,6 +1356,7 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str commaNode->gtType = blockNodeAddr->gtType; commaNode->AsOp()->gtOp2 = blockNodeAddr; blockNode->AsOp()->gtOp1 = commaNode; + blockNode->AddAllEffectsFlags(commaNode); if (parent == structVal) { structVal = blockNode; @@ -1425,36 +1366,9 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str break; default: - noway_assert(!"Unexpected node in impNormStructVal()"); break; } - if (makeTemp) - { - unsigned tmpNum = lvaGrabTemp(true DEBUGARG("struct address for call/obj")); - - impAssignTempGen(tmpNum, structVal, structHnd, curLevel); - - // The structVal is now the temp itself - - structLcl = gtNewLclvNode(tmpNum, structType)->AsLclVarCommon(); - structVal = structLcl; - } - - if (structLcl != nullptr) - { - // A BLK on a ADDR(LCL_VAR) can never raise an exception - // so we don't set GTF_EXCEPT here. - if (!lvaIsImplicitByRefLocal(structLcl->GetLclNum())) - { - structVal->gtFlags &= ~GTF_GLOB_REF; - } - } - else if (structVal->OperIsBlk()) - { - // In general a BLK is an indirection and could raise an exception. - structVal->gtFlags |= GTF_EXCEPT; - } return structVal; } @@ -1847,8 +1761,7 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken if (i != 0) { - slotPtrTree = gtNewOperNode(GT_IND, TYP_I_IMPL, slotPtrTree); - slotPtrTree->gtFlags |= (GTF_IND_NONFAULTING | GTF_IND_INVARIANT); + slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); } if ((i == 1 && pRuntimeLookup->indirectFirstOffset) || (i == 2 && pRuntimeLookup->indirectSecondOffset)) @@ -1871,8 +1784,8 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken return slotPtrTree; } - slotPtrTree = gtNewOperNode(GT_IND, TYP_I_IMPL, slotPtrTree); - slotPtrTree->gtFlags |= GTF_IND_NONFAULTING; + slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, GTF_IND_NONFAULTING); + slotPtrTree->gtFlags &= ~GTF_GLOB_REF; // TODO-Bug?: this is a quirk. Can we mark this indirection invariant? return slotPtrTree; } @@ -1943,14 +1856,18 @@ bool Compiler::impSpillStackEntry(unsigned level, /* Assign the spilled entry to the temp */ impAssignTempGen(tnum, tree, verCurrentState.esStack[level].seTypeInfo.GetClassHandle(), level); - // If temp is newly introduced and a ref type, grab what type info we can. - if (isNewTemp && (lvaTable[tnum].lvType == TYP_REF)) + if (isNewTemp) { assert(lvaTable[tnum].lvSingleDef == 0); lvaTable[tnum].lvSingleDef = 1; JITDUMP("Marked V%02u as a single def temp\n", tnum); - CORINFO_CLASS_HANDLE stkHnd = verCurrentState.esStack[level].seTypeInfo.GetClassHandle(); - lvaSetClass(tnum, tree, stkHnd); + + // If temp is newly introduced and a ref type, grab what type info we can. + if (lvaTable[tnum].lvType == TYP_REF) + { + CORINFO_CLASS_HANDLE stkHnd = verCurrentState.esStack[level].seTypeInfo.GetClassHandle(); + lvaSetClass(tnum, tree, stkHnd); + } // If we're assigning a GT_RET_EXPR, note the temp over on the call, // so the inliner can use it in case it needs a return spill temp. @@ -3345,18 +3262,13 @@ int Compiler::impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken, if (castResult == TypeCompareState::Must) { - const CORINFO_FIELD_HANDLE hasValueFldHnd = - info.compCompHnd->getFieldInClass(nullableCls, 0); - - assert(info.compCompHnd->getFieldOffset(hasValueFldHnd) == 0); - GenTree* objToBox = impPopStack().val; // Spill struct to get its address (to access hasValue field) objToBox = impGetStructAddr(objToBox, nullableCls, CHECK_SPILL_ALL, true); + static_assert_no_msg(OFFSETOF__CORINFO_NullableOfT__hasValue == 0); - impPushOnStack(gtNewFieldRef(TYP_BOOL, hasValueFldHnd, objToBox, 0), - typeInfo(TI_INT)); + impPushOnStack(gtNewIndir(TYP_BOOL, objToBox), typeInfo(TI_INT)); JITDUMP("\n Importing BOX; ISINST; BR_TRUE/FALSE as nullableVT.hasValue\n"); return 1 + sizeof(mdToken); @@ -3666,7 +3578,8 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken) exprToBox = gtNewCastNode(genActualType(dstTyp), exprToBox, false, dstTyp); } - op1 = gtNewAssignNode(gtNewOperNode(GT_IND, dstTyp, op1), exprToBox); + op1 = gtNewIndir(dstTyp, op1, GTF_IND_NONFAULTING); + op1 = gtNewAssignNode(op1, exprToBox); } // Spill eval stack to flush out any pending side effects. @@ -3869,7 +3782,7 @@ GenTree* Compiler::impImportStaticReadOnlyField(CORINFO_FIELD_HANDLE field, CORI if (varTypeIsIntegral(fieldType) || varTypeIsFloating(fieldType) || (fieldType == TYP_REF)) { assert(bufferSize >= genTypeSize(fieldType)); - if (info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, genTypeSize(fieldType))) + if (info.compCompHnd->getStaticFieldContent(field, buffer, genTypeSize(fieldType))) { GenTree* cnsValue = impImportCnsTreeFromBuffer(buffer, fieldType); if (cnsValue != nullptr) @@ -3899,7 +3812,7 @@ GenTree* Compiler::impImportStaticReadOnlyField(CORINFO_FIELD_HANDLE field, CORI } uint8_t buffer[MaxStructSize] = {0}; - if (info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, totalSize)) + if (info.compCompHnd->getStaticFieldContent(field, buffer, totalSize)) { #ifdef FEATURE_SIMD // First, let's check whether field is a SIMD vector and import it as GT_CNS_VEC @@ -3949,7 +3862,7 @@ GenTree* Compiler::impImportStaticReadOnlyField(CORINFO_FIELD_HANDLE field, CORI return gtNewLclvNode(structTempNum, realType); } - JITDUMP("getReadonlyStaticFieldValue returned false - bail out."); + JITDUMP("getStaticFieldContent returned false - bail out."); return nullptr; } @@ -3980,7 +3893,7 @@ GenTree* Compiler::impImportStaticReadOnlyField(CORINFO_FIELD_HANDLE field, CORI const int bufferSize = TARGET_POINTER_SIZE; uint8_t buffer[bufferSize] = {0}; - if ((totalSize > bufferSize) || !info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, totalSize)) + if ((totalSize > bufferSize) || !info.compCompHnd->getStaticFieldContent(field, buffer, totalSize)) { return nullptr; } @@ -4098,19 +4011,35 @@ GenTree* Compiler::impImportCnsTreeFromBuffer(uint8_t* buffer, var_types valueTy return tree; } +//------------------------------------------------------------------------ +// impImportStaticFieldAccess: Generate an access of a static field +// +// Arguments: +// pResolvedToken - resolved token for the static field to access +// access - type of access to the field, distinguishes address-taken vs load/store +// pFieldInfo - EE instructions for accessing the field +// lclTyp - type of the field +// pIsHoistable - optional out parameter - whether any type initialization side effects +// of the returned tree can be hoisted to occur earlier +// +// Return Value: +// Tree representing the access to the static field +// +// Notes: +// Ordinary static fields never overlap. RVA statics, however, can overlap (if they're +// mapped to the same ".data" declaration). That said, such mappings only appear to be +// possible with ILASM, and in ILASM-produced (ILONLY) images, RVA statics are always +// read-only (using "stsfld" on them is UB). In mixed-mode assemblies, RVA statics can +// be mutable, but the only current producer of such images, the C++/CLI compiler, does +// not appear to support mapping different fields to the same address. So we will say +// that "mutable overlapping RVA statics" are UB as well. + GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_ACCESS_FLAGS access, CORINFO_FIELD_INFO* pFieldInfo, - var_types lclTyp) + var_types lclTyp, + /* OUT */ bool* pIsHoistable) { - // Ordinary static fields never overlap. RVA statics, however, can overlap (if they're - // mapped to the same ".data" declaration). That said, such mappings only appear to be - // possible with ILASM, and in ILASM-produced (ILONLY) images, RVA statics are always - // read-only (using "stsfld" on them is UB). In mixed-mode assemblies, RVA statics can - // be mutable, but the only current producer of such images, the C++/CLI compiler, does - // not appear to support mapping different fields to the same address. So we will say - // that "mutable overlapping RVA statics" are UB as well. - // For statics that are not "boxed", the initial address tree will contain the field sequence. // For those that are, we will attach it later, when adding the indirection for the box, since // that tree will represent the true address. @@ -4151,9 +4080,11 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT outerFldSeq = nullptr; } - bool isStaticReadOnlyInitedRef = false; - unsigned typeIndex = 0; - GenTree* op1; + bool isHoistable = false; + bool isStaticReadOnlyInitedRef = false; + GenTreeFlags indirFlags = GTF_EMPTY; + unsigned typeIndex = 0; + GenTree* op1; switch (pFieldInfo->fieldAccessor) { case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER: @@ -4182,6 +4113,8 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT break; } + isHoistable = !s_helperCallProperties.MayRunCctor(pFieldInfo->helper) || + (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_BEFOREFIELDINIT); op1 = gtNewHelperCallNode(pFieldInfo->helper, type, op1); op1 = gtNewOperNode(GT_ADD, type, op1, gtNewIconNode(pFieldInfo->offset, innerFldSeq)); } @@ -4199,8 +4132,10 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT { GenTreeFlags callFlags = GTF_EMPTY; - if (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_BEFOREFIELDINIT) + if (!s_helperCallProperties.MayRunCctor(pFieldInfo->helper) || + (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_BEFOREFIELDINIT)) { + isHoistable = true; callFlags |= GTF_CALL_HOISTABLE; } @@ -4225,7 +4160,8 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT else #endif { - op1 = fgGetStaticsCCtorHelper(pResolvedToken->hClass, pFieldInfo->helper, typeIndex); + op1 = fgGetStaticsCCtorHelper(pResolvedToken->hClass, pFieldInfo->helper, typeIndex); + isHoistable = isHoistable || (op1->gtFlags & GTF_CALL_HOISTABLE); } op1 = gtNewOperNode(GT_ADD, op1->TypeGet(), op1, gtNewIconNode(pFieldInfo->offset, innerFldSeq)); @@ -4249,6 +4185,7 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT op1 = gtNewIndOfIconHandleNode(TYP_I_IMPL, fldAddr, GTF_ICON_STATIC_ADDR_PTR, true); } GenTree* offset = gtNewIconNode(pFieldInfo->offset, innerFldSeq); + isHoistable = true; op1 = gtNewOperNode(GT_ADD, TYP_I_IMPL, op1, offset); #else unreached(); @@ -4267,14 +4204,17 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT GenTree* ctxTree = getRuntimeContextTree(kind.runtimeLookupKind); - GenTreeFlags callFlags = GTF_EMPTY; + CorInfoHelpFunc helper = CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE; + GenTreeFlags callFlags = GTF_EMPTY; - if (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_BEFOREFIELDINIT) + if (!s_helperCallProperties.MayRunCctor(helper) || + (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_BEFOREFIELDINIT)) { + isHoistable = true; callFlags |= GTF_CALL_HOISTABLE; } var_types type = TYP_BYREF; - op1 = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE, type, ctxTree); + op1 = gtNewHelperCallNode(helper, type, ctxTree); op1->gtFlags |= callFlags; op1->AsCall()->setEntryPoint(pFieldInfo->fieldLookup); @@ -4317,11 +4257,12 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT { handleKind = GTF_ICON_STATIC_HDL; } - op1 = gtNewIconHandleNode(fldAddr, handleKind, innerFldSeq); + isHoistable = true; + op1 = gtNewIconHandleNode(fldAddr, handleKind, innerFldSeq); INDEBUG(op1->AsIntCon()->gtTargetHandle = reinterpret_cast(pResolvedToken->hField)); if (pFieldInfo->fieldFlags & CORINFO_FLG_FIELD_INITCLASS) { - op1->gtFlags |= GTF_ICON_INITCLASS; + indirFlags |= GTF_IND_INITCLASS; } break; } @@ -4329,8 +4270,9 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT if (isBoxedStatic) { - op1 = gtNewIndir(TYP_REF, op1, GTF_IND_INVARIANT | GTF_IND_NONFAULTING | GTF_IND_NONNULL); - op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, gtNewIconNode(TARGET_POINTER_SIZE, outerFldSeq)); + op1 = gtNewIndir(TYP_REF, op1, GTF_IND_INVARIANT | GTF_IND_NONFAULTING | GTF_IND_NONNULL | indirFlags); + indirFlags = GTF_EMPTY; + op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, gtNewIconNode(TARGET_POINTER_SIZE, outerFldSeq)); } if (!(access & CORINFO_ACCESS_ADDRESS)) @@ -4339,21 +4281,18 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT lclTyp = TypeHandleToVarType(pFieldInfo->fieldType, pFieldInfo->structType, &layout); // TODO-CQ: mark the indirections non-faulting. - if (lclTyp == TYP_STRUCT) - { - op1 = gtNewBlkIndir(layout, op1); - } - else - { - op1 = gtNewOperNode(GT_IND, lclTyp, op1); - op1->gtFlags |= GTF_GLOB_REF; - } + op1 = (lclTyp == TYP_STRUCT) ? gtNewBlkIndir(layout, op1, indirFlags) : gtNewIndir(lclTyp, op1, indirFlags); + if (isStaticReadOnlyInitedRef) { op1->gtFlags |= (GTF_IND_INVARIANT | GTF_IND_NONFAULTING | GTF_IND_NONNULL); } } + if (pIsHoistable) + { + *pIsHoistable = isHoistable; + } return op1; } @@ -7179,6 +7118,13 @@ void Compiler::impImportBlockCode(BasicBlock* block) return; } + if (opts.OptimizationEnabled() && (gtGetArrayElementClassHandle(impStackTop(1).val) == ldelemClsHnd) && + impIsClassExact(ldelemClsHnd)) + { + JITDUMP("\nldelema of T[] with T exact: skipping covariant check\n"); + goto ARR_LD; + } + GenTree* index = impPopStack().val; GenTree* arr = impPopStack().val; @@ -8334,17 +8280,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) { // If the value being produced comes from loading // via an underlying address, just null check the address. - if (op1->OperIs(GT_FIELD, GT_IND, GT_BLK)) + if (op1->OperIs(GT_IND, GT_BLK)) { - GenTree* addr = op1->gtGetOp1(); - if ((addr != nullptr) && fgAddrCouldBeNull(addr)) - { - gtChangeOperToNullCheck(op1, block); - } - else - { - op1 = gtNewNothingNode(); - } + gtChangeOperToNullCheck(op1, block); } else { @@ -8428,12 +8366,12 @@ void Compiler::impImportBlockCode(BasicBlock* block) impAssignTempGen(tmpNum, op1, tiRetVal.GetClassHandle(), CHECK_SPILL_ALL); var_types type = genActualType(lvaTable[tmpNum].TypeGet()); + assert(lvaTable[tmpNum].lvSingleDef == 0); + lvaTable[tmpNum].lvSingleDef = 1; + JITDUMP("Marked V%02u as a single def local\n", tmpNum); // Propagate type info to the temp from the stack and the original tree if (type == TYP_REF) { - assert(lvaTable[tmpNum].lvSingleDef == 0); - lvaTable[tmpNum].lvSingleDef = 1; - JITDUMP("Marked V%02u as a single def local\n", tmpNum); lvaSetClass(tmpNum, tree, tiRetVal.GetClassHandle()); } @@ -8522,22 +8460,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) } #endif - op1 = gtNewOperNode(GT_IND, lclTyp, op1); - op1->gtFlags |= GTF_EXCEPT | GTF_GLOB_REF; - - if (prefixFlags & PREFIX_VOLATILE) - { - assert(op1->OperGet() == GT_IND); - op1->gtFlags |= GTF_ORDER_SIDEEFF; // Prevent this from being reordered - op1->gtFlags |= GTF_IND_VOLATILE; - } - - if ((prefixFlags & PREFIX_UNALIGNED) && !varTypeIsByte(lclTyp)) - { - assert(op1->OperGet() == GT_IND); - op1->gtFlags |= GTF_IND_UNALIGNED; - } - + op1 = gtNewIndir(lclTyp, op1, impPrefixFlagsToIndirFlags(prefixFlags)); op1 = gtNewAssignNode(op1, op2); goto SPILL_APPEND; @@ -8588,26 +8511,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) assertImp(genActualType(op1->gtType) == TYP_I_IMPL || op1->gtType == TYP_BYREF); - op1 = gtNewOperNode(GT_IND, lclTyp, op1); - - // ldind could point anywhere, example a boxed class static int - op1->gtFlags |= (GTF_EXCEPT | GTF_GLOB_REF); - - if (prefixFlags & PREFIX_VOLATILE) - { - assert(op1->OperGet() == GT_IND); - op1->gtFlags |= GTF_ORDER_SIDEEFF; // Prevent this from being reordered - op1->gtFlags |= GTF_IND_VOLATILE; - } - - if ((prefixFlags & PREFIX_UNALIGNED) && !varTypeIsByte(lclTyp)) - { - assert(op1->OperGet() == GT_IND); - op1->gtFlags |= GTF_IND_UNALIGNED; - } - + op1 = gtNewIndir(lclTyp, op1, impPrefixFlagsToIndirFlags(prefixFlags)); impPushOnStack(op1, tiRetVal); - break; case CEE_UNALIGNED: @@ -9347,33 +9252,32 @@ void Compiler::impImportBlockCode(BasicBlock* block) obj = impGetStructAddr(obj, objType, CHECK_SPILL_ALL, true); } - if (isLoadAddress) - { - op1 = gtNewFieldAddrNode(varTypeIsGC(obj) ? TYP_BYREF : TYP_I_IMPL, resolvedToken.hField, - obj, fieldInfo.offset); - } - else - { - op1 = gtNewFieldRef(lclTyp, resolvedToken.hField, obj, fieldInfo.offset); - } + op1 = gtNewFieldAddrNode(varTypeIsGC(obj) ? TYP_BYREF : TYP_I_IMPL, resolvedToken.hField, obj, + fieldInfo.offset); #ifdef FEATURE_READYTORUN if (fieldInfo.fieldAccessor == CORINFO_FIELD_INSTANCE_WITH_BASE) { - op1->AsField()->gtFieldLookup = fieldInfo.fieldLookup; + op1->AsFieldAddr()->gtFieldLookup = fieldInfo.fieldLookup; } #endif - if (StructHasOverlappingFields(info.compCompHnd->getClassAttribs(resolvedToken.hClass))) { - op1->AsField()->gtFldMayOverlap = true; + op1->AsFieldAddr()->gtFldMayOverlap = true; } - if (!isLoadAddress && compIsForInlining() && - impInlineIsGuaranteedThisDerefBeforeAnySideEffects(nullptr, nullptr, obj, - impInlineInfo->inlArgInfo)) + if (!isLoadAddress) { - impInlineInfo->thisDereferencedFirst = true; + ClassLayout* layout; + lclTyp = TypeHandleToVarType(fieldInfo.fieldType, clsHnd, &layout); + op1 = gtNewFieldIndirNode(lclTyp, layout, op1->AsFieldAddr()); + + if (compIsForInlining() && + impInlineIsGuaranteedThisDerefBeforeAnySideEffects(nullptr, nullptr, obj, + impInlineInfo->inlArgInfo)) + { + impInlineInfo->thisDereferencedFirst = true; + } } } break; @@ -9388,15 +9292,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) { ClassLayout* layout; lclTyp = TypeHandleToVarType(fieldInfo.fieldType, fieldInfo.structType, &layout); - if (lclTyp == TYP_STRUCT) - { - op1 = gtNewBlkIndir(layout, op1, GTF_IND_NONFAULTING); - } - else - { - op1 = gtNewIndir(lclTyp, op1, GTF_IND_NONFAULTING); - op1->gtFlags |= GTF_GLOB_REF; - } + op1 = (lclTyp == TYP_STRUCT) ? gtNewBlkIndir(layout, op1, GTF_IND_NONFAULTING) + : gtNewIndir(lclTyp, op1, GTF_IND_NONFAULTING); } break; #else @@ -9477,14 +9374,13 @@ void Compiler::impImportBlockCode(BasicBlock* block) if (!isLoadAddress) { - if (prefixFlags & PREFIX_VOLATILE) { op1->gtFlags |= GTF_ORDER_SIDEEFF; // Prevent this from being reordered if (!usesHelper) { - assert(op1->OperIs(GT_FIELD, GT_IND, GT_BLK)); + assert(op1->OperIs(GT_IND, GT_BLK)); op1->gtFlags |= GTF_IND_VOLATILE; } } @@ -9493,7 +9389,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) { if (!usesHelper) { - assert(op1->OperIs(GT_FIELD, GT_IND, GT_BLK)); + assert(op1->OperIs(GT_IND, GT_BLK)); op1->gtFlags |= GTF_IND_UNALIGNED; } } @@ -9521,7 +9417,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) case CEE_STFLD: case CEE_STSFLD: { - bool isStoreStatic = (opcode == CEE_STSFLD); /* Get the CP_Fieldref index */ @@ -9537,7 +9432,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) eeGetFieldInfo(&resolvedToken, (CORINFO_ACCESS_FLAGS)aflags, &fieldInfo); - lclTyp = JITtype2varType(fieldInfo.fieldType); + ClassLayout* layout; + lclTyp = TypeHandleToVarType(fieldInfo.fieldType, fieldInfo.structType, &layout); if (compIsForInlining()) { @@ -9577,10 +9473,49 @@ void Compiler::impImportBlockCode(BasicBlock* block) } if (helperNode != nullptr) { - impAppendTree(helperNode, CHECK_SPILL_ALL, impCurStmtDI); + bool isHoistable = + info.compCompHnd->getClassAttribs(resolvedToken.hClass) & CORINFO_FLG_BEFOREFIELDINIT; + unsigned check_spill = isHoistable ? CHECK_SPILL_NONE : CHECK_SPILL_ALL; + impAppendTree(helperNode, check_spill, impCurStmtDI); } } + // Handle the cases that might trigger type initialization + // (and possibly need to spill the tree for the stored value) + switch (fieldInfo.fieldAccessor) + { + case CORINFO_FIELD_INSTANCE: +#ifdef FEATURE_READYTORUN + case CORINFO_FIELD_INSTANCE_WITH_BASE: +#endif + case CORINFO_FIELD_STATIC_TLS: + case CORINFO_FIELD_STATIC_ADDR_HELPER: + case CORINFO_FIELD_INSTANCE_HELPER: + case CORINFO_FIELD_INSTANCE_ADDR_HELPER: + // Nothing now - handled later + break; + + case CORINFO_FIELD_STATIC_TLS_MANAGED: + case CORINFO_FIELD_STATIC_ADDRESS: + case CORINFO_FIELD_STATIC_RVA_ADDRESS: + case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER: + case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER: + case CORINFO_FIELD_STATIC_READYTORUN_HELPER: + case CORINFO_FIELD_STATIC_RELOCATABLE: + bool isHoistable; + op1 = impImportStaticFieldAccess(&resolvedToken, (CORINFO_ACCESS_FLAGS)aflags, &fieldInfo, + lclTyp, &isHoistable); + + if (!isHoistable) + { + impSpillSideEffects(true, CHECK_SPILL_ALL DEBUGARG("value for stsfld with typeinit")); + } + break; + + default: + assert(!"Unexpected fieldAccessor"); + } + // Pull the value from the stack. StackEntry se = impPopStack(); op2 = se.val; @@ -9614,6 +9549,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) obj = nullptr; } + // Handle the cases that use the stored value (obj). + // Conveniently these don't trigger type initialization, so there aren't + // any ordering issues between it and the tree for the stored value. switch (fieldInfo.fieldAccessor) { case CORINFO_FIELD_INSTANCE: @@ -9621,20 +9559,21 @@ void Compiler::impImportBlockCode(BasicBlock* block) case CORINFO_FIELD_INSTANCE_WITH_BASE: #endif { - /* Create the data member node */ - op1 = gtNewFieldRef(lclTyp, resolvedToken.hField, obj, fieldInfo.offset); - DWORD typeFlags = info.compCompHnd->getClassAttribs(resolvedToken.hClass); - if (StructHasOverlappingFields(typeFlags)) - { - op1->AsField()->gtFldMayOverlap = true; - } + op1 = gtNewFieldAddrNode(varTypeIsGC(obj) ? TYP_BYREF : TYP_I_IMPL, resolvedToken.hField, obj, + fieldInfo.offset); #ifdef FEATURE_READYTORUN if (fieldInfo.fieldAccessor == CORINFO_FIELD_INSTANCE_WITH_BASE) { - op1->AsField()->gtFieldLookup = fieldInfo.fieldLookup; + op1->AsFieldAddr()->gtFieldLookup = fieldInfo.fieldLookup; } #endif + if (StructHasOverlappingFields(info.compCompHnd->getClassAttribs(resolvedToken.hClass))) + { + op1->AsFieldAddr()->gtFldMayOverlap = true; + } + + op1 = gtNewFieldIndirNode(lclTyp, layout, op1->AsFieldAddr()); if (compIsForInlining() && impInlineIsGuaranteedThisDerefBeforeAnySideEffects(op2, nullptr, obj, @@ -9650,17 +9589,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) op1 = gtNewFieldAddrNode(TYP_I_IMPL, resolvedToken.hField, nullptr, fieldInfo.offset); op1->gtFlags |= GTF_FLD_TLS; // fgMorphExpandTlsField will handle the transformation. - ClassLayout* layout; - lclTyp = TypeHandleToVarType(fieldInfo.fieldType, fieldInfo.structType, &layout); - if (lclTyp == TYP_STRUCT) - { - op1 = gtNewBlkIndir(layout, op1, GTF_IND_NONFAULTING); - } - else - { - op1 = gtNewIndir(lclTyp, op1, GTF_IND_NONFAULTING); - op1->gtFlags |= GTF_GLOB_REF; - } + op1 = (lclTyp == TYP_STRUCT) ? gtNewBlkIndir(layout, op1, GTF_IND_NONFAULTING) + : gtNewIndir(lclTyp, op1, GTF_IND_NONFAULTING); break; #else fieldInfo.fieldAccessor = CORINFO_FIELD_STATIC_ADDR_HELPER; @@ -9682,8 +9612,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER: case CORINFO_FIELD_STATIC_READYTORUN_HELPER: case CORINFO_FIELD_STATIC_RELOCATABLE: - op1 = impImportStaticFieldAccess(&resolvedToken, (CORINFO_ACCESS_FLAGS)aflags, &fieldInfo, - lclTyp); + // Handled above break; default: @@ -9696,7 +9625,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) } else { - assert(op1->OperIs(GT_FIELD, GT_IND)); + assert(op1->OperIs(GT_IND)); if (prefixFlags & PREFIX_VOLATILE) { @@ -9714,8 +9643,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) if ((lclTyp == TYP_REF) && (((fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC) != 0) || obj->TypeIs(TYP_REF))) { - static_assert_no_msg(GTF_FLD_TGT_HEAP == GTF_IND_TGT_HEAP); - op1->gtFlags |= GTF_FLD_TGT_HEAP; + op1->gtFlags |= GTF_IND_TGT_HEAP; } /* V4.0 allows assignment of i4 constant values to i8 type vars when IL verifier is bypassed (full @@ -9791,11 +9719,57 @@ void Compiler::impImportBlockCode(BasicBlock* block) // So if we have an int, explicitly extend it to be a native int. op2 = impImplicitIorI4Cast(op2, TYP_I_IMPL); + bool isFrozenAllocator = false; + // If we're jitting a static constructor and detect the following code pattern: + // + // newarr + // stsfld + // ret + // + // we emit a "frozen" allocator for newarr to, hopefully, allocate that array on a frozen segment. + // This is a very simple and conservative implementation targeting Array.Empty()'s shape + // Ideally, we want to be able to use frozen allocators more broadly, but such an analysis is + // not trivial. + // + if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && + // Does VM allow us to use frozen allocators? + opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) + { + // Check next two opcodes (have to be STSFLD and RET) + const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); + const BYTE* nextOpcode2 = nextOpcode1 + sizeof(mdToken) + 1; + if ((nextOpcode2 < codeEndp) && (getU1LittleEndian(nextOpcode1) == CEE_STSFLD)) + { + if (getU1LittleEndian(nextOpcode2) == CEE_RET) + { + // Check that the field is "static readonly", we don't want to waste memory + // for potentially mutable fields. + CORINFO_RESOLVED_TOKEN fldToken; + impResolveToken(nextOpcode1 + 1, &fldToken, CORINFO_TOKENKIND_Field); + CORINFO_FIELD_INFO fi; + eeGetFieldInfo(&fldToken, CORINFO_ACCESS_SET, &fi); + unsigned flagsToCheck = CORINFO_FLG_FIELD_STATIC | CORINFO_FLG_FIELD_FINAL; + if ((fi.fieldFlags & flagsToCheck) == flagsToCheck) + { #ifdef FEATURE_READYTORUN - if (opts.IsReadyToRun()) + if (opts.IsReadyToRun()) + { + // Need to restore array classes before creating array objects on the heap + op1 = impTokenToHandle(&resolvedToken, nullptr, true /*mustRestoreHandle*/); + } +#endif + op1 = gtNewHelperCallNode(CORINFO_HELP_NEWARR_1_MAYBEFROZEN, TYP_REF, op1, op2); + isFrozenAllocator = true; + } + } + } + } + +#ifdef FEATURE_READYTORUN + if (opts.IsReadyToRun() && !isFrozenAllocator) { - op1 = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_NEWARR_1, TYP_REF, nullptr, - op2); + helper = CORINFO_HELP_READYTORUN_NEWARR_1; + op1 = impReadyToRunHelperToTree(&resolvedToken, helper, TYP_REF, nullptr, op2); usingReadyToRunHelper = (op1 != nullptr); if (!usingReadyToRunHelper) @@ -9807,7 +9781,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) // 3) Allocate the new array // Reason: performance (today, we'll always use the slow helper for the R2R generics case) - // Need to restore array classes before creating array objects on the heap op1 = impTokenToHandle(&resolvedToken, nullptr, true /*mustRestoreHandle*/); if (op1 == nullptr) { // compDonotInline() @@ -9816,15 +9789,15 @@ void Compiler::impImportBlockCode(BasicBlock* block) } } - if (!usingReadyToRunHelper) + if (!usingReadyToRunHelper && !isFrozenAllocator) #endif { /* Create a call to 'new' */ + helper = info.compCompHnd->getNewArrHelper(resolvedToken.hClass); // Note that this only works for shared generic code because the same helper is used for all // reference array types - op1 = - gtNewHelperCallNode(info.compCompHnd->getNewArrHelper(resolvedToken.hClass), TYP_REF, op1, op2); + op1 = gtNewHelperCallNode(helper, TYP_REF, op1, op2); } op1->AsCall()->compileTimeHelperArgumentHandle = (CORINFO_GENERIC_HANDLE)resolvedToken.hClass; @@ -10078,7 +10051,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // Fetch the type from the correct slot op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, gtNewIconNode(OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL)); - op1 = gtNewOperNode(GT_IND, TYP_BYREF, op1); + op1 = gtNewIndir(TYP_BYREF, op1); } // Convert native TypeHandle to RuntimeTypeHandle. @@ -10663,7 +10636,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) } else { - op2 = gtNewOperNode(GT_IND, TYP_STRUCT, op2); + op2 = gtNewIndir(TYP_STRUCT, op2); } #ifdef TARGET_64BIT @@ -10692,7 +10665,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) { op2 = impPopStack().val; // address to load from op2 = gtNewIndir(lclTyp, op2); - op2->gtFlags |= GTF_GLOB_REF; goto STIND_VALUE; } @@ -12447,24 +12419,6 @@ void Compiler::verResetCurrentState(BasicBlock* block, EntryState* destState) } } -unsigned BasicBlock::bbStackDepthOnEntry() const -{ - return (bbEntryState ? bbEntryState->esStackDepth : 0); -} - -void BasicBlock::bbSetStack(void* stackBuffer) -{ - assert(bbEntryState); - assert(stackBuffer); - bbEntryState->esStack = (StackEntry*)stackBuffer; -} - -StackEntry* BasicBlock::bbStackOnEntry() const -{ - assert(bbEntryState); - return bbEntryState->esStack; -} - void Compiler::verInitCurrentState() { // initialize stack info @@ -12754,11 +12708,11 @@ void Compiler::impFixPredLists() // // Remarks: // This is a variant of GenTree::IsInvariant that is more suitable for use -// during import. Unlike that function, this one handles GT_FIELD nodes. +// during import. Unlike that function, this one handles GT_FIELD_ADDR nodes. // bool Compiler::impIsInvariant(const GenTree* tree) { - return tree->OperIsConst() || impIsAddressInLocal(tree); + return tree->OperIsConst() || impIsAddressInLocal(tree) || tree->OperIs(GT_FTN_ADDR); } //------------------------------------------------------------------------ @@ -12775,9 +12729,9 @@ bool Compiler::impIsInvariant(const GenTree* tree) bool Compiler::impIsAddressInLocal(const GenTree* tree, GenTree** lclVarTreeOut) { const GenTree* op = tree; - while (op->OperIs(GT_FIELD_ADDR) && op->AsField()->IsInstance()) + while (op->OperIs(GT_FIELD_ADDR) && op->AsFieldAddr()->IsInstance()) { - op = op->AsField()->GetFldObj(); + op = op->AsFieldAddr()->GetFldObj(); } if (op->OperIs(GT_LCL_ADDR)) @@ -13662,19 +13616,19 @@ unsigned Compiler::impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reas lvaTable[tmpNum].lvHasILStoreOp = inlineeLocal.lclHasStlocOp; lvaTable[tmpNum].lvHasMultipleILStoreOp = inlineeLocal.lclHasMultipleStlocOp; + assert(lvaTable[tmpNum].lvSingleDef == 0); + + lvaTable[tmpNum].lvSingleDef = !inlineeLocal.lclHasMultipleStlocOp && !inlineeLocal.lclHasLdlocaOp; + if (lvaTable[tmpNum].lvSingleDef) + { + JITDUMP("Marked V%02u as a single def temp\n", tmpNum); + } + // Copy over class handle for ref types. Note this may be a // shared type -- someday perhaps we can get the exact // signature and pass in a more precise type. if (lclTyp == TYP_REF) { - assert(lvaTable[tmpNum].lvSingleDef == 0); - - lvaTable[tmpNum].lvSingleDef = !inlineeLocal.lclHasMultipleStlocOp && !inlineeLocal.lclHasLdlocaOp; - if (lvaTable[tmpNum].lvSingleDef) - { - JITDUMP("Marked V%02u as a single def temp\n", tmpNum); - } - lvaSetClass(tmpNum, inlineeLocal.lclVerTypeInfo.GetClassHandleForObjRef()); } @@ -13859,20 +13813,21 @@ GenTree* Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, In lvaTable[tmpNum].lvType = lclTyp; - // For ref types, determine the type of the temp. - if (lclTyp == TYP_REF) + // If arg can't be modified, mark it as single def. + // For ref types, determine the class of the arg temp. + if (!argCanBeModified) { - if (!argCanBeModified) + assert(lvaTable[tmpNum].lvSingleDef == 0); + lvaTable[tmpNum].lvSingleDef = 1; + JITDUMP("Marked V%02u as a single def temp\n", tmpNum); + if (lclTyp == TYP_REF) { - // If the arg can't be modified in the method - // body, use the type of the value, if - // known. Otherwise, use the declared type. - assert(lvaTable[tmpNum].lvSingleDef == 0); - lvaTable[tmpNum].lvSingleDef = 1; - JITDUMP("Marked V%02u as a single def temp\n", tmpNum); lvaSetClass(tmpNum, argNode, lclInfo.lclVerTypeInfo.GetClassHandleForObjRef()); } - else + } + else + { + if (lclTyp == TYP_REF) { // Arg might be modified, use the declared type of // the argument. diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index eb54117a882335..f952836c704899 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -1631,8 +1631,9 @@ GenTreeCall* Compiler::impImportIndirectCall(CORINFO_SIG_INFO* sig, const DebugI * it may cause registered args to be spilled. Simply spill it. */ - // Ignore this trivial case. - if (impStackTop().val->gtOper != GT_LCL_VAR) + // Ignore no args or trivial cases. + if ((sig->callConv != CORINFO_CALLCONV_DEFAULT || sig->totalILArgs() > 0) && + !impStackTop().val->OperIs(GT_LCL_VAR, GT_FTN_ADDR, GT_CNS_INT)) { impSpillStackEntry(verCurrentState.esStackDepth - 1, BAD_VAR_NUM DEBUGARG(false) DEBUGARG("impImportIndirectCall")); @@ -1871,6 +1872,7 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) bool isMDArray = false; if (newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_DIRECT) && + newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_MAYBEFROZEN) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_OBJ) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_VC) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8) @@ -2041,7 +2043,8 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) GenTree* arrayLengthNode; #ifdef FEATURE_READYTORUN - if (newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1)) + if (newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1) || + newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_MAYBEFROZEN)) { // Array length is 1st argument for readytorun helper arrayLengthNode = newArrayCall->AsCall()->gtArgs.GetArgByIndex(0)->GetNode(); @@ -2124,11 +2127,10 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) ClassLayout* blkLayout = typGetBlkLayout(blkSize); GenTree* dstAddr = gtNewOperNode(GT_ADD, TYP_BYREF, arrayLocalNode, gtNewIconNode(dataOffset, TYP_I_IMPL)); - GenTree* dst = gtNewLoadValueNode(blkLayout, dstAddr); - dst->gtFlags |= GTF_GLOB_REF; + GenTree* dst = gtNewBlkIndir(blkLayout, dstAddr); GenTree* srcAddr = gtNewIconHandleNode((size_t)initData, GTF_ICON_CONST_PTR); - GenTree* src = gtNewLoadValueNode(blkLayout, srcAddr); + GenTree* src = gtNewBlkIndir(blkLayout, srcAddr); #ifdef DEBUG src->gtGetOp1()->AsIntCon()->gtTargetHandle = THT_InitializeArrayIntrinsics; @@ -2896,8 +2898,10 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, CORINFO_FIELD_HANDLE lengthHnd = info.compCompHnd->getFieldInClass(clsHnd, 1); const unsigned lengthOffset = info.compCompHnd->getFieldOffset(lengthHnd); - GenTreeField* length = gtNewFieldRef(TYP_INT, lengthHnd, ptrToSpan, lengthOffset); - length->SetIsSpanLength(true); + GenTreeFieldAddr* lengthFieldAddr = + gtNewFieldAddrNode(genActualType(ptrToSpan), lengthHnd, ptrToSpan, lengthOffset); + lengthFieldAddr->SetIsSpanLength(true); + GenTree* length = gtNewFieldIndirNode(TYP_INT, nullptr, lengthFieldAddr); GenTree* boundsCheck = new (this, GT_BOUNDS_CHECK) GenTreeBoundsChk(index, length, SCK_RNGCHK_FAIL); @@ -2913,8 +2917,10 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, CORINFO_FIELD_HANDLE ptrHnd = info.compCompHnd->getFieldInClass(clsHnd, 0); const unsigned ptrOffset = info.compCompHnd->getFieldOffset(ptrHnd); - GenTree* data = gtNewFieldRef(TYP_BYREF, ptrHnd, ptrToSpanClone, ptrOffset); - GenTree* result = gtNewOperNode(GT_ADD, TYP_BYREF, data, index); + GenTreeFieldAddr* dataFieldAddr = + gtNewFieldAddrNode(genActualType(ptrToSpanClone), ptrHnd, ptrToSpanClone, ptrOffset); + GenTree* data = gtNewFieldIndirNode(TYP_BYREF, nullptr, dataFieldAddr); + GenTree* result = gtNewOperNode(GT_ADD, TYP_BYREF, data, index); // Prepare result var_types resultType = JITtype2varType(sig->retType); @@ -2957,9 +2963,12 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, CORINFO_FIELD_HANDLE lengthHnd = info.compCompHnd->getFieldInClass(clsHnd, 1); const unsigned lengthOffset = info.compCompHnd->getFieldOffset(lengthHnd); - GenTreeField* fieldRef = gtNewFieldRef(TYP_INT, lengthHnd, ptrToSpan, lengthOffset); - fieldRef->SetIsSpanLength(true); - return fieldRef; + GenTreeFieldAddr* lengthFieldAddr = + gtNewFieldAddrNode(genActualType(ptrToSpan), lengthHnd, ptrToSpan, lengthOffset); + lengthFieldAddr->SetIsSpanLength(true); + GenTree* lengthField = gtNewFieldIndirNode(TYP_INT, nullptr, lengthFieldAddr); + + return lengthField; } case NI_System_RuntimeTypeHandle_GetValueInternal: @@ -3697,8 +3706,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, unsigned offs = eeGetMDArrayLengthOffset(rank, dim); GenTree* gtOffs = gtNewIconNode(offs, TYP_I_IMPL); GenTree* gtAddr = gtNewOperNode(GT_ADD, TYP_BYREF, gtArr, gtOffs); - retNode = gtNewIndir(TYP_INT, gtAddr); - retNode->gtFlags |= GTF_IND_INVARIANT; + retNode = gtNewIndir(TYP_INT, gtAddr, GTF_IND_INVARIANT); break; } case NI_System_Array_GetLowerBound: @@ -3707,8 +3715,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, unsigned offs = eeGetMDArrayLowerBoundOffset(rank, dim); GenTree* gtOffs = gtNewIconNode(offs, TYP_I_IMPL); GenTree* gtAddr = gtNewOperNode(GT_ADD, TYP_BYREF, gtArr, gtOffs); - retNode = gtNewIndir(TYP_INT, gtAddr); - retNode->gtFlags |= GTF_IND_INVARIANT; + retNode = gtNewIndir(TYP_INT, gtAddr, GTF_IND_INVARIANT); break; } case NI_System_Array_GetUpperBound: @@ -3721,14 +3728,12 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, unsigned offs = eeGetMDArrayLowerBoundOffset(rank, dim); GenTree* gtOffs = gtNewIconNode(offs, TYP_I_IMPL); GenTree* gtAddr = gtNewOperNode(GT_ADD, TYP_BYREF, gtArr, gtOffs); - GenTree* gtLowerBound = gtNewIndir(TYP_INT, gtAddr); - gtLowerBound->gtFlags |= GTF_IND_INVARIANT; + GenTree* gtLowerBound = gtNewIndir(TYP_INT, gtAddr, GTF_IND_INVARIANT); offs = eeGetMDArrayLengthOffset(rank, dim); gtOffs = gtNewIconNode(offs, TYP_I_IMPL); gtAddr = gtNewOperNode(GT_ADD, TYP_BYREF, gtArrClone, gtOffs); - GenTree* gtLength = gtNewIndir(TYP_INT, gtAddr); - gtLength->gtFlags |= GTF_IND_INVARIANT; + GenTree* gtLength = gtNewIndir(TYP_INT, gtAddr, GTF_IND_INVARIANT); GenTree* gtSum = gtNewOperNode(GT_ADD, TYP_INT, gtLowerBound, gtLength); GenTree* gtOne = gtNewIconNode(1, TYP_INT); @@ -5156,10 +5161,7 @@ GenTree* Compiler::impTransformThis(GenTree* thisPtr, assert(genActualType(obj->gtType) == TYP_I_IMPL || obj->gtType == TYP_BYREF); CorInfoType constraintTyp = info.compCompHnd->asCorInfoType(pConstrainedResolvedToken->hClass); - obj = gtNewOperNode(GT_IND, JITtype2varType(constraintTyp), obj); - // ldind could point anywhere, example a boxed class static int - obj->gtFlags |= (GTF_EXCEPT | GTF_GLOB_REF); - + obj = gtNewIndir(JITtype2varType(constraintTyp), obj); return obj; } @@ -5484,12 +5486,11 @@ class SpillRetExprHelper comp->impAssignTempGen(tmp, retExpr, (unsigned)Compiler::CHECK_SPILL_NONE); *pRetExpr = comp->gtNewLclvNode(tmp, retExpr->TypeGet()); + assert(comp->lvaTable[tmp].lvSingleDef == 0); + comp->lvaTable[tmp].lvSingleDef = 1; + JITDUMP("Marked V%02u as a single def temp\n", tmp); if (retExpr->TypeGet() == TYP_REF) { - assert(comp->lvaTable[tmp].lvSingleDef == 0); - comp->lvaTable[tmp].lvSingleDef = 1; - JITDUMP("Marked V%02u as a single def temp\n", tmp); - bool isExact = false; bool isNonNull = false; CORINFO_CLASS_HANDLE retClsHnd = comp->gtGetClassHandle(retExpr, &isExact, &isNonNull); @@ -8880,8 +8881,7 @@ GenTree* Compiler::impArrayAccessIntrinsic( } else { - // TODO-Bug: GTF_GLOB_REF is missing. - arrElem = gtNewOperNode(GT_IND, elemType, arrElem); + arrElem = gtNewIndir(elemType, arrElem); } } diff --git a/src/coreclr/jit/importervectorization.cpp b/src/coreclr/jit/importervectorization.cpp index 2a36b09b96988d..c751c7b4d3ee5b 100644 --- a/src/coreclr/jit/importervectorization.cpp +++ b/src/coreclr/jit/importervectorization.cpp @@ -388,7 +388,7 @@ GenTree* Compiler::impExpandHalfConstEqualsSWAR( // // Arguments: // data - Pointer (LCL_VAR) to a data to vectorize -// lengthFld - Pointer (LCL_VAR or GT_FIELD) to Length field +// lengthFld - Pointer (LCL_VAR or GT_IND) to Length field // checkForNull - Check data for null // startsWith - Is it StartsWith or Equals? // cns - Constant data (array of 2-byte chars) @@ -787,8 +787,10 @@ GenTree* Compiler::impSpanEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO* GenTreeLclVar* spanObjRefLcl = gtNewLclvNode(spanObjRef, TYP_BYREF); GenTreeLclVar* spanDataTmpLcl = gtNewLclvNode(spanDataTmp, TYP_BYREF); - GenTreeField* spanLength = gtNewFieldRef(TYP_INT, lengthHnd, gtClone(spanObjRefLcl), lengthOffset); - GenTreeField* spanData = gtNewFieldRef(TYP_BYREF, pointerHnd, spanObjRefLcl); + GenTreeFieldAddr* spanLengthAddr = gtNewFieldAddrNode(TYP_BYREF, lengthHnd, gtClone(spanObjRefLcl), lengthOffset); + GenTree* spanLength = gtNewFieldIndirNode(TYP_INT, nullptr, spanLengthAddr); + GenTreeFieldAddr* spanDataAddr = gtNewFieldAddrNode(TYP_BYREF, pointerHnd, spanObjRefLcl); + GenTree* spanData = gtNewFieldIndirNode(TYP_BYREF, nullptr, spanDataAddr); GenTree* unrolled = impExpandHalfConstEquals(spanDataTmpLcl, spanLength, false, startsWith, (WCHAR*)str, cnsLength, 0, cmpMode); diff --git a/src/coreclr/jit/indirectcalltransformer.cpp b/src/coreclr/jit/indirectcalltransformer.cpp index b62ffc4e5a6752..b5183f1586e597 100644 --- a/src/coreclr/jit/indirectcalltransformer.cpp +++ b/src/coreclr/jit/indirectcalltransformer.cpp @@ -377,7 +377,7 @@ class IndirectCallTransformer elseBlock = CreateAndInsertBasicBlock(BBJ_NONE, thenBlock); GenTree* fixedFptrAddress = GetFixedFptrAddress(); - GenTree* actualCallAddress = compiler->gtNewOperNode(GT_IND, pointerType, fixedFptrAddress); + GenTree* actualCallAddress = compiler->gtNewIndir(pointerType, fixedFptrAddress); GenTree* hiddenArgument = GetHiddenArgument(fixedFptrAddress); Statement* fatStmt = CreateFatCallStmt(actualCallAddress, hiddenArgument); @@ -409,7 +409,7 @@ class IndirectCallTransformer GenTree* fixedFptrAddressCopy = compiler->gtCloneExpr(fixedFptrAddress); GenTree* wordSize = new (compiler, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, genTypeSize(TYP_I_IMPL)); GenTree* hiddenArgumentPtr = compiler->gtNewOperNode(GT_ADD, pointerType, fixedFptrAddressCopy, wordSize); - return compiler->gtNewOperNode(GT_IND, fixedFptrAddressCopy->TypeGet(), hiddenArgumentPtr); + return compiler->gtNewIndir(fixedFptrAddressCopy->TypeGet(), hiddenArgumentPtr); } //------------------------------------------------------------------------ @@ -612,8 +612,7 @@ class IndirectCallTransformer compiler->gtNewIconNode((ssize_t)compiler->eeGetEEInfo()->offsetOfDelegateFirstTarget, TYP_I_IMPL); GenTree* tarTree = compiler->gtNewOperNode(GT_ADD, TYP_BYREF, thisTree, offset); - tarTree = compiler->gtNewIndir(TYP_I_IMPL, tarTree); - tarTree->gtFlags |= GTF_IND_INVARIANT; + tarTree = compiler->gtNewIndir(TYP_I_IMPL, tarTree, GTF_IND_INVARIANT); CORINFO_METHOD_HANDLE methHnd = guardedInfo->guardedMethodHandle; CORINFO_CONST_LOOKUP lookup; @@ -1157,9 +1156,7 @@ class IndirectCallTransformer case IAT_PVALUE: { GenTree* tree = CreateFunctionTargetAddr(methHnd, lookup); - tree = compiler->gtNewIndir(TYP_I_IMPL, tree); - tree->gtFlags |= GTF_IND_NONFAULTING | GTF_IND_INVARIANT; - tree->gtFlags &= ~GTF_EXCEPT; + tree = compiler->gtNewIndir(TYP_I_IMPL, tree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); return tree; } case IAT_PPVALUE: @@ -1171,10 +1168,8 @@ class IndirectCallTransformer { GenTree* addr = CreateFunctionTargetAddr(methHnd, lookup); GenTree* tree = CreateFunctionTargetAddr(methHnd, lookup); - tree = compiler->gtNewIndir(TYP_I_IMPL, tree); - tree->gtFlags |= GTF_IND_NONFAULTING | GTF_IND_INVARIANT; - tree->gtFlags &= ~GTF_EXCEPT; - tree = compiler->gtNewOperNode(GT_ADD, TYP_I_IMPL, tree, addr); + tree = compiler->gtNewIndir(TYP_I_IMPL, tree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); + tree = compiler->gtNewOperNode(GT_ADD, TYP_I_IMPL, tree, addr); return tree; } default: diff --git a/src/coreclr/jit/inlinepolicy.cpp b/src/coreclr/jit/inlinepolicy.cpp index d11cc1e905f8fa..ebba45105bbd15 100644 --- a/src/coreclr/jit/inlinepolicy.cpp +++ b/src/coreclr/jit/inlinepolicy.cpp @@ -846,9 +846,7 @@ int DefaultPolicy::DetermineCallsiteNativeSizeEstimate(CORINFO_METHOD_INFO* meth { int callsiteSize = 55; // Direct call take 5 native bytes; indirect call takes 6 native bytes. - bool hasThis = methInfo->args.hasThis(); - - if (hasThis) + if (methInfo->args.hasImplicitThis()) { callsiteSize += 30; // "mov" or "lea" } @@ -856,7 +854,7 @@ int DefaultPolicy::DetermineCallsiteNativeSizeEstimate(CORINFO_METHOD_INFO* meth CORINFO_ARG_LIST_HANDLE argLst = methInfo->args.args; COMP_HANDLE comp = m_RootCompiler->info.compCompHnd; - for (unsigned i = (hasThis ? 1 : 0); i < methInfo->args.totalILArgs(); i++, argLst = comp->getArgNext(argLst)) + for (unsigned i = 0; i < methInfo->args.numArgs; i++, argLst = comp->getArgNext(argLst)) { var_types sigType = (var_types)m_RootCompiler->eeGetArgType(argLst, &methInfo->args); diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp index 27a775cec2606f..b942ddd6d878d9 100644 --- a/src/coreclr/jit/instr.cpp +++ b/src/coreclr/jit/instr.cpp @@ -145,6 +145,26 @@ const char* CodeGen::genInsDisplayName(emitter::instrDesc* id) return "vpxord"; } + case INS_roundpd: + { + return "vrndscalepd"; + } + + case INS_roundps: + { + return "vrndscaleps"; + } + + case INS_roundsd: + { + return "vrndscalesd"; + } + + case INS_roundss: + { + return "vrndscaless"; + } + case INS_vbroadcastf128: { return "vbroadcastf32x4"; @@ -1144,6 +1164,76 @@ void CodeGen::inst_RV_RV_TT( unreached(); } } + +//------------------------------------------------------------------------ +// inst_RV_RV_TT_IV: Generates an instruction that takes 3 operands: +// a register operand, an operand that may be in memory or register, +// and an immediate value. The result is returned in register +// +// Arguments: +// ins -- The instruction being emitted +// size -- The emit size attribute +// targetReg -- The target register +// op1Reg -- The first operand register +// op2 -- The second operand, which may be a memory node or a node producing a register +// ival -- The immediate operand +// isRMW -- true if the instruction is RMW; otherwise, false +// +void CodeGen::inst_RV_RV_TT_IV( + instruction ins, emitAttr size, regNumber targetReg, regNumber op1Reg, GenTree* op2, int8_t ival, bool isRMW) +{ + emitter* emit = GetEmitter(); + noway_assert(emit->emitVerifyEncodable(ins, EA_SIZE(size), op1Reg)); + + // TODO-XArch-CQ: Commutative operations can have op1 be contained + // TODO-XArch-CQ: Non-VEX encoded instructions can have both ops contained + + OperandDesc op2Desc = genOperandDesc(op2); + switch (op2Desc.GetKind()) + { + case OperandKind::ClsVar: + emit->emitIns_SIMD_R_R_C_I(ins, size, targetReg, op1Reg, op2Desc.GetFieldHnd(), 0, ival); + break; + + case OperandKind::Local: + emit->emitIns_SIMD_R_R_S_I(ins, size, targetReg, op1Reg, op2Desc.GetVarNum(), op2Desc.GetLclOffset(), ival); + break; + + case OperandKind::Indir: + { + // Until we improve the handling of addressing modes in the emitter, we'll create a + // temporary GT_IND to generate code with. + GenTreeIndir indirForm; + GenTreeIndir* indir = op2Desc.GetIndirForm(&indirForm); + emit->emitIns_SIMD_R_R_A_I(ins, size, targetReg, op1Reg, indir, ival); + } + break; + + case OperandKind::Reg: + { + regNumber op2Reg = op2Desc.GetReg(); + + if ((op1Reg != targetReg) && (op2Reg == targetReg) && isRMW) + { + // We have "reg2 = reg1 op reg2" where "reg1 != reg2" on a RMW intrinsic. + // + // For non-commutative intrinsics, we should have ensured that op2 was marked + // delay free in order to prevent it from getting assigned the same register + // as target. However, for commutative intrinsics, we can just swap the operands + // in order to have "reg2 = reg2 op reg1" which will end up producing the right code. + + op2Reg = op1Reg; + op1Reg = targetReg; + } + + emit->emitIns_SIMD_R_R_R_I(ins, size, targetReg, op1Reg, op2Reg, ival); + } + break; + + default: + unreached(); + } +} #endif // TARGET_XARCH /***************************************************************************** @@ -1316,153 +1406,159 @@ bool CodeGenInterface::validImmForBL(ssize_t addr) */ instruction CodeGen::ins_Move_Extend(var_types srcType, bool srcInReg) { - NYI_LOONGARCH64("ins_Move_Extend"); - NYI_RISCV64("ins_Move_Extend"); - - instruction ins = INS_invalid; - - if (varTypeIsSIMD(srcType)) + if (varTypeUsesIntReg(srcType)) { -#if defined(TARGET_XARCH) - // SSE2/AVX requires destination to be a reg always. - // If src is in reg means, it is a reg-reg move. - // - // SSE2 Note: always prefer movaps/movups over movapd/movupd since the - // former doesn't require 66h prefix and one byte smaller than the - // latter. - // - // TODO-CQ: based on whether src type is aligned use movaps instead - - return (srcInReg) ? INS_movaps : INS_movups; -#elif defined(TARGET_ARM64) - return (srcInReg) ? INS_mov : ins_Load(srcType); -#else // !defined(TARGET_ARM64) && !defined(TARGET_XARCH) - assert(!"unhandled SIMD type"); -#endif // !defined(TARGET_ARM64) && !defined(TARGET_XARCH) - } - -#if defined(TARGET_XARCH) - if (varTypeIsFloating(srcType)) - { - if (srcType == TYP_DOUBLE) - { - return (srcInReg) ? INS_movaps : INS_movsd_simd; - } - else if (srcType == TYP_FLOAT) - { - return (srcInReg) ? INS_movaps : INS_movss; - } - else - { - assert(!"unhandled floating type"); - } - } -#elif defined(TARGET_ARM) - if (varTypeIsFloating(srcType)) - return INS_vmov; -#else - if (varTypeIsFloating(srcType)) - return INS_mov; -#endif + instruction ins = INS_invalid; #if defined(TARGET_XARCH) - if (!varTypeIsSmall(srcType)) - { - ins = INS_mov; - } - else if (varTypeIsUnsigned(srcType)) - { - ins = INS_movzx; - } - else - { - ins = INS_movsx; - } -#elif defined(TARGET_ARM) - // - // Register to Register zero/sign extend operation - // - if (srcInReg) - { if (!varTypeIsSmall(srcType)) { ins = INS_mov; } else if (varTypeIsUnsigned(srcType)) { - if (varTypeIsByte(srcType)) - ins = INS_uxtb; - else - ins = INS_uxth; + ins = INS_movzx; } else { - if (varTypeIsByte(srcType)) - ins = INS_sxtb; - else - ins = INS_sxth; + ins = INS_movsx; } - } - else - { - ins = ins_Load(srcType); - } -#elif defined(TARGET_ARM64) - // - // Register to Register zero/sign extend operation - // - if (srcInReg) - { - if (varTypeIsUnsigned(srcType)) +#elif defined(TARGET_ARM) + // + // Register to Register zero/sign extend operation + // + if (srcInReg) { - if (varTypeIsByte(srcType)) + if (!varTypeIsSmall(srcType)) { - ins = INS_uxtb; + ins = INS_mov; } - else if (varTypeIsShort(srcType)) + else if (varTypeIsUnsigned(srcType)) { - ins = INS_uxth; + if (varTypeIsByte(srcType)) + ins = INS_uxtb; + else + ins = INS_uxth; } else { - // A mov Rd, Rm instruction performs the zero extend - // for the upper 32 bits when the size is EA_4BYTE - - ins = INS_mov; + if (varTypeIsByte(srcType)) + ins = INS_sxtb; + else + ins = INS_sxth; } } else { - if (varTypeIsByte(srcType)) - { - ins = INS_sxtb; - } - else if (varTypeIsShort(srcType)) + ins = ins_Load(srcType); + } +#elif defined(TARGET_ARM64) + // + // Register to Register zero/sign extend operation + // + if (srcInReg) + { + if (varTypeIsUnsigned(srcType)) { - ins = INS_sxth; + if (varTypeIsByte(srcType)) + { + ins = INS_uxtb; + } + else if (varTypeIsShort(srcType)) + { + ins = INS_uxth; + } + else + { + // A mov Rd, Rm instruction performs the zero extend + // for the upper 32 bits when the size is EA_4BYTE + + ins = INS_mov; + } } else { - if (srcType == TYP_INT) + if (varTypeIsByte(srcType)) + { + ins = INS_sxtb; + } + else if (varTypeIsShort(srcType)) { - ins = INS_sxtw; + ins = INS_sxth; } else { - ins = INS_mov; + if (srcType == TYP_INT) + { + ins = INS_sxtw; + } + else + { + ins = INS_mov; + } } } } + else + { + ins = ins_Load(srcType); + } +#else + NYI("ins_Move_Extend"); +#endif + + assert(ins != INS_invalid); + return ins; + } + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (varTypeUsesMaskReg(srcType)) + { + return INS_kmovq_msk; + } +#endif // TARGET_XARCH && FEATURE_SIMD + + assert(varTypeUsesFloatReg(srcType)); + +#if defined(TARGET_XARCH) + // SSE2/AVX requires destination to be a reg always. + // If src is in reg means, it is a reg-reg move. + // + // SSE2 Note: always prefer movaps/movups over movapd/movupd since the + // former doesn't require 66h prefix and one byte smaller than the + // latter. + // + // TODO-CQ: based on whether src type is aligned use movaps instead + + if (srcInReg) + { + return INS_movaps; + } + + unsigned srcSize = genTypeSize(srcType); + + if (srcSize == 4) + { + return INS_movss; + } + else if (srcSize == 8) + { + return INS_movsd_simd; } else { - ins = ins_Load(srcType); + assert((srcSize == 12) || (srcSize == 16) || (srcSize == 32) || (srcSize == 64)); + return INS_movups; } +#elif defined(TARGET_ARM64) + return (srcInReg) ? INS_mov : ins_Load(srcType); +#elif defined(TARGET_ARM) + assert(!varTypeIsSIMD(srcType)); + return INS_vmov; #else NYI("ins_Move_Extend"); + return INS_invalid; #endif - assert(ins != INS_invalid); - return ins; } /***************************************************************************** @@ -1475,166 +1571,158 @@ instruction CodeGen::ins_Move_Extend(var_types srcType, bool srcInReg) */ instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false*/) { - instruction ins = INS_invalid; - - if (varTypeIsSIMD(srcType)) + if (varTypeUsesIntReg(srcType)) { + instruction ins = INS_invalid; + #if defined(TARGET_XARCH) -#ifdef FEATURE_SIMD - if (srcType == TYP_SIMD8) + if (!varTypeIsSmall(srcType)) { - return INS_movsd_simd; + ins = INS_mov; + } + else if (varTypeIsUnsigned(srcType)) + { + ins = INS_movzx; } else -#endif // FEATURE_SIMD { - // SSE2 Note: always prefer movaps/movups over movapd/movupd since the - // former doesn't require 66h prefix and one byte smaller than the - // latter. - return (aligned) ? INS_movaps : INS_movups; + ins = INS_movsx; } -#elif defined(TARGET_ARM64) - return INS_ldr; -#else - assert(!"ins_Load with SIMD type"); -#endif - } - - if (varTypeIsFloating(srcType)) - { -#if defined(TARGET_XARCH) - if (srcType == TYP_DOUBLE) +#elif defined(TARGET_ARMARCH) + if (!varTypeIsSmall(srcType)) { - return INS_movsd_simd; + ins = INS_ldr; } - else if (srcType == TYP_FLOAT) + else if (varTypeIsByte(srcType)) { - return INS_movss; + if (varTypeIsUnsigned(srcType)) + ins = INS_ldrb; + else + ins = INS_ldrsb; } - else + else if (varTypeIsShort(srcType)) { - assert(!"unhandled floating type"); + if (varTypeIsUnsigned(srcType)) + ins = INS_ldrh; + else + ins = INS_ldrsh; } -#elif defined(TARGET_ARM64) - return INS_ldr; -#elif defined(TARGET_ARM) - return INS_vldr; #elif defined(TARGET_LOONGARCH64) - if (srcType == TYP_DOUBLE) + if (varTypeIsByte(srcType)) + { + if (varTypeIsUnsigned(srcType)) + ins = INS_ld_bu; + else + ins = INS_ld_b; + } + else if (varTypeIsShort(srcType)) { - return INS_fld_d; + if (varTypeIsUnsigned(srcType)) + ins = INS_ld_hu; + else + ins = INS_ld_h; } - else if (srcType == TYP_FLOAT) + else if (TYP_INT == srcType) { - return INS_fld_s; + ins = INS_ld_w; } else { - assert(!"unhandled floating type"); + ins = INS_ld_d; // default ld_d. } #elif defined(TARGET_RISCV64) - if (srcType == TYP_DOUBLE) + if (varTypeIsByte(srcType)) + { + if (varTypeIsUnsigned(srcType)) + ins = INS_lbu; + else + ins = INS_lb; + } + else if (varTypeIsShort(srcType)) { - return INS_fld; + if (varTypeIsUnsigned(srcType)) + ins = INS_lhu; + else + ins = INS_lh; } - else if (srcType == TYP_FLOAT) + else if (TYP_INT == srcType) { - return INS_flw; + ins = INS_lw; } else { - assert(!"unhandled floating type"); + ins = INS_ld; // default ld. } #else - assert(!varTypeIsFloating(srcType)); + NYI("ins_Load"); #endif - } -#if defined(TARGET_XARCH) - if (!varTypeIsSmall(srcType)) - { - ins = INS_mov; - } - else if (varTypeIsUnsigned(srcType)) - { - ins = INS_movzx; + assert(ins != INS_invalid); + return ins; } - else + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (varTypeUsesMaskReg(srcType)) { - ins = INS_movsx; + return INS_kmovq_msk; } +#endif // TARGET_XARCH && FEATURE_SIMD -#elif defined(TARGET_ARMARCH) - if (!varTypeIsSmall(srcType)) + assert(varTypeUsesFloatReg(srcType)); + +#if defined(TARGET_XARCH) + unsigned srcSize = genTypeSize(srcType); + + if (srcSize == 4) { - ins = INS_ldr; + return INS_movss; } - else if (varTypeIsByte(srcType)) + else if (srcSize == 8) { - if (varTypeIsUnsigned(srcType)) - ins = INS_ldrb; - else - ins = INS_ldrsb; + return INS_movsd_simd; } - else if (varTypeIsShort(srcType)) + else { - if (varTypeIsUnsigned(srcType)) - ins = INS_ldrh; - else - ins = INS_ldrsh; + assert((srcSize == 12) || (srcSize == 16) || (srcSize == 32) || (srcSize == 64)); + + // SSE2 Note: always prefer movaps/movups over movapd/movupd since the + // former doesn't require 66h prefix and one byte smaller than the + // latter. + + return (aligned) ? INS_movaps : INS_movups; } +#elif defined(TARGET_ARM64) + return INS_ldr; +#elif defined(TARGET_ARM) + assert(!varTypeIsSIMD(srcType)); + return INS_vldr; #elif defined(TARGET_LOONGARCH64) - if (varTypeIsByte(srcType)) - { - if (varTypeIsUnsigned(srcType)) - ins = INS_ld_bu; - else - ins = INS_ld_b; - } - else if (varTypeIsShort(srcType)) - { - if (varTypeIsUnsigned(srcType)) - ins = INS_ld_hu; - else - ins = INS_ld_h; - } - else if (TYP_INT == srcType) + assert(!varTypeIsSIMD(srcType)); + + if (srcType == TYP_DOUBLE) { - ins = INS_ld_w; + return INS_fld_d; } else { - ins = INS_ld_d; // default ld_d. + assert(srcType == TYP_FLOAT); + return INS_fld_s; } #elif defined(TARGET_RISCV64) - if (varTypeIsByte(srcType)) - { - if (varTypeIsUnsigned(srcType)) - ins = INS_lbu; - else - ins = INS_lb; - } - else if (varTypeIsShort(srcType)) - { - if (varTypeIsUnsigned(srcType)) - ins = INS_lhu; - else - ins = INS_lh; - } - else if (TYP_INT == srcType) + assert(!varTypeIsSIMD(srcType)); + + if (srcType == TYP_DOUBLE) { - ins = INS_lw; + return INS_fld; } else { - ins = INS_ld; // default ld. + assert(srcType == TYP_FLOAT); + return INS_flw; } #else NYI("ins_Load"); #endif - - assert(ins != INS_invalid); - return ins; } /***************************************************************************** @@ -1647,59 +1735,66 @@ instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false* instruction CodeGen::ins_Copy(var_types dstType) { assert(emitTypeActSz[dstType] != 0); -#if defined(TARGET_XARCH) - if (varTypeIsSIMD(dstType)) - { - return INS_movaps; - } - else if (varTypeIsFloating(dstType)) + + if (varTypeUsesIntReg(dstType)) { - // Both float and double copy can use movaps - return INS_movaps; +#if defined(TARGET_XARCH) || defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) + return INS_mov; +#else + NYI("ins_Copy"); +#endif } - else + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (varTypeUsesMaskReg(dstType)) { - return INS_mov; + return INS_kmovq_msk; } +#endif // TARGET_XARCH && FEATURE_SIMD + + assert(varTypeUsesFloatReg(dstType)); + +#if defined(TARGET_XARCH) + return INS_movaps; #elif defined(TARGET_ARM64) - if (varTypeIsFloating(dstType)) + if (varTypeIsSIMD(dstType)) { - return INS_fmov; + return INS_mov; } else { - return INS_mov; + assert(varTypeIsFloating(dstType)); + return INS_fmov; } #elif defined(TARGET_ARM) assert(!varTypeIsSIMD(dstType)); - if (varTypeIsFloating(dstType)) - { - return INS_vmov; - } - else - { - return INS_mov; - } + return INS_vmov; #elif defined(TARGET_LOONGARCH64) - if (varTypeIsFloating(dstType)) + assert(!varTypeIsSIMD(dstType)); + + if (dstType == TYP_DOUBLE) { - return dstType == TYP_FLOAT ? INS_fmov_s : INS_fmov_d; + return INS_fmov_d; } else { - return INS_mov; + assert(dstType == TYP_FLOAT); + return INS_fmov_s; } #elif defined(TARGET_RISCV64) - if (varTypeIsFloating(dstType)) + assert(!varTypeIsSIMD(dstType)); + + if (dstType == TYP_DOUBLE) { - return dstType == TYP_FLOAT ? INS_fsgnj_s : INS_fsgnj_d; + return INS_fsgnj_d; } else { - return INS_mov; + assert(dstType == TYP_FLOAT); + return INS_fsgnj_s; } -#else // TARGET_* -#error "Unknown TARGET" +#else + NYI("ins_Copy"); #endif } @@ -1717,67 +1812,111 @@ instruction CodeGen::ins_Copy(var_types dstType) // instruction CodeGen::ins_Copy(regNumber srcReg, var_types dstType) { - bool dstIsFloatReg = isFloatRegType(dstType); - bool srcIsFloatReg = genIsValidFloatReg(srcReg); - if (srcIsFloatReg == dstIsFloatReg) + assert(srcReg != REG_NA); + + if (varTypeUsesIntReg(dstType)) { - return ins_Copy(dstType); - } + if (genIsValidIntOrFakeReg(srcReg)) + { + // int to int + return ins_Copy(dstType); + } + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (genIsValidMaskReg(srcReg)) + { + // mask to int + return INS_kmovq_gpr; + } +#endif // TARGET_XARCH && FEATURE_SIMD + + // float to int + assert(genIsValidFloatReg(srcReg)); + #if defined(TARGET_XARCH) - return INS_movd; + return INS_movd; #elif defined(TARGET_ARM64) - if (dstIsFloatReg) - { - return INS_fmov; - } - else - { return INS_mov; - } #elif defined(TARGET_ARM) - // No SIMD support yet. - assert(!varTypeIsSIMD(dstType)); - if (dstIsFloatReg) - { - // Can't have LONG in a register. - assert(dstType == TYP_FLOAT); - return INS_vmov_i2f; - } - else - { // Can't have LONG in a register. assert(dstType == TYP_INT); + + assert(!varTypeIsSIMD(dstType)); return INS_vmov_f2i; +#elif defined(TARGET_LOONGARCH64) + assert(!varTypeIsSIMD(dstType)); + return EA_SIZE(emitActualTypeSize(dstType)) == EA_4BYTE ? INS_movfr2gr_s : INS_movfr2gr_d; +#elif defined(TARGET_RISCV64) + assert(!varTypeIsSIMD(dstType)); + return EA_SIZE(emitActualTypeSize(dstType)) == EA_4BYTE ? INS_fmv_x_w : INS_fmv_x_d; +#else + NYI("ins_Copy"); +#endif + } + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (varTypeUsesMaskReg(dstType)) + { + if (genIsValidMaskReg(srcReg)) + { + // mask to mask + return ins_Copy(dstType); + } + + // mask to int + assert(genIsValidIntOrFakeReg(srcReg)); + return INS_kmovq_gpr; + } +#endif // TARGET_XARCH && FEATURE_SIMD + + assert(varTypeUsesFloatReg(dstType)); + + if (genIsValidFloatReg(srcReg)) + { + // float to float + return ins_Copy(dstType); } + + // int to float + assert(genIsValidIntOrFakeReg(srcReg)); + +#if defined(TARGET_XARCH) + return INS_movd; +#elif defined(TARGET_ARM64) + return INS_fmov; +#elif defined(TARGET_ARM) + // Can't have LONG in a register. + assert(dstType == TYP_FLOAT); + + assert(!varTypeIsSIMD(dstType)); + return INS_vmov_i2f; #elif defined(TARGET_LOONGARCH64) - // TODO-LoongArch64-CQ: supporting SIMD. assert(!varTypeIsSIMD(dstType)); - if (dstIsFloatReg) + + if (dstType == TYP_DOUBLE) { - assert(!genIsValidFloatReg(srcReg)); - return dstType == TYP_FLOAT ? INS_movgr2fr_w : INS_movgr2fr_d; + return INS_movgr2fr_d; } else { - assert(genIsValidFloatReg(srcReg)); - return EA_SIZE(emitActualTypeSize(dstType)) == EA_4BYTE ? INS_movfr2gr_s : INS_movfr2gr_d; + assert(dstType == TYP_FLOAT); + return INS_movgr2fr_w; } #elif defined(TARGET_RISCV64) - // TODO-RISCV64-CQ: supporting SIMD. assert(!varTypeIsSIMD(dstType)); - if (dstIsFloatReg) + assert(!genIsValidFloatReg(srcReg)); + + if (dstType == TYP_DOUBLE) { - assert(!genIsValidFloatReg(srcReg)); - return dstType == TYP_FLOAT ? INS_fcvt_s_l : INS_fcvt_d_l; + return INS_fmv_d_x; } else { - assert(genIsValidFloatReg(srcReg)); - return EA_SIZE(emitActualTypeSize(dstType)) == EA_4BYTE ? INS_fcvt_w_d : INS_fcvt_l_d; + assert(dstType == TYP_FLOAT); + return INS_fmv_w_x; } - return INS_invalid; -#else // TARGET* -#error "Unknown TARGET" +#else + NYI("ins_Copy"); #endif } @@ -1792,116 +1931,106 @@ instruction CodeGen::ins_Copy(regNumber srcReg, var_types dstType) */ instruction CodeGenInterface::ins_Store(var_types dstType, bool aligned /*=false*/) { - instruction ins = INS_invalid; + if (varTypeUsesIntReg(dstType)) + { + instruction ins = INS_invalid; #if defined(TARGET_XARCH) - if (varTypeIsSIMD(dstType)) - { -#ifdef FEATURE_SIMD - if (dstType == TYP_SIMD8) - { - return INS_movsd_simd; - } + ins = INS_mov; +#elif defined(TARGET_ARMARCH) + if (!varTypeIsSmall(dstType)) + ins = INS_str; + else if (varTypeIsByte(dstType)) + ins = INS_strb; + else if (varTypeIsShort(dstType)) + ins = INS_strh; +#elif defined(TARGET_LOONGARCH64) + if (varTypeIsByte(dstType)) + ins = aligned ? INS_stx_b : INS_st_b; + else if (varTypeIsShort(dstType)) + ins = aligned ? INS_stx_h : INS_st_h; + else if (TYP_INT == dstType) + ins = aligned ? INS_stx_w : INS_st_w; else -#endif // FEATURE_SIMD - { - // SSE2 Note: always prefer movaps/movups over movapd/movupd since the - // former doesn't require 66h prefix and one byte smaller than the - // latter. - return (aligned) ? INS_movaps : INS_movups; - } + ins = aligned ? INS_stx_d : INS_st_d; +#elif defined(TARGET_RISCV64) + if (varTypeIsByte(dstType)) + ins = INS_sb; + else if (varTypeIsShort(dstType)) + ins = INS_sh; + else if (TYP_INT == dstType) + ins = INS_sw; + else + ins = INS_sd; +#else + NYI("ins_Store"); +#endif + assert(ins != INS_invalid); + return ins; } - else if (varTypeIsFloating(dstType)) + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (varTypeUsesMaskReg(dstType)) { - if (dstType == TYP_DOUBLE) - { - return INS_movsd_simd; - } - else if (dstType == TYP_FLOAT) - { - return INS_movss; - } - else - { - assert(!"unhandled floating type"); - } + return INS_kmovq_msk; } -#elif defined(TARGET_ARM64) - if (varTypeIsSIMD(dstType) || varTypeIsFloating(dstType)) +#endif // TARGET_XARCH && FEATURE_SIMD + + assert(varTypeUsesFloatReg(dstType)); + +#if defined(TARGET_XARCH) + unsigned dstSize = genTypeSize(dstType); + + if (dstSize == 4) { - // All sizes of SIMD and FP instructions use INS_str - return INS_str; + return INS_movss; } -#elif defined(TARGET_ARM) - assert(!varTypeIsSIMD(dstType)); - if (varTypeIsFloating(dstType)) + else if (dstSize == 8) { - return INS_vstr; + return INS_movsd_simd; + } + else + { + assert((dstSize == 12) || (dstSize == 16) || (dstSize == 32) || (dstSize == 64)); + + // SSE2 Note: always prefer movaps/movups over movapd/movupd since the + // former doesn't require 66h prefix and one byte smaller than the + // latter. + + return (aligned) ? INS_movaps : INS_movups; } +#elif defined(TARGET_ARM64) + return INS_str; +#elif defined(TARGET_ARM) + assert(!varTypeIsSIMD(dstType)); + return INS_vstr; #elif defined(TARGET_LOONGARCH64) assert(!varTypeIsSIMD(dstType)); - if (varTypeIsFloating(dstType)) + + if (dstType == TYP_DOUBLE) { - if (dstType == TYP_DOUBLE) - { - return aligned ? INS_fstx_d : INS_fst_d; - } - else if (dstType == TYP_FLOAT) - { - return aligned ? INS_fstx_s : INS_fst_s; - } + return aligned ? INS_fstx_d : INS_fst_d; } -#elif defined(TARGET_RISCV64) - assert(!varTypeIsSIMD(dstType)); - if (varTypeIsFloating(dstType)) + else { - if (dstType == TYP_DOUBLE) - { - return INS_fsd; - } - else if (dstType == TYP_FLOAT) - { - return INS_fsw; - } + assert(dstType == TYP_FLOAT); + return aligned ? INS_fstx_s : INS_fst_s; } -#else +#elif defined(TARGET_RISCV64) assert(!varTypeIsSIMD(dstType)); - assert(!varTypeIsFloating(dstType)); -#endif -#if defined(TARGET_XARCH) - ins = INS_mov; -#elif defined(TARGET_ARMARCH) - if (!varTypeIsSmall(dstType)) - ins = INS_str; - else if (varTypeIsByte(dstType)) - ins = INS_strb; - else if (varTypeIsShort(dstType)) - ins = INS_strh; -#elif defined(TARGET_LOONGARCH64) - if (varTypeIsByte(dstType)) - ins = aligned ? INS_stx_b : INS_st_b; - else if (varTypeIsShort(dstType)) - ins = aligned ? INS_stx_h : INS_st_h; - else if (TYP_INT == dstType) - ins = aligned ? INS_stx_w : INS_st_w; - else - ins = aligned ? INS_stx_d : INS_st_d; -#elif defined(TARGET_RISCV64) - if (varTypeIsByte(dstType)) - ins = INS_sb; - else if (varTypeIsShort(dstType)) - ins = INS_sh; - else if (TYP_INT == dstType) - ins = INS_sw; + if (dstType == TYP_DOUBLE) + { + return INS_fsd; + } else - ins = INS_sd; + { + assert(dstType == TYP_FLOAT); + return INS_fsw; + } #else NYI("ins_Store"); #endif - - assert(ins != INS_invalid); - return ins; } //------------------------------------------------------------------------ @@ -1919,34 +2048,88 @@ instruction CodeGenInterface::ins_StoreFromSrc(regNumber srcReg, var_types dstTy { assert(srcReg != REG_NA); - bool dstIsFloatType = isFloatRegType(dstType); - bool srcIsFloatReg = genIsValidFloatReg(srcReg); - if (srcIsFloatReg == dstIsFloatType) + if (varTypeUsesIntReg(dstType)) { + if (genIsValidIntOrFakeReg(srcReg)) + { + // int to int + return ins_Store(dstType, aligned); + } + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (genIsValidMaskReg(srcReg)) + { + // mask to int, treat as mask so it works on 32-bit + return ins_Store(TYP_MASK, aligned); + } +#endif // TARGET_XARCH && FEATURE_SIMD + + // float to int, treat as float to float + assert(genIsValidFloatReg(srcReg)); + + unsigned dstSize = genTypeSize(dstType); + + if (dstSize == 4) + { + dstType = TYP_FLOAT; + } + else + { +#if defined(TARGET_64BIT) + assert(dstSize == 8); + dstType = TYP_DOUBLE; +#else + unreached(); +#endif + } + return ins_Store(dstType, aligned); } - else + +#if defined(TARGET_XARCH) && defined(FEATURE_SIMD) + if (varTypeUsesMaskReg(dstType)) { - // We know that we are writing to memory, so make the destination type same - // as the source type. - var_types dstTypeForStore = TYP_UNDEF; - unsigned dstSize = genTypeSize(dstType); - switch (dstSize) + if (genIsValidMaskReg(srcReg)) + { + // mask to mask + return ins_Store(dstType, aligned); + } + + // mask to int, keep as mask so it works on 32-bit + assert(genIsValidIntOrFakeReg(srcReg)); + return ins_Store(dstType, aligned); + } +#endif // TARGET_XARCH && FEATURE_SIMD + + assert(varTypeUsesFloatReg(dstType)); + + if (genIsValidIntOrFakeReg(srcReg)) + { + // int to float, treat as int to int + + unsigned dstSize = genTypeSize(dstType); + + if (dstSize == 4) + { + dstType = TYP_INT; + } + else { - case 4: - dstTypeForStore = srcIsFloatReg ? TYP_FLOAT : TYP_INT; - break; #if defined(TARGET_64BIT) - case 8: - dstTypeForStore = srcIsFloatReg ? TYP_DOUBLE : TYP_LONG; - break; -#endif // TARGET_64BIT - default: - assert(!"unexpected write to the stack."); - break; + assert(dstSize == 8); + dstType = TYP_LONG; +#else + unreached(); +#endif } - return ins_Store(dstTypeForStore, aligned); } + else + { + // float to float + assert(genIsValidFloatReg(srcReg)); + } + + return ins_Store(dstType, aligned); } #if defined(TARGET_XARCH) @@ -2197,6 +2380,8 @@ void CodeGen::instGen_Return(unsigned stkArgSize) */ void CodeGen::instGen_Set_Reg_To_Zero(emitAttr size, regNumber reg, insFlags flags) { + assert(genIsValidIntOrFakeReg(reg)); + #if defined(TARGET_XARCH) GetEmitter()->emitIns_R_R(INS_xor, size, reg, reg); #elif defined(TARGET_ARM) @@ -2210,6 +2395,7 @@ void CodeGen::instGen_Set_Reg_To_Zero(emitAttr size, regNumber reg, insFlags fla #else #error "Unknown TARGET" #endif + regSet.verifyRegUsed(reg); } diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index e67de8a9aaa49f..189a0d66bd8535 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -195,8 +195,8 @@ INST3(addps, "addps", IUM_WR, BAD_CODE, BAD_CODE, INST3(addss, "addss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x58), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Add scalar singles INST3(andnps, "andnps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x55), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // And-Not packed singles INST3(andps, "andps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x54), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // AND packed singles -INST3(cmpps, "cmpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0xC2), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed singles -INST3(cmpss, "cmpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xC2), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar singles +INST3(cmpps, "cmpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0xC2), INS_TT_NONE, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed singles +INST3(cmpss, "cmpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xC2), INS_TT_NONE, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar singles INST3(comiss, "comiss", IUM_RD, BAD_CODE, BAD_CODE, PCKFLT(0x2F), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Writes_PF | Writes_CF) // ordered compare singles INST3(cvtsi2ss32, "cvtsi2ss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x2A), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // cvt DWORD to scalar single INST3(cvtsi2ss64, "cvtsi2ss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x2A), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // cvt QWORD to scalar single @@ -244,8 +244,8 @@ INST3(addpd, "addpd", IUM_WR, BAD_CODE, BAD_CODE, INST3(addsd, "addsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x58), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Add scalar doubles INST3(andnpd, "andnpd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x55), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // And-Not packed doubles INST3(andpd, "andpd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x54), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // AND packed doubles -INST3(cmppd, "cmppd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC2), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed doubles -INST3(cmpsd, "cmpsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0xC2), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar doubles +INST3(cmppd, "cmppd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC2), INS_TT_NONE, Input_64Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed doubles +INST3(cmpsd, "cmpsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0xC2), INS_TT_NONE, Input_64Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar doubles INST3(comisd, "comisd", IUM_RD, BAD_CODE, BAD_CODE, PCKDBL(0x2F), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Writes_PF | Writes_CF) // ordered compare doubles INST3(cvtdq2pd, "cvtdq2pd", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xE6), INS_TT_HALF, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX) // cvt packed DWORDs to doubles INST3(cvtdq2ps, "cvtdq2ps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x5B), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX) // cvt packed DWORDs to singles @@ -301,12 +301,12 @@ INST3(pand, "pand", IUM_WR, BAD_CODE, BAD_CODE, INST3(pandn, "pandn", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDF), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise AND NOT of two xmm regs INST3(pavgb, "pavgb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xE0), INS_TT_FULL_MEM, Input_8Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Average of packed byte integers INST3(pavgw, "pavgw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xE3), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Average of packed word integers -INST3(pcmpeqb, "pcmpeqb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x74), INS_TT_FULL_MEM, Input_8Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit integers for equality -INST3(pcmpeqd, "pcmpeqd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x76), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 32-bit integers for equality -INST3(pcmpeqw, "pcmpeqw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x75), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit integers for equality -INST3(pcmpgtb, "pcmpgtb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x64), INS_TT_FULL_MEM, Input_8Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit signed integers for greater than -INST3(pcmpgtd, "pcmpgtd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x66), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 32-bit signed integers for greater than -INST3(pcmpgtw, "pcmpgtw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x65), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit signed integers for greater than +INST3(pcmpeqb, "pcmpeqb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x74), INS_TT_NONE, Input_8Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit integers for equality +INST3(pcmpeqd, "pcmpeqd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x76), INS_TT_NONE, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 32-bit integers for equality +INST3(pcmpeqw, "pcmpeqw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x75), INS_TT_NONE, Input_16Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit integers for equality +INST3(pcmpgtb, "pcmpgtb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x64), INS_TT_NONE, Input_8Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit signed integers for greater than +INST3(pcmpgtd, "pcmpgtd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x66), INS_TT_NONE, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 32-bit signed integers for greater than +INST3(pcmpgtw, "pcmpgtw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x65), INS_TT_NONE, Input_16Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit signed integers for greater than INST3(pextrw, "pextrw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC5), INS_TT_TUPLE1_SCALAR, Input_16Bit | REX_W0 | Encoding_VEX | Encoding_EVEX) // Extract 16-bit value into a r32 with zero extended to 32-bits INST3(pinsrw, "pinsrw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC4), INS_TT_TUPLE1_SCALAR, Input_16Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert word at index INST3(pmaddwd, "pmaddwd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xF5), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply packed signed 16-bit integers in a and b, producing intermediate signed 32-bit integers. Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in dst @@ -335,8 +335,8 @@ INST3(psrldq, "psrldq", IUM_WR, BAD_CODE, PCKDBL(0x73), INST3(psrlq, "psrlq", IUM_WR, BAD_CODE, PCKDBL(0x73), PCKDBL(0xD3), INS_TT_FULL | INS_TT_MEM128, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed shift right logical of 64-bit integers INST3(psrlw, "psrlw", IUM_WR, BAD_CODE, PCKDBL(0x71), PCKDBL(0xD1), INS_TT_FULL_MEM | INS_TT_MEM128, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed shift right logical of 16-bit integers INST3(psubb, "psubb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xF8), INS_TT_FULL_MEM, Input_8Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Subtract packed word (16-bit) integers -INST3(psubd, "psubd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xFA), INS_TT_FULL_MEM, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Subtract packed double-word (32-bit) integers -INST3(psubq, "psubq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xFB), INS_TT_FULL_MEM, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // subtract packed quad-word (64-bit) integers +INST3(psubd, "psubd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xFA), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Subtract packed double-word (32-bit) integers +INST3(psubq, "psubq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xFB), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // subtract packed quad-word (64-bit) integers INST3(psubw, "psubw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xF9), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Subtract packed word (16-bit) integers INST3(psubsb, "psubsb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xE8), INS_TT_FULL_MEM, Input_8Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Subtract packed 8-bit integers in b from packed 8-bit integers in a using saturation INST3(psubsw, "psubsw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xE9), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Subtract packed 16-bit integers in b from packed 16-bit integers in a using saturation @@ -414,7 +414,7 @@ INST3(mpsadbw, "mpsadbw", IUM_WR, BAD_CODE, BAD_CODE, INST3(packusdw, "packusdw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x2B), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Pack (narrow) int to unsigned short with saturation INST3(pblendvb, "pblendvb", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x10), INS_TT_NONE, Input_8Bit | REX_W0) // Variable Blend Packed Bytes INST3(pblendw, "pblendw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0E), INS_TT_NONE, Input_16Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Blend Packed Words -INST3(pcmpeqq, "pcmpeqq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x29), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 64-bit integers for equality +INST3(pcmpeqq, "pcmpeqq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x29), INS_TT_NONE, Input_64Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 64-bit integers for equality INST3(pextrb, "pextrb", IUM_WR, SSE3A(0x14), BAD_CODE, BAD_CODE, INS_TT_TUPLE1_SCALAR, Input_8Bit | REX_W0 | Encoding_VEX | Encoding_EVEX) // Extract Byte INST3(pextrd, "pextrd", IUM_WR, SSE3A(0x16), BAD_CODE, BAD_CODE, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX) // Extract Dword INST3(pextrq, "pextrq", IUM_WR, SSE3A(0x16), BAD_CODE, BAD_CODE, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX) // Extract Qword @@ -445,14 +445,14 @@ INST3(pmovzxwd, "pmovzxwd", IUM_WR, BAD_CODE, BAD_CODE, INST3(pmovzxwq, "pmovzxwq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x34), INS_TT_QUARTER_MEM, Input_16Bit | REX_WIG | Encoding_VEX | Encoding_EVEX) // Packed zero extend short to long INST3(pmuldq, "pmuldq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x28), INS_TT_FULL, Input_32Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed multiply 32-bit signed integers and store 64-bit result INST3(pmulld, "pmulld", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x40), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed multiply 32 bit unsigned integers and store lower 32 bits of each result -INST3(ptest, "ptest", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x17), INS_TT_NONE, REX_WIG | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF) // Packed logical compare -INST3(roundpd, "roundpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x09), INS_TT_NONE, Input_64Bit | REX_WIG | Encoding_VEX) // Round packed double precision floating-point values -INST3(roundps, "roundps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x08), INS_TT_NONE, Input_32Bit | REX_WIG | Encoding_VEX) // Round packed single precision floating-point values -INST3(roundsd, "roundsd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0B), INS_TT_NONE, Input_64Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar double precision floating-point values -INST3(roundss, "roundss", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0A), INS_TT_NONE, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar single precision floating-point values +INST3(ptest, "ptest", IUM_RD, BAD_CODE, BAD_CODE, SSE38(0x17), INS_TT_NONE, REX_WIG | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF) // Packed logical compare +INST3(roundpd, "roundpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x09), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX) // Round packed double precision floating-point values +INST3(roundps, "roundps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x08), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX) // Round packed single precision floating-point values +INST3(roundsd, "roundsd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0B), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar double precision floating-point values +INST3(roundss, "roundss", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0A), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar single precision floating-point values // SSE4.2 -INST3(pcmpgtq, "pcmpgtq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x37), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 64-bit integers for equality +INST3(pcmpgtq, "pcmpgtq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x37), INS_TT_NONE, Input_64Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 64-bit integers for equality INST3(LAST_SSE_INSTRUCTION, "LAST_SSE_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) @@ -474,8 +474,8 @@ INST3(vpermilpd, "permilpd", IUM_WR, BAD_CODE, BAD_CODE, INST3(vpermilpdvar, "permilpd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x0D), INS_TT_FULL, Input_64Bit | REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Permute In-Lane of Quadruples of Double-Precision Floating-Point Values INST3(vpermilps, "permilps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x04), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX) // Permute In-Lane of Quadruples of Single-Precision Floating-Point Values INST3(vpermilpsvar, "permilps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x0C), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Permute In-Lane of Quadruples of Single-Precision Floating-Point Values -INST3(vtestpd, "testpd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x0F), INS_TT_NONE, Input_64Bit | REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF) // Packed Bit Test -INST3(vtestps, "testps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x0E), INS_TT_NONE, Input_32Bit | REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF) // Packed Bit Test +INST3(vtestpd, "testpd", IUM_RD, BAD_CODE, BAD_CODE, SSE38(0x0F), INS_TT_NONE, Input_64Bit | REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF) // Packed Bit Test +INST3(vtestps, "testps", IUM_RD, BAD_CODE, BAD_CODE, SSE38(0x0E), INS_TT_NONE, Input_32Bit | REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF) // Packed Bit Test INST3(vzeroupper, "zeroupper", IUM_WR, 0xC577F8, BAD_CODE, BAD_CODE, INS_TT_NONE, REX_WIG | Encoding_VEX) // Zero upper 128-bits of all YMM regs (includes 2-byte fixed VEX prefix) // AVX2 @@ -510,66 +510,66 @@ INST3(vpsrlvq, "psrlvq", IUM_WR, BAD_CODE, BAD_CODE, INST3(FIRST_FMA_INSTRUCTION, "FIRST_FMA_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) // id nm um mr mi rm flags -INST3(vfmadd132pd, "fmadd132pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x98), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Packed Double-Precision Floating-Point Values -INST3(vfmadd213pd, "fmadd213pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA8), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmadd231pd, "fmadd231pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB8), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmadd132ps, "fmadd132ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x98), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Packed Single-Precision Floating-Point Values -INST3(vfmadd213ps, "fmadd213ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA8), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmadd231ps, "fmadd231ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB8), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmadd132sd, "fmadd132sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x99), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Scalar Double-Precision Floating-Point Values -INST3(vfmadd213sd, "fmadd213sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA9), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmadd231sd, "fmadd231sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB9), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmadd132ss, "fmadd132ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x99), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Scalar Single-Precision Floating-Point Values -INST3(vfmadd213ss, "fmadd213ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA9), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmadd231ss, "fmadd231ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB9), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmaddsub132pd, "fmaddsub132pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x96), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values -INST3(vfmaddsub213pd, "fmaddsub213pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA6), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmaddsub231pd, "fmaddsub231pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB6), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmaddsub132ps, "fmaddsub132ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x96), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values -INST3(vfmaddsub213ps, "fmaddsub213ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA6), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmaddsub231ps, "fmaddsub231ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB6), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsubadd132pd, "fmsubadd132pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x97), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values -INST3(vfmsubadd213pd, "fmsubadd213pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA7), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsubadd231pd, "fmsubadd231pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB7), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsubadd132ps, "fmsubadd132ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x97), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values -INST3(vfmsubadd213ps, "fmsubadd213ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xA7), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsubadd231ps, "fmsubadd231ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xB7), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub132pd, "fmsub132pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9A), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values -INST3(vfmsub213pd, "fmsub213pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAA), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub231pd, "fmsub231pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBA), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub132ps, "fmsub132ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9A), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values -INST3(vfmsub213ps, "fmsub213ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAA), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub231ps, "fmsub231ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBA), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub132sd, "fmsub132sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9B), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values -INST3(vfmsub213sd, "fmsub213sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAB), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub231sd, "fmsub231sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBB), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub132ss, "fmsub132ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9B), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values -INST3(vfmsub213ss, "fmsub213ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAB), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfmsub231ss, "fmsub231ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBB), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd132pd, "fnmadd132pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9C), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values -INST3(vfnmadd213pd, "fnmadd213pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAC), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd231pd, "fnmadd231pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBC), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd132ps, "fnmadd132ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9C), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values -INST3(vfnmadd213ps, "fnmadd213ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAC), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd231ps, "fnmadd231ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBC), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd132sd, "fnmadd132sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9D), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values -INST3(vfnmadd213sd, "fnmadd213sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAD), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd231sd, "fnmadd231sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBD), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd132ss, "fnmadd132ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9D), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values -INST3(vfnmadd213ss, "fnmadd213ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAD), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmadd231ss, "fnmadd231ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBD), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub132pd, "fnmsub132pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9E), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values -INST3(vfnmsub213pd, "fnmsub213pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAE), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub231pd, "fnmsub231pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBE), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub132ps, "fnmsub132ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9E), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values -INST3(vfnmsub213ps, "fnmsub213ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAE), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub231ps, "fnmsub231ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBE), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub132sd, "fnmsub132sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9F), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values -INST3(vfnmsub213sd, "fnmsub213sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAF), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub231sd, "fnmsub231sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBF), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub132ss, "fnmsub132ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x9F), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values -INST3(vfnmsub213ss, "fnmsub213ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xAF), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // -INST3(vfnmsub231ss, "fnmsub231ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xBF), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd132pd, "fmadd132pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x98), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Packed Double-Precision Floating-Point Values +INST3(vfmadd213pd, "fmadd213pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA8), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd231pd, "fmadd231pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB8), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd132ps, "fmadd132ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x98), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Packed Single-Precision Floating-Point Values +INST3(vfmadd213ps, "fmadd213ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA8), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd231ps, "fmadd231ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB8), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd132sd, "fmadd132sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x99), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Scalar Double-Precision Floating-Point Values +INST3(vfmadd213sd, "fmadd213sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA9), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd231sd, "fmadd231sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB9), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd132ss, "fmadd132ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x99), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Add of Scalar Single-Precision Floating-Point Values +INST3(vfmadd213ss, "fmadd213ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA9), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmadd231ss, "fmadd231ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB9), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmaddsub132pd, "fmaddsub132pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x96), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values +INST3(vfmaddsub213pd, "fmaddsub213pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA6), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmaddsub231pd, "fmaddsub231pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB6), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmaddsub132ps, "fmaddsub132ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x96), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values +INST3(vfmaddsub213ps, "fmaddsub213ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA6), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmaddsub231ps, "fmaddsub231ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB6), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsubadd132pd, "fmsubadd132pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x97), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values +INST3(vfmsubadd213pd, "fmsubadd213pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA7), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsubadd231pd, "fmsubadd231pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB7), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsubadd132ps, "fmsubadd132ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x97), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values +INST3(vfmsubadd213ps, "fmsubadd213ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xA7), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsubadd231ps, "fmsubadd231ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB7), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub132pd, "fmsub132pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9A), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values +INST3(vfmsub213pd, "fmsub213pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAA), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub231pd, "fmsub231pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBA), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub132ps, "fmsub132ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9A), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values +INST3(vfmsub213ps, "fmsub213ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAA), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub231ps, "fmsub231ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBA), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub132sd, "fmsub132sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9B), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values +INST3(vfmsub213sd, "fmsub213sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAB), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub231sd, "fmsub231sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBB), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub132ss, "fmsub132ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9B), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values +INST3(vfmsub213ss, "fmsub213ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAB), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfmsub231ss, "fmsub231ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBB), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd132pd, "fnmadd132pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9C), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values +INST3(vfnmadd213pd, "fnmadd213pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAC), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd231pd, "fnmadd231pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBC), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd132ps, "fnmadd132ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9C), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values +INST3(vfnmadd213ps, "fnmadd213ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAC), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd231ps, "fnmadd231ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBC), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd132sd, "fnmadd132sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9D), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values +INST3(vfnmadd213sd, "fnmadd213sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAD), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd231sd, "fnmadd231sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBD), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd132ss, "fnmadd132ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9D), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values +INST3(vfnmadd213ss, "fnmadd213ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAD), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmadd231ss, "fnmadd231ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBD), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub132pd, "fnmsub132pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9E), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values +INST3(vfnmsub213pd, "fnmsub213pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAE), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub231pd, "fnmsub231pd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBE), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub132ps, "fnmsub132ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9E), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values +INST3(vfnmsub213ps, "fnmsub213ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAE), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub231ps, "fnmsub231ps", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBE), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub132sd, "fnmsub132sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9F), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values +INST3(vfnmsub213sd, "fnmsub213sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAF), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub231sd, "fnmsub231sd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBF), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub132ss, "fnmsub132ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x9F), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values +INST3(vfnmsub213ss, "fnmsub213ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xAF), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // +INST3(vfnmsub231ss, "fnmsub231ss", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xBF), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // INST3(LAST_FMA_INSTRUCTION, "LAST_FMA_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) INST3(FIRST_AVXVNNI_INSTRUCTION, "FIRST_AVXVNNI_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) @@ -610,69 +610,183 @@ INST3(FIRST_AVX512_INSTRUCTION, "FIRST_AVX512_INSTRUCTION", IUM_WR, BAD_CODE, BA // AVX512F INST3(kmovw_gpr, "kmovw", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x92), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) INST3(kmovw_msk, "kmovw", IUM_WR, PCKFLT(0x91), BAD_CODE, PCKFLT(0x90), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) -INST3(kortestw, "kortestw", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x98), INS_TT_NONE, REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) -INST3(vextractf64x4, "extractf64x4", IUM_WR, SSE3A(0x1B), BAD_CODE, BAD_CODE, INS_TT_TUPLE4, Input_64Bit | REX_W1_EVEX | Encoding_EVEX) // Extract 256-bit packed double-precision floating point values -INST3(vextracti64x4, "extracti64x4", IUM_WR, SSE3A(0x3B), BAD_CODE, BAD_CODE, INS_TT_TUPLE4, Input_64Bit | REX_W1_EVEX | Encoding_EVEX) // Extract 256-bit packed quadword integer values -INST3(vinsertf64x4, "insertf64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1A), INS_TT_TUPLE4, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed double-precision floating point values -INST3(vinserti64x4, "inserti64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3A), INS_TT_TUPLE4, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed quadword integer values -INST3(vmovdqa64, "movdqa64", IUM_WR, PCKDBL(0x7F), BAD_CODE, PCKDBL(0x6F), INS_TT_FULL_MEM, Input_64Bit | REX_W1_EVEX | Encoding_EVEX) -INST3(vmovdqu64, "movdqu64", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_64Bit | REX_W1_EVEX | Encoding_EVEX) -INST3(vpabsq, "pabsq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1F), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX) // Packed absolute value of 64-bit integers -INST3(vpandq, "pandq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDB), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise AND of two xmm regs -INST3(vpandnq, "pandnq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDF), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise AND NOT of two xmm regs -INST3(vpmaxsq, "pmaxsq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x3D), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed maximum 64-bit signed integers -INST3(vpmaxuq, "pmaxuq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x3F), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed maximum 64-bit unsigned integers -INST3(vpminsq, "pminsq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x39), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed minimum 64-bit signed integers -INST3(vpminuq, "pminuq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x3B), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed minimum 64-bit unsigned integers -INST3(vpmovdw, "pmovdw", IUM_WR, PSSE38(0xF3, 0x33), BAD_CODE, PSSE38(0xF3, 0x33), INS_TT_HALF_MEM, Input_32Bit | REX_W0_EVEX | Encoding_EVEX) -INST3(vpmovqd, "pmovqd", IUM_WR, PSSE38(0xF3, 0x35), BAD_CODE, PSSE38(0xF3, 0x35), INS_TT_HALF_MEM, Input_64Bit | REX_W0_EVEX | Encoding_EVEX) -INST3(vporq, "porq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEB), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise OR of two xmm regs -INST3(vpsraq, "psraq", IUM_WR, BAD_CODE, PCKDBL(0x72), PCKDBL(0xE2), INS_TT_FULL | INS_TT_MEM128, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed shift right arithmetic of 64-bit integers -INST3(vpternlogd, "pternlogd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x25), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) -INST3(vpxorq, "pxorq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEF), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise XOR of two xmm regs +INST3(kortestw, "kortestw", IUM_RD, BAD_CODE, BAD_CODE, PCKFLT(0x98), INS_TT_NONE, REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) +INST3(vbroadcastf64x2, "broadcastf64x2", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1A), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast packed float values read from memory to entire register +INST3(vbroadcasti64x2, "broadcasti64x2", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5A), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register +INST3(vbroadcastf64x4, "broadcastf64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1B), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast packed float values read from memory to entire register +INST3(vbroadcasti64x4, "broadcasti64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5B), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register +INST3(vcmpps, "cmpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0xC2), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // compare packed singles +INST3(vcmpss, "cmpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xC2), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // compare scalar singles +INST3(vcmppd, "cmppd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC2), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // compare packed doubles +INST3(vcmpsd, "cmpsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0xC2), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // compare scalar doubles +INST3(vcvtpd2udq, "cvtpd2udq", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x79), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt packed doubles to unsigned DWORDs +INST3(vcvtps2udq, "cvtps2udq", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x79), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt packed singles to unsigned DWORDs +INST3(vcvtsd2usi, "cvtsd2usi", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x79), INS_TT_TUPLE1_FIXED, Input_64Bit | REX_WX | Encoding_EVEX) // cvt scalar double to unsigned DWORD/QWORD +INST3(vcvtss2usi, "cvtss2usi", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x79), INS_TT_TUPLE1_FIXED, Input_32Bit | REX_WX | Encoding_EVEX) // cvt scalar single to unsigned DWORD/QWORD +INST3(vcvttpd2udq, "cvttpd2udq", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x78), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt w/ truncation packed doubles to unsigned DWORDs +INST3(vcvttps2udq, "cvttps2udq", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x78), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt w/ truncation packed singles to unsigned DWORDs +INST3(vcvttsd2usi, "cvttsd2usi", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x78), INS_TT_TUPLE1_FIXED, Input_64Bit | REX_WX | Encoding_EVEX) // cvt w/ truncation scalar double to unsigned DWORD/QWORD +INST3(vcvttss2usi, "cvttss2usi", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x78), INS_TT_TUPLE1_FIXED, Input_32Bit | REX_WX | Encoding_EVEX) // cvt w/ truncation scalar single to unsigned DWORD/QWORD +INST3(vcvtudq2pd, "cvtudq2pd", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x7A), INS_TT_HALF, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt packed unsigned DWORDs to doubles +INST3(vcvtudq2ps, "cvtudq2ps", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x7A), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt packed unsigned DWORDs to singles +INST3(vcvtusi2sd32, "cvtusi2sd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x7B), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // cvt scalar unsigned DWORD to double +INST3(vcvtusi2sd64, "cvtusi2sd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x7B), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // cvt scalar unsigned QWORD to double +INST3(vcvtusi2ss32, "cvtusi2ss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x7B), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // cvt scalar unsigned DWORD to single +INST3(vcvtusi2ss64, "cvtusi2ss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x7B), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // cvt scalar unsigned QWORD to single +INST3(vextractf64x4, "extractf64x4", IUM_WR, SSE3A(0x1B), BAD_CODE, BAD_CODE, INS_TT_TUPLE4, Input_64Bit | REX_W1 | Encoding_EVEX) // Extract 256-bit packed double-precision floating point values +INST3(vextracti64x4, "extracti64x4", IUM_WR, SSE3A(0x3B), BAD_CODE, BAD_CODE, INS_TT_TUPLE4, Input_64Bit | REX_W1 | Encoding_EVEX) // Extract 256-bit packed quadword integer values +INST3(vfixupimmpd, "fixupimmpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x54), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fixup special packed double-precision floating-point values +INST3(vfixupimmps, "fixupimmps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x54), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fixup special packed single-precision floating-point values +INST3(vfixupimmsd, "fixupimmsd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x55), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fixup special scalar double-precision floating-point value +INST3(vfixupimmss, "fixupimmss", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x55), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Fixup special scalar single-precision floating-point value +INST3(vgetexppd, "getexppd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x42), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Extract exponents of packed double-precision floating-point values +INST3(vgetexpps, "getexpps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x42), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Extract exponents of packed single-precision floating-point values +INST3(vgetexpsd, "getexpsd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x43), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Extract exponents of scalar double-precision floating-point value +INST3(vgetexpss, "getexpss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x43), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Extract exponents of scalar single-precision floating-point value +INST3(vgetmantpd, "getmantpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x26), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Extract mantissas of packed double-precision floating-point values +INST3(vgetmantps, "getmantps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x26), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Extract mantissas of packed single-precision floating-point values +INST3(vgetmantsd, "getmantsd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x27), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Extract mantissas of scalar double-precision floating-point value +INST3(vgetmantss, "getmantss", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x27), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Extract mantissas of scalar single-precision floating-point value +INST3(vinsertf64x4, "insertf64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1A), INS_TT_TUPLE4, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed double-precision floating point values +INST3(vinserti64x4, "inserti64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3A), INS_TT_TUPLE4, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed quadword integer values +INST3(vmovdqa64, "movdqa64", IUM_WR, PCKDBL(0x7F), BAD_CODE, PCKDBL(0x6F), INS_TT_FULL_MEM, Input_64Bit | REX_W1 | Encoding_EVEX) +INST3(vmovdqu64, "movdqu64", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_64Bit | REX_W1 | Encoding_EVEX) +INST3(vpabsq, "pabsq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1F), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Packed absolute value of 64-bit integers +INST3(vpandq, "pandq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDB), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise AND of two xmm regs +INST3(vpandnq, "pandnq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDF), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise AND NOT of two xmm regs +INST3(vpbroadcastd_gpr, "pbroadcastd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7C), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX) // Broadcast int32 value from gpr to entire register +INST3(vpbroadcastq_gpr, "pbroadcastq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7C), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast int64 value from gpr to entire register +INST3(vpcmpeqd, "pcmpeqd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x76), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 32-bit integers for equality +INST3(vpcmpgtd, "pcmpgtd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x66), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 32-bit signed integers for greater than +INST3(vpcmpeqq, "pcmpeqq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x29), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 64-bit integers for equality +INST3(vpcmpgtq, "pcmpgtq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x37), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 64-bit integers for equality +INST3(vpermq_reg, "permq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x36), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Permute 64-bit of input register +INST3(vpermpd_reg, "permpd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x16), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Permute 64-bit of input register +INST3(vpmaxsq, "pmaxsq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x3D), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed maximum 64-bit signed integers +INST3(vpmaxuq, "pmaxuq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x3F), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed maximum 64-bit unsigned integers +INST3(vpminsq, "pminsq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x39), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed minimum 64-bit signed integers +INST3(vpminuq, "pminuq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x3B), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed minimum 64-bit unsigned integers +INST3(vpmovdb, "pmovdb", IUM_WR, PSSE38(0xF3, 0x31), BAD_CODE, PSSE38(0xF3, 0x31), INS_TT_QUARTER_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovdw, "pmovdw", IUM_WR, PSSE38(0xF3, 0x33), BAD_CODE, PSSE38(0xF3, 0x33), INS_TT_HALF_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovqb, "pmovqb", IUM_WR, PSSE38(0xF3, 0x32), BAD_CODE, PSSE38(0xF3, 0x32), INS_TT_EIGHTH_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovqd, "pmovqd", IUM_WR, PSSE38(0xF3, 0x35), BAD_CODE, PSSE38(0xF3, 0x35), INS_TT_HALF_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovqw, "pmovqw", IUM_WR, PSSE38(0xF3, 0x34), BAD_CODE, PSSE38(0xF3, 0x34), INS_TT_QUARTER_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovsdb, "pmovsdb", IUM_WR, PSSE38(0xF3, 0x21), BAD_CODE, PSSE38(0xF3, 0x21), INS_TT_QUARTER_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovsdw, "pmovsdw", IUM_WR, PSSE38(0xF3, 0x23), BAD_CODE, PSSE38(0xF3, 0x23), INS_TT_HALF_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovsqb, "pmovsqb", IUM_WR, PSSE38(0xF3, 0x22), BAD_CODE, PSSE38(0xF3, 0x22), INS_TT_EIGHTH_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovsqd, "pmovsqd", IUM_WR, PSSE38(0xF3, 0x25), BAD_CODE, PSSE38(0xF3, 0x25), INS_TT_HALF_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovsqw, "pmovsqw", IUM_WR, PSSE38(0xF3, 0x24), BAD_CODE, PSSE38(0xF3, 0x24), INS_TT_QUARTER_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovusdb, "pmovusdb", IUM_WR, PSSE38(0xF3, 0x11), BAD_CODE, PSSE38(0xF3, 0x11), INS_TT_QUARTER_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovusdw, "pmovusdw", IUM_WR, PSSE38(0xF3, 0x13), BAD_CODE, PSSE38(0xF3, 0x13), INS_TT_HALF_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovusqb, "pmovusqb", IUM_WR, PSSE38(0xF3, 0x12), BAD_CODE, PSSE38(0xF3, 0x12), INS_TT_EIGHTH_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovusqd, "pmovusqd", IUM_WR, PSSE38(0xF3, 0x15), BAD_CODE, PSSE38(0xF3, 0x15), INS_TT_HALF_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovusqw, "pmovusqw", IUM_WR, PSSE38(0xF3, 0x14), BAD_CODE, PSSE38(0xF3, 0x14), INS_TT_QUARTER_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) +INST3(vporq, "porq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEB), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise OR of two xmm regs +INST3(vpsraq, "psraq", IUM_WR, BAD_CODE, PCKDBL(0x72), PCKDBL(0xE2), INS_TT_FULL | INS_TT_MEM128, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed shift right arithmetic of 64-bit integers +INST3(vpsravq, "psravq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x46), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Right Arithmetic +INST3(vpternlogd, "pternlogd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x25), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) +INST3(vpxorq, "pxorq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEF), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise XOR of two xmm regs +INST3(vrangepd, "rangepd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x50), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Range restriction calculation from a pair of packed double-precision floating-point values +INST3(vrangeps, "rangeps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x50), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Range restriction calculation from a pair of packed single-precision floating-point values +INST3(vrangesd, "rangesd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x51), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Range restriction calculation from a pair of scalar double-precision floating-point value +INST3(vrangess, "rangess", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x51), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Range restriction calculation from a pair of scalar single-precision floating-point value +INST3(vrcp14pd, "rcp14pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4C), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Compute approximate reciprocals of packed double-precision floating-point values +INST3(vrcp14ps, "rcp14ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4C), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Compute approximate reciprocals of packed single-precision floating-point values +INST3(vrcp14sd, "rcp14sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4D), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Compute approximate reciprocals of scalar double-precision floating-point value +INST3(vrcp14ss, "rcp14ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4D), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Compute approximate reciprocals of scalar single-precision floating-point value +INST3(vreducepd, "reducepd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x56), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Perform a reduction transformation on packed double-precision floating-point values +INST3(vreduceps, "reduceps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x56), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Perform a reduction transformation on packed single-precision floating-point values +INST3(vreducesd, "reducesd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x57), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Perform a reduction transformation on scalar double-precision floating-point value +INST3(vreducess, "reducess", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x57), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Perform a reduction transformation on scalar single-precision floating-point value +INST3(vrndscalepd, "rndscalepd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x09), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Round packed double-precision floating-point values to include a given number of fraction bits +INST3(vrndscaleps, "rndscaleps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x08), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Round packed single-precision floating-point values to include a given number of fraction bits +INST3(vrndscalesd, "rndscalesd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0B), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar double-precision floating-point value to include a given number of fraction bits +INST3(vrndscaless, "rndscaless", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0A), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar single-precision floating-point value to include a given number of fraction bits +INST3(vrsqrt14pd, "rsqrt14pd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4E), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Compute approximate reciprocals of square roots of packed double-precision floating-point values +INST3(vrsqrt14ps, "rsqrt14ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4E), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Compute approximate reciprocals of square roots of packed single-precision floating-point values +INST3(vrsqrt14sd, "rsqrt14sd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4F), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Compute approximate reciprocals of square roots of scalar double-precision floating-point value +INST3(vrsqrt14ss, "rsqrt14ss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x4F), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Compute approximate reciprocals of square roots of scalar single-precision floating-point value +INST3(vscalefpd, "scalefpd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x2C), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Scale packed double-precision floating-point values +INST3(vscalefps, "scalefps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x2C), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Scale packed single-precision floating-point values +INST3(vscalefsd, "scalefsd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x2D), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Scale scalar double-precision floating-point value +INST3(vscalefss, "scalefss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x2D), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Scale scalar single-precision floating-point value // AVX512BW INST3(kmovd_gpr, "kmovd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x92), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) INST3(kmovd_msk, "kmovd", IUM_WR, PCKDBL(0x91), BAD_CODE, PCKDBL(0x90), INS_TT_NONE, REX_W1 | Encoding_VEX | KInstruction) INST3(kmovq_gpr, "kmovq", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x92), INS_TT_NONE, REX_W1 | Encoding_VEX | KInstruction) INST3(kmovq_msk, "kmovq", IUM_WR, PCKFLT(0x91), BAD_CODE, PCKFLT(0x90), INS_TT_NONE, REX_W1 | Encoding_VEX | KInstruction) -INST3(kortestd, "kortestd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x98), INS_TT_NONE, REX_W1 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) -INST3(kortestq, "kortestq", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x98), INS_TT_NONE, REX_W1 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) -INST3(vmovdqu8, "movdqu8", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_8Bit | REX_W0_EVEX | Encoding_EVEX) -INST3(vmovdqu16, "movdqu16", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_16Bit | REX_W1_EVEX | Encoding_EVEX) -INST3(vpcmpb, "pcmpb", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), INS_TT_FULL_MEM, Input_8Bit | REX_W0_EVEX | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) -INST3(vpcmpw, "pcmpw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), INS_TT_FULL, Input_16Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) -INST3(vpcmpub, "pcmpub", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), INS_TT_FULL_MEM, Input_8Bit | REX_W0_EVEX | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) -INST3(vpcmpuw, "pcmpuw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), INS_TT_FULL, Input_16Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) -INST3(vpmovb2m, "pmovb2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x29), INS_TT_NONE, Input_8Bit | REX_W0_EVEX | Encoding_EVEX) -INST3(vpmovm2b, "pmovm2b", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x28), INS_TT_NONE, Input_8Bit | REX_W0_EVEX | Encoding_EVEX) -INST3(vpmovm2w, "pmovm2w", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x28), INS_TT_NONE, Input_16Bit | REX_W1_EVEX | Encoding_EVEX) -INST3(vpmovw2m, "pmovw2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x29), INS_TT_NONE, Input_16Bit | REX_W1_EVEX | Encoding_EVEX) -INST3(vpmovwb, "pmovwb", IUM_WR, PSSE38(0xF3, 0x30), BAD_CODE, PSSE38(0xF3, 0x30), INS_TT_HALF_MEM, Input_16Bit | REX_W0_EVEX | Encoding_EVEX) +INST3(kortestd, "kortestd", IUM_RD, BAD_CODE, BAD_CODE, PCKDBL(0x98), INS_TT_NONE, REX_W1 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) +INST3(kortestq, "kortestq", IUM_RD, BAD_CODE, BAD_CODE, PCKFLT(0x98), INS_TT_NONE, REX_W1 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) +INST3(vmovdqu8, "movdqu8", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_8Bit | REX_W0 | Encoding_EVEX) +INST3(vmovdqu16, "movdqu16", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX) +INST3(vpbroadcastb_gpr, "pbroadcastb", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7A), INS_TT_TUPLE1_SCALAR, Input_8Bit | REX_W0 | Encoding_EVEX) // Broadcast int8 value from gpr to entire register +INST3(vpbroadcastw_gpr, "pbroadcastw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7B), INS_TT_TUPLE1_SCALAR, Input_16Bit | REX_W0 | Encoding_EVEX) // Broadcast int16 value from gpr to entire register +INST3(vpcmpb, "pcmpb", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), INS_TT_FULL_MEM, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) +INST3(vpcmpeqb, "pcmpeqb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x74), INS_TT_FULL_MEM, Input_8Bit | REX_WIG | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 8-bit integers for equality +INST3(vpcmpeqw, "pcmpeqw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x75), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 16-bit integers for equality +INST3(vpcmpgtb, "pcmpgtb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x64), INS_TT_FULL_MEM, Input_8Bit | REX_WIG | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 8-bit signed integers for greater than +INST3(vpcmpgtw, "pcmpgtw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x65), INS_TT_FULL_MEM, Input_16Bit | REX_WIG | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) // Packed compare 16-bit signed integers for greater than +INST3(vpcmpw, "pcmpw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) +INST3(vpcmpub, "pcmpub", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), INS_TT_FULL_MEM, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) +INST3(vpcmpuw, "pcmpuw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsMskSrcSrcEvexInstruction) +INST3(vpermw, "permw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x8D), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Permute Packed Doublewords Elements +INST3(vpmovb2m, "pmovb2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x29), INS_TT_NONE, Input_8Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovm2b, "pmovm2b", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x28), INS_TT_NONE, Input_8Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovm2w, "pmovm2w", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x28), INS_TT_NONE, Input_16Bit | REX_W1 | Encoding_EVEX) +INST3(vpmovw2m, "pmovw2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x29), INS_TT_NONE, Input_16Bit | REX_W1 | Encoding_EVEX) +INST3(vpmovwb, "pmovwb", IUM_WR, PSSE38(0xF3, 0x30), BAD_CODE, PSSE38(0xF3, 0x30), INS_TT_HALF_MEM, Input_16Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovswb, "pmovswb", IUM_WR, PSSE38(0xF3, 0x20), BAD_CODE, PSSE38(0xF3, 0x20), INS_TT_HALF_MEM, Input_16Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovuswb, "pmovuswb", IUM_WR, PSSE38(0xF3, 0x10), BAD_CODE, PSSE38(0xF3, 0x10), INS_TT_HALF_MEM, Input_16Bit | REX_W0 | Encoding_EVEX) +INST3(vpsllvw, "psllvw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x12), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Left Logical +INST3(vpsravw, "psravw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x11), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Right Arithmetic +INST3(vpsrlvw, "psrlvw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x10), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Right Logical // AVX512DQ -INST3(kortestb, "kortestb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x98), INS_TT_NONE, REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) +INST3(kortestb, "kortestb", IUM_RD, BAD_CODE, BAD_CODE, PCKDBL(0x98), INS_TT_NONE, REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) INST3(kmovb_gpr, "kmovb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x92), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) INST3(kmovb_msk, "kmovb", IUM_WR, PCKDBL(0x91), BAD_CODE, PCKDBL(0x90), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) -INST3(vextractf32x8, "extractf32x8", IUM_WR, SSE3A(0x1B), BAD_CODE, BAD_CODE, INS_TT_TUPLE8, Input_32Bit | REX_W0_EVEX | Encoding_EVEX) // Extract 256-bit packed double-precision floating point values -INST3(vextracti32x8, "extracti32x8", IUM_WR, SSE3A(0x3B), BAD_CODE, BAD_CODE, INS_TT_TUPLE8, Input_32Bit | REX_W0_EVEX | Encoding_EVEX) // Extract 256-bit packed quadword integer values -INST3(vinsertf32x8, "insertf32x8", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1A), INS_TT_TUPLE8, Input_32Bit | REX_W0_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed double-precision floating point values -INST3(vinserti32x8, "inserti32x8", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3A), INS_TT_TUPLE8, Input_32Bit | REX_W0_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed quadword integer values -INST3(vpcmpd, "pcmpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpcmpq, "pcmpq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpcmpud, "pcmpud", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), INS_TT_FULL, Input_32Bit | REX_W0_EVEX | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpcmpuq, "pcmpuq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpmovd2m, "pmovd2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x39), INS_TT_NONE, Input_32Bit | REX_W0_EVEX | Encoding_EVEX) -INST3(vpmovm2d, "pmovm2d", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x38), INS_TT_NONE, Input_32Bit | REX_W0_EVEX | Encoding_EVEX) -INST3(vpmovm2q, "pmovm2q", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x38), INS_TT_NONE, Input_64Bit | REX_W1_EVEX | Encoding_EVEX) -INST3(vpmovq2m, "pmovq2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x39), INS_TT_NONE, Input_64Bit | REX_W1_EVEX | Encoding_EVEX) -INST3(vpmullq, "pmullq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x40), INS_TT_FULL, Input_64Bit | REX_W1_EVEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed multiply 64 bit unsigned integers and store lower 64 bits of each result - +INST3(vbroadcastf32x2, "broadcastf32x2", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x19), INS_TT_TUPLE2, Input_32Bit | REX_W0 | Encoding_EVEX) // Broadcast packed float values read from memory to entire register +INST3(vbroadcasti32x2, "broadcasti32x2", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x59), INS_TT_TUPLE2, Input_32Bit | REX_W0 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register +INST3(vbroadcastf32x8, "broadcastf32x8", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1B), INS_TT_TUPLE8, Input_32Bit | REX_W0 | Encoding_EVEX) // Broadcast packed float values read from memory to entire register +INST3(vbroadcasti32x8, "broadcasti32x8", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5B), INS_TT_TUPLE8, Input_32Bit | REX_W0 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register +INST3(vcvtpd2qq, "cvtpd2qq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x7B), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt packed doubles to signed QWORDs +INST3(vcvtpd2uqq, "cvtpd2uqq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x79), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt packed doubles to unsigned QWORDs +INST3(vcvtps2qq, "cvtps2qq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x7B), INS_TT_HALF, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt packed singles to signed QWORDs +INST3(vcvtps2uqq, "cvtps2uqq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x79), INS_TT_HALF, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt packed singles to unsigned QWORDs +INST3(vcvtqq2pd, "cvtqq2pd", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xE6), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt packed signed QWORDs to doubles +INST3(vcvtqq2ps, "cvtqq2ps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x5B), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt packed signed QWORDs to singles +INST3(vcvttpd2qq, "cvttpd2qq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x7A), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt w/ truncation packed doubles to signed QWORDs +INST3(vcvttpd2uqq, "cvttpd2uqq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x78), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt w/ truncation packed doubles to unsigned QWORDs +INST3(vcvttps2qq, "cvttps2qq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x7A), INS_TT_HALF, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt w/ truncation packed singles to signed QWORDs +INST3(vcvttps2uqq, "cvttps2uqq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x78), INS_TT_HALF, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt w/ truncation packed singles to unsigned QWORDs +INST3(vcvtuqq2pd, "cvtuqq2pd", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x7A), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt packed signed QWORDs to doubles +INST3(vcvtuqq2ps, "cvtuqq2ps", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0x7A), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt packed signed QWORDs to singles +INST3(vextractf32x8, "extractf32x8", IUM_WR, SSE3A(0x1B), BAD_CODE, BAD_CODE, INS_TT_TUPLE8, Input_32Bit | REX_W0 | Encoding_EVEX) // Extract 256-bit packed double-precision floating point values +INST3(vextractf64x2, "extractf64x2", IUM_WR, SSE3A(0x19), BAD_CODE, BAD_CODE, INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Extract 256-bit packed double-precision floating point values +INST3(vextracti32x8, "extracti32x8", IUM_WR, SSE3A(0x3B), BAD_CODE, BAD_CODE, INS_TT_TUPLE8, Input_32Bit | REX_W0 | Encoding_EVEX) // Extract 256-bit packed quadword integer values +INST3(vextracti64x2, "extracti64x2", IUM_WR, SSE3A(0x39), BAD_CODE, BAD_CODE, INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Extract 256-bit packed quadword integer values +INST3(vinsertf32x8, "insertf32x8", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1A), INS_TT_TUPLE8, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed double-precision floating point values +INST3(vinsertf64x2, "insertf64x2", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x18), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed double-precision floating point values +INST3(vinserti32x8, "inserti32x8", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3A), INS_TT_TUPLE8, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed quadword integer values +INST3(vinserti64x2, "inserti64x2", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x38), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 256-bit packed quadword integer values +INST3(vpcmpd, "pcmpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) +INST3(vpcmpq, "pcmpq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) +INST3(vpcmpud, "pcmpud", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) +INST3(vpcmpuq, "pcmpuq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) +INST3(vpmovd2m, "pmovd2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x39), INS_TT_NONE, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovm2d, "pmovm2d", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x38), INS_TT_NONE, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vpmovm2q, "pmovm2q", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x38), INS_TT_NONE, Input_64Bit | REX_W1 | Encoding_EVEX) +INST3(vpmovq2m, "pmovq2m", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0x39), INS_TT_NONE, Input_64Bit | REX_W1 | Encoding_EVEX) +INST3(vpmullq, "pmullq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x40), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed multiply 64 bit unsigned integers and store lower 64 bits of each result + +// AVX512VBMI +INST3(vpermb, "permb", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x8D), INS_TT_FULL_MEM, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Permute Packed Byte Elements INST3(LAST_AVX512_INSTRUCTION, "LAST_AVX512_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) // Scalar instructions in SSE4.2 -INST3(crc32, "crc32", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF2, 0xF0), INS_TT_NONE, INS_FLAGS_None) +INST3(crc32, "crc32", IUM_RW, BAD_CODE, BAD_CODE, PSSE38(0xF2, 0xF0), INS_TT_NONE, INS_FLAGS_None) // BMI1 INST3(tzcnt, "tzcnt", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xBC), INS_TT_NONE, Undefined_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF) // Count the Number of Trailing Zero Bits diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 49b382a96885ad..578edeb50ccb51 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -170,6 +170,7 @@ CONFIG_INTEGER(JitStressModeNamesOnly, W("JitStressModeNamesOnly"), 0) // Intern CONFIG_INTEGER(JitStressProcedureSplitting, W("JitStressProcedureSplitting"), 0) // Always split after the first basic // block. Skips functions with EH // for simplicity. +CONFIG_INTEGER(JitStressMorphStores, W("JitStressMorphStores"), 0) // Morph trees after assignment rationalization CONFIG_INTEGER(JitStressRegs, W("JitStressRegs"), 0) CONFIG_STRING(JitStressRegsRange, W("JitStressRegsRange")) // Only apply JitStressRegs to methods in this hash range @@ -314,41 +315,43 @@ CONFIG_INTEGER(JitStressEvexEncoding, W("JitStressEvexEncoding"), 0) // Enable E CONFIG_INTEGER(EnableHWIntrinsic, W("EnableHWIntrinsic"), 1) // Allows Base+ hardware intrinsics to be disabled #if defined(TARGET_AMD64) || defined(TARGET_X86) -CONFIG_INTEGER(EnableAES, W("EnableAES"), 1) // Allows AES+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Allows AVX+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX2, W("EnableAVX2"), 1) // Allows AVX2+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512BW, W("EnableAVX512BW"), 1) // Allows AVX512BW+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512BW_VL, W("EnableAVX512BW_VL"), 1) // Allows AVX512BW+ AVX512VL+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512CD, W("EnableAVX512CD"), 1) // Allows AVX512CD+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512CD_VL, W("EnableAVX512CD_VL"), 1) // Allows AVX512CD+ AVX512VL+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512DQ, W("EnableAVX512DQ"), 1) // Allows AVX512DQ+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512DQ_VL, W("EnableAVX512DQ_VL"), 1) // Allows AVX512DQ+ AVX512VL+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512F, W("EnableAVX512F"), 1) // Allows AVX512F+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVX512F_VL, W("EnableAVX512F_VL"), 1) // Allows AVX512BW+ AVX512VL+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableAVXVNNI, W("EnableAVXVNNI"), 1) // Allows AVX VNNI+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableBMI1, W("EnableBMI1"), 1) // Allows BMI1+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableBMI2, W("EnableBMI2"), 1) // Allows BMI2+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableFMA, W("EnableFMA"), 1) // Allows FMA+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableLZCNT, W("EnableLZCNT"), 1) // Allows LZCNT+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1) // Allows PCLMULQDQ+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnablePOPCNT, W("EnablePOPCNT"), 1) // Allows POPCNT+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableSSE, W("EnableSSE"), 1) // Allows SSE+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableSSE2, W("EnableSSE2"), 1) // Allows SSE2+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableSSE3, W("EnableSSE3"), 1) // Allows SSE3+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableSSE3_4, W("EnableSSE3_4"), 1) // Allows SSE3+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableSSE41, W("EnableSSE41"), 1) // Allows SSE4.1+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableSSE42, W("EnableSSE42"), 1) // Allows SSE4.2+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableSSSE3, W("EnableSSSE3"), 1) // Allows SSSE3+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAES, W("EnableAES"), 1) // Allows AES+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Allows AVX+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX2, W("EnableAVX2"), 1) // Allows AVX2+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512BW, W("EnableAVX512BW"), 1) // Allows AVX512BW+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512BW_VL, W("EnableAVX512BW_VL"), 1) // Allows AVX512BW+ AVX512VL+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512CD, W("EnableAVX512CD"), 1) // Allows AVX512CD+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512CD_VL, W("EnableAVX512CD_VL"), 1) // Allows AVX512CD+ AVX512VL+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512DQ, W("EnableAVX512DQ"), 1) // Allows AVX512DQ+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512DQ_VL, W("EnableAVX512DQ_VL"), 1) // Allows AVX512DQ+ AVX512VL+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512F, W("EnableAVX512F"), 1) // Allows AVX512F+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512F_VL, W("EnableAVX512F_VL"), 1) // Allows AVX512BW+ AVX512VL+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512VBMI, W("EnableAVX512VBMI"), 1) // Allows AVX512VBMI+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVX512VBMI_VL, W("EnableAVX512VBMI_VL"), 1) // Allows AVX512VBMI_VL+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableAVXVNNI, W("EnableAVXVNNI"), 1) // Allows AVXVNNI+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableBMI1, W("EnableBMI1"), 1) // Allows BMI1+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableBMI2, W("EnableBMI2"), 1) // Allows BMI2+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableFMA, W("EnableFMA"), 1) // Allows FMA+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableLZCNT, W("EnableLZCNT"), 1) // Allows LZCNT+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1) // Allows PCLMULQDQ+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnablePOPCNT, W("EnablePOPCNT"), 1) // Allows POPCNT+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableSSE, W("EnableSSE"), 1) // Allows SSE+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableSSE2, W("EnableSSE2"), 1) // Allows SSE2+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableSSE3, W("EnableSSE3"), 1) // Allows SSE3+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableSSE3_4, W("EnableSSE3_4"), 1) // Allows SSE3+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableSSE41, W("EnableSSE41"), 1) // Allows SSE4.1+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableSSE42, W("EnableSSE42"), 1) // Allows SSE4.2+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableSSSE3, W("EnableSSSE3"), 1) // Allows SSSE3+ hardware intrinsics to be disabled #elif defined(TARGET_ARM64) -CONFIG_INTEGER(EnableArm64AdvSimd, W("EnableArm64AdvSimd"), 1) // Allows Arm64 AdvSimd+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Aes, W("EnableArm64Aes"), 1) // Allows Arm64 Aes+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Atomics, W("EnableArm64Atomics"), 1) // Allows Arm64 Atomics+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Crc32, W("EnableArm64Crc32"), 1) // Allows Arm64 Crc32+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Dczva, W("EnableArm64Dczva"), 1) // Allows Arm64 Dczva+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Dp, W("EnableArm64Dp"), 1) // Allows Arm64 Dp+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Rdm, W("EnableArm64Rdm"), 1) // Allows Arm64 Rdm+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Sha1, W("EnableArm64Sha1"), 1) // Allows Arm64 Sha1+ hardware intrinsics to be disabled -CONFIG_INTEGER(EnableArm64Sha256, W("EnableArm64Sha256"), 1) // Allows Arm64 Sha256+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64AdvSimd, W("EnableArm64AdvSimd"), 1) // Allows Arm64 AdvSimd+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Aes, W("EnableArm64Aes"), 1) // Allows Arm64 Aes+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Atomics, W("EnableArm64Atomics"), 1) // Allows Arm64 Atomics+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Crc32, W("EnableArm64Crc32"), 1) // Allows Arm64 Crc32+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Dczva, W("EnableArm64Dczva"), 1) // Allows Arm64 Dczva+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Dp, W("EnableArm64Dp"), 1) // Allows Arm64 Dp+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Rdm, W("EnableArm64Rdm"), 1) // Allows Arm64 Rdm+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Sha1, W("EnableArm64Sha1"), 1) // Allows Arm64 Sha1+ hardware intrinsics to be disabled +CONFIG_INTEGER(EnableArm64Sha256, W("EnableArm64Sha256"), 1) // Allows Arm64 Sha256+ hardware intrinsics to be disabled #endif // clang-format on diff --git a/src/coreclr/jit/jitee.h b/src/coreclr/jit/jitee.h index 7d3b4f6a624b40..b55719f56e8250 100644 --- a/src/coreclr/jit/jitee.h +++ b/src/coreclr/jit/jitee.h @@ -40,7 +40,7 @@ class JitFlags JIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement JIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT - JIT_FLAG_UNUSED8 = 15, + JIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators JIT_FLAG_UNUSED9 = 16, #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) @@ -187,6 +187,7 @@ class JitFlags #endif FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT, JIT_FLAG_ALT_JIT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED, JIT_FLAG_FROZEN_ALLOC_ALLOWED); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE, JIT_FLAG_MAKEFINALCODE); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN, JIT_FLAG_READYTORUN); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE, JIT_FLAG_PROF_ENTERLEAVE); diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp index 272895768079ae..1284185219dd02 100644 --- a/src/coreclr/jit/lclmorph.cpp +++ b/src/coreclr/jit/lclmorph.cpp @@ -65,7 +65,7 @@ class LocalSequencer final : public GenTreeVisitor else { assert(lastNode->gtNext == nullptr); - assert(lastNode->OperIsLocal() || lastNode->OperIs(GT_LCL_ADDR)); + assert(lastNode->OperIsAnyLocal()); } firstNode->gtPrev = nullptr; @@ -78,7 +78,7 @@ class LocalSequencer final : public GenTreeVisitor fgWalkResult PostOrderVisit(GenTree** use, GenTree* user) { GenTree* node = *use; - if (node->OperIsLocal() || node->OperIs(GT_LCL_ADDR)) + if (node->OperIsAnyLocal()) { SequenceLocal(node->AsLclVarCommon()); } @@ -217,7 +217,7 @@ class LocalAddressVisitor final : public GenTreeVisitor { // During tree traversal every GenTree node produces a "value" that represents: // - the memory location associated with a local variable, including an offset - // accumulated from GT_LCL_FLD and GT_FIELD nodes. + // accumulated from GT_LCL_FLD and GT_FIELD_ADDR nodes. // - the address of local variable memory location, including an offset as well. // - an unknown value - the result of a node we don't know how to process. This // also includes the result of TYP_VOID nodes (or any other nodes that don't @@ -462,7 +462,6 @@ class LocalAddressVisitor final : public GenTreeVisitor { DoPreOrder = true, DoPostOrder = true, - ComputeStack = true, DoLclVarsOnly = false, UseExecutionOrder = true, }; @@ -555,41 +554,60 @@ class LocalAddressVisitor final : public GenTreeVisitor { GenTree* const node = *use; - if (node->OperIs(GT_IND, GT_FIELD, GT_FIELD_ADDR)) - { - MorphStructField(node, user); - } - else if (node->OperIs(GT_LCL_FLD)) + switch (node->OperGet()) { - MorphLocalField(node, user); - } + case GT_IND: + case GT_BLK: + if (MorphStructField(node->AsIndir(), user)) + { + goto LOCAL_NODE; + } + break; - if (node->OperIsLocal() || node->OperIs(GT_LCL_ADDR)) - { - unsigned const lclNum = node->AsLclVarCommon()->GetLclNum(); - LclVarDsc* const varDsc = m_compiler->lvaGetDesc(lclNum); + case GT_FIELD_ADDR: + if (MorphStructFieldAddress(node, 0) != BAD_VAR_NUM) + { + goto LOCAL_NODE; + } + break; - UpdateEarlyRefCount(lclNum); + case GT_LCL_FLD: + MorphLocalField(node, user); + goto LOCAL_NODE; - if (varDsc->lvIsStructField) + case GT_LCL_VAR: + case GT_LCL_ADDR: + LOCAL_NODE: { - // Promoted field, increase count for the parent lclVar. - // - assert(!m_compiler->lvaIsImplicitByRefLocal(lclNum)); - unsigned parentLclNum = varDsc->lvParentLcl; - UpdateEarlyRefCount(parentLclNum); - } + unsigned const lclNum = node->AsLclVarCommon()->GetLclNum(); + LclVarDsc* const varDsc = m_compiler->lvaGetDesc(lclNum); - if (varDsc->lvPromoted) - { - // Promoted struct, increase count for each promoted field. - // - for (unsigned childLclNum = varDsc->lvFieldLclStart; - childLclNum < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++childLclNum) + UpdateEarlyRefCount(lclNum, node, user); + + if (varDsc->lvIsStructField) { - UpdateEarlyRefCount(childLclNum); + // Promoted field, increase count for the parent lclVar. + // + assert(!m_compiler->lvaIsImplicitByRefLocal(lclNum)); + unsigned parentLclNum = varDsc->lvParentLcl; + UpdateEarlyRefCount(parentLclNum, node, user); + } + + if (varDsc->lvPromoted) + { + // Promoted struct, increase count for each promoted field. + // + for (unsigned childLclNum = varDsc->lvFieldLclStart; + childLclNum < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++childLclNum) + { + UpdateEarlyRefCount(childLclNum, node, user); + } } } + break; + + default: + break; } PushValue(use); @@ -679,12 +697,12 @@ class LocalAddressVisitor final : public GenTreeVisitor } case GT_FIELD_ADDR: - if (node->AsField()->IsInstance()) + if (node->AsFieldAddr()->IsInstance()) { assert(TopValue(1).Node() == node); - assert(TopValue(0).Node() == node->AsField()->GetFldObj()); + assert(TopValue(0).Node() == node->AsFieldAddr()->GetFldObj()); - if (!TopValue(1).AddOffset(TopValue(0), node->AsField()->gtFldOffset)) + if (!TopValue(1).AddOffset(TopValue(0), node->AsFieldAddr()->gtFldOffset)) { // The field object did not represent an address, or the latter overflowed. EscapeValue(TopValue(0), node); @@ -698,32 +716,6 @@ class LocalAddressVisitor final : public GenTreeVisitor } break; - case GT_FIELD: - if (node->AsField()->IsInstance()) - { - assert(TopValue(1).Node() == node); - assert(TopValue(0).Node() == node->AsField()->GetFldObj()); - - if (node->AsField()->IsVolatile()) - { - // Volatile indirections must not be removed so the address, if any, must be escaped. - EscapeValue(TopValue(0), node); - } - else if (!TopValue(1).Indir(TopValue(0), node->AsField()->gtFldOffset)) - { - // Either the address comes from a location value (e.g. FIELD(IND(...))) or the field - // offset has overflowed. - EscapeValue(TopValue(0), node); - } - - PopValue(); - } - else - { - assert(TopValue(0).Node() == node); - } - break; - case GT_BLK: case GT_IND: assert(TopValue(1).Node() == node); @@ -965,7 +957,7 @@ class LocalAddressVisitor final : public GenTreeVisitor unsigned lclNum = val.LclNum(); LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); - unsigned indirSize = GetIndirSize(node); + unsigned indirSize = node->AsIndir()->Size(); bool isWide; if ((indirSize == 0) || ((val.Offset() + indirSize) > UINT16_MAX)) @@ -1014,35 +1006,6 @@ class LocalAddressVisitor final : public GenTreeVisitor INDEBUG(val.Consume();) } - //------------------------------------------------------------------------ - // GetIndirSize: Return the size (in bytes) of an indirection node. - // - // Arguments: - // indir - the indirection node - // user - the node that uses the indirection - // - // Notes: - // This returns 0 for indirection of unknown size, i. e. IND - // nodes that are used as sources of STORE_DYN_BLKs. - // - unsigned GetIndirSize(GenTree* indir) - { - assert(indir->OperIs(GT_IND, GT_BLK, GT_FIELD)); - - if (indir->TypeGet() != TYP_STRUCT) - { - return genTypeSize(indir); - } - - if (indir->OperIs(GT_IND)) - { - // TODO-1stClassStructs: remove once "IND" nodes are no more. - return 0; - } - - return indir->GetLayout(m_compiler)->GetSize(); - } - //------------------------------------------------------------------------ // MorphLocalAddress: Change a tree that represents a local variable address // to a single LCL_VAR_ADDR or LCL_FLD_ADDR node. @@ -1089,27 +1052,13 @@ class LocalAddressVisitor final : public GenTreeVisitor // void MorphWideLocalIndir(const Value& val) { - assert(val.Node()->OperIsIndir() || val.Node()->OperIs(GT_FIELD)); + assert(val.Node()->OperIsIndir()); GenTree* node = val.Node(); - GenTree* addr = node->gtGetOp1(); + GenTree* addr = node->AsIndir()->Addr(); MorphLocalAddress(addr, val.LclNum(), val.Offset()); - if (node->OperIs(GT_FIELD)) - { - if (node->TypeIs(TYP_STRUCT)) - { - ClassLayout* layout = node->GetLayout(m_compiler); - node->SetOper(GT_BLK); - node->AsBlk()->Initialize(layout); - } - else - { - node->SetOper(GT_IND); - } - } - // GLOB_REF may not be set already in the "large offset" case. Add it. node->gtFlags |= GTF_GLOB_REF; } @@ -1289,11 +1238,11 @@ class LocalAddressVisitor final : public GenTreeVisitor // IndirTransform SelectLocalIndirTransform(const Value& val, GenTree* user, ClassLayout** pStructLayout) { - GenTree* indir = val.Node(); + GenTreeIndir* indir = val.Node()->AsIndir(); // We don't expect indirections that cannot be turned into local nodes here. assert(val.Offset() <= UINT16_MAX); - assert(indir->OperIs(GT_IND, GT_BLK, GT_FIELD) && ((indir->gtFlags & GTF_IND_VOLATILE) == 0)); + assert(indir->OperIs(GT_IND, GT_BLK) && !indir->IsVolatile()); if (IsUnused(indir, user)) { @@ -1371,29 +1320,15 @@ class LocalAddressVisitor final : public GenTreeVisitor return IndirTransform::LclFld; } - ClassLayout* indirLayout = nullptr; - - if (indir->OperIs(GT_FIELD)) - { - CORINFO_CLASS_HANDLE fieldClassHandle; - var_types fieldType = m_compiler->eeGetFieldType(indir->AsField()->gtFldHnd, &fieldClassHandle); - assert(fieldType == TYP_STRUCT); - - indirLayout = m_compiler->typGetObjLayout(fieldClassHandle); - } - else - { - indirLayout = indir->AsBlk()->GetLayout(); - } - - *pStructLayout = indirLayout; + ClassLayout* layout = indir->AsBlk()->GetLayout(); + *pStructLayout = layout; if (varDsc->TypeGet() != TYP_STRUCT) { return IndirTransform::LclFld; } - if ((val.Offset() == 0) && ClassLayout::AreCompatible(indirLayout, varDsc->GetLayout())) + if ((val.Offset() == 0) && ClassLayout::AreCompatible(layout, varDsc->GetLayout())) { return IndirTransform::LclVar; } @@ -1403,107 +1338,119 @@ class LocalAddressVisitor final : public GenTreeVisitor //------------------------------------------------------------------------ // MorphStructField: Reduces indirect access to a promoted local (e.g. - // FIELD(ADDR(LCL_VAR))) to a GT_LCL_VAR that references the struct field. + // IND(FIELD_ADDR(LCL_ADDR))) to a GT_LCL_VAR that references the field. // // Arguments: - // node - the GT_IND/GT_FIELD/GT_FIELD_ADDR node - // user - the node that uses the field + // node - the GT_IND/GT_BLK node + // user - "node"'s user // - // Notes: - // This does not do anything if the access does not denote a promoted - // struct field. + // Return Value: + // Whether the indirection node was replaced with a local one. // - void MorphStructField(GenTree* node, GenTree* user) + bool MorphStructField(GenTreeIndir* node, GenTree* user) { - assert(node->OperIs(GT_IND, GT_FIELD, GT_FIELD_ADDR)); + assert(node->OperIs(GT_IND, GT_BLK)); - GenTree* objRef = node->AsUnOp()->gtOp1; + GenTree* addr = node->Addr(); + if (node->IsVolatile() && (!addr->OperIs(GT_FIELD_ADDR) || ((addr->gtFlags & GTF_FLD_DEREFERENCED) == 0))) + { + // TODO-Bug: transforming volatile indirections like this is not legal. The above condition is a quirk. + return false; + } - // TODO-Bug: this code does not pay attention to "GTF_IND_VOLATILE". - if ((objRef != nullptr) && objRef->IsLclVarAddr()) + unsigned fieldLclNum = MorphStructFieldAddress(addr, node->Size()); + if (fieldLclNum == BAD_VAR_NUM) { - const LclVarDsc* varDsc = m_compiler->lvaGetDesc(objRef->AsLclVarCommon()); + return false; + } - if (varDsc->lvPromoted) + LclVarDsc* fieldVarDsc = m_compiler->lvaGetDesc(fieldLclNum); + var_types fieldType = fieldVarDsc->TypeGet(); + assert(fieldType != TYP_STRUCT); // Promoted LCL_VAR can't have a struct type. + + if (node->TypeGet() == fieldType) + { + GenTreeFlags lclVarFlags = node->gtFlags & (GTF_NODE_MASK | GTF_DONT_CSE); + + if ((user != nullptr) && user->OperIs(GT_ASG) && (user->AsOp()->gtOp1 == node)) { - unsigned fieldOffset = node->OperIs(GT_IND) ? 0 : node->AsField()->gtFldOffset; - unsigned fieldLclNum = m_compiler->lvaGetFieldLocal(varDsc, fieldOffset); + lclVarFlags |= GTF_VAR_DEF; + } + + node->ChangeOper(GT_LCL_VAR); + node->AsLclVar()->SetLclNum(fieldLclNum); + node->gtType = fieldType; + node->gtFlags = lclVarFlags; + return true; + } + + return false; + } + //------------------------------------------------------------------------ + // MorphStructFieldAddress: Replace FIELD_ADDR(LCL_ADDR) with LCL_ADDR + // that references a promoted field. + // + // Arguments: + // node - the address node + // accessSize - load/store size if known, zero otherwise + // + // Return Value: + // Local number for the promoted field if the replacement was successful, + // BAD_VAR_NUM otherwise. + // + unsigned MorphStructFieldAddress(GenTree* node, unsigned accessSize) + { + unsigned offset = 0; + bool isSpanLength = false; + GenTree* addr = node; + if (addr->OperIs(GT_FIELD_ADDR) && addr->AsFieldAddr()->IsInstance()) + { + offset = addr->AsFieldAddr()->gtFldOffset; + isSpanLength = addr->AsFieldAddr()->IsSpanLength(); + addr = addr->AsFieldAddr()->GetFldObj(); + } + + if (addr->IsLclVarAddr()) + { + const LclVarDsc* varDsc = m_compiler->lvaGetDesc(addr->AsLclVarCommon()); + + if (varDsc->lvPromoted) + { + unsigned fieldLclNum = m_compiler->lvaGetFieldLocal(varDsc, offset); if (fieldLclNum == BAD_VAR_NUM) { // Access a promoted struct's field with an offset that doesn't correspond to any field. // It can happen if the struct was cast to another struct with different offsets. - return; + return BAD_VAR_NUM; } - const LclVarDsc* fieldDsc = m_compiler->lvaGetDesc(fieldLclNum); - var_types fieldType = fieldDsc->TypeGet(); - assert(fieldType != TYP_STRUCT); // Promoted LCL_VAR can't have a struct type. + LclVarDsc* fieldVarDsc = m_compiler->lvaGetDesc(fieldLclNum); - if (node->OperIs(GT_FIELD_ADDR)) + // Retargeting the indirection to reference the promoted field would make it "wide", exposing + // the whole parent struct (with all of its fields). + if (accessSize > genTypeSize(fieldVarDsc)) { - node->ChangeOper(GT_LCL_ADDR); - node->AsLclFld()->SetLclNum(fieldLclNum); - node->AsLclFld()->SetLclOffs(0); + return BAD_VAR_NUM; } - else if (node->TypeGet() == fieldType) - { - GenTreeFlags lclVarFlags = node->gtFlags & (GTF_NODE_MASK | GTF_DONT_CSE); - - if (node->OperIs(GT_FIELD) && node->AsField()->IsSpanLength()) - { - m_compiler->lvaGetDesc(fieldLclNum)->SetIsNeverNegative(true); - } - - if ((user != nullptr) && user->OperIs(GT_ASG) && (user->AsOp()->gtOp1 == node)) - { - lclVarFlags |= GTF_VAR_DEF; - } - node->ChangeOper(GT_LCL_VAR); - node->AsLclVar()->SetLclNum(fieldLclNum); - node->gtType = fieldType; - node->gtFlags = lclVarFlags; - } - else // Here we will turn "FIELD/IND(LCL_ADDR_VAR)" into "OBJ/IND(LCL_ADDR_VAR)". + if (isSpanLength && (accessSize == genTypeSize(TYP_INT))) { - // This type mismatch is somewhat common due to how we retype fields of struct type that - // recursively simplify down to a primitive. E. g. for "struct { struct { int a } A, B }", - // the promoted local would look like "{ int a, B }", while the IR would contain "FIELD" - // nodes for the outer struct "A". - // - // TODO-1stClassStructs: delete this once "IND" nodes are no more. - if (node->OperIs(GT_IND) && node->TypeIs(TYP_STRUCT)) - { - return; - } - - ClassLayout* layout = node->TypeIs(TYP_STRUCT) ? node->GetLayout(m_compiler) : nullptr; - unsigned indSize = node->TypeIs(TYP_STRUCT) ? layout->GetSize() : genTypeSize(node); - if (indSize > genTypeSize(fieldType)) - { - // Retargeting this indirection to reference the promoted field would make it - // "wide", address-exposing the whole parent struct (with all of its fields). - return; - } - - if (node->TypeIs(TYP_STRUCT)) - { - node->SetOper(GT_BLK); - node->AsBlk()->Initialize(layout); - } - else - { - node->SetOper(GT_IND); - } - - objRef->AsLclFld()->SetLclNum(fieldLclNum); + fieldVarDsc->SetIsNeverNegative(true); } JITDUMP("Replacing the field in promoted struct with local var V%02u\n", fieldLclNum); m_stmtModified = true; + + node->ChangeOper(GT_LCL_ADDR); + node->AsLclFld()->SetLclNum(fieldLclNum); + node->AsLclFld()->SetLclOffs(0); + + return fieldLclNum; } } + + return BAD_VAR_NUM; } //------------------------------------------------------------------------ @@ -1535,23 +1482,20 @@ class LocalAddressVisitor final : public GenTreeVisitor // // Arguments: // lclNum - the local number to update the count for. + // node - local node representing the reference + // user - "node"'s user // // Notes: - // fgMakeOutgoingStructArgCopy checks the ref counts for implicit byref params when it decides - // if it's legal to elide certain copies of them; // fgRetypeImplicitByRefArgs checks the ref counts when it decides to undo promotions. - // fgForwardSub uses ref counts to decide when to forward sub. + // fgForwardSub may use ref counts to decide when to forward sub. // - void UpdateEarlyRefCount(unsigned lclNum) + void UpdateEarlyRefCount(unsigned lclNum, GenTree* node, GenTree* user) { LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); // Note we don't need accurate counts when the values are large. // - if (varDsc->lvRefCnt(RCS_EARLY) < USHRT_MAX) - { - varDsc->incLvRefCnt(1, RCS_EARLY); - } + varDsc->incLvRefCntSaturating(1, RCS_EARLY); if (!m_compiler->lvaIsImplicitByRefLocal(lclNum)) { @@ -1566,43 +1510,7 @@ class LocalAddressVisitor final : public GenTreeVisitor // But the pattern should at least subset the implicit byref cases that are // handled in fgCanFastTailCall and fgMakeOutgoingStructArgCopy. // - // CALL(OBJ(LCL_VAR_ADDR...)) - // -or- - // CALL(LCL_VAR) - - // TODO-1stClassStructs: We've removed most, but not all, cases where OBJ(LCL_VAR_ADDR) - // is introduced (it was primarily from impNormStructVal). But until all cases are gone - // we still want to handle it as well. - - if (m_ancestors.Height() < 2) - { - return; - } - - GenTree* node = m_ancestors.Top(0); - - if (node->OperIs(GT_LCL_VAR)) - { - node = m_ancestors.Top(1); - } - else if (node->IsLclVarAddr()) - { - if (m_ancestors.Height() < 3) - { - return; - } - - node = m_ancestors.Top(1); - - if (!node->OperIs(GT_BLK)) - { - return; - } - - node = m_ancestors.Top(2); - } - - if (node->IsCall()) + if ((node != nullptr) && node->OperIs(GT_LCL_VAR) && (user != nullptr) && user->IsCall()) { JITDUMP("LocalAddressVisitor incrementing weighted ref count from " FMT_WT " to " FMT_WT " for implicit by-ref V%02d arg passed to call\n", @@ -1714,7 +1622,7 @@ PhaseStatus Compiler::fgMarkAddressExposedLocals() // GT_JMP has implicit uses of all arguments. for (unsigned lclNum = 0; lclNum < info.compArgsCount; lclNum++) { - visitor.UpdateEarlyRefCount(lclNum); + visitor.UpdateEarlyRefCount(lclNum, nullptr, nullptr); } } } @@ -1814,7 +1722,7 @@ bool Compiler::fgMorphCombineSIMDFieldAssignments(BasicBlock* block, Statement* else { GenTree* copyBlkDst = CreateAddressNodeForSimdHWIntrinsicCreate(originalLHS, TYP_FLOAT, simdSize); - dstNode = gtNewOperNode(GT_IND, simdType, copyBlkDst); + dstNode = gtNewIndir(simdType, copyBlkDst); } JITDUMP("\n" FMT_BB " " FMT_STMT " (before):\n", block->bbNum, stmt->GetID()); diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index ebaa81610df34c..0b9e98dbbb411f 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3332,59 +3332,6 @@ unsigned Compiler::lvaLclExactSize(unsigned varNum) return lvaGetDesc(varNum)->lvExactSize(); } -// getCalledCount -- get the value used to normalized weights for this method -// if we don't have profile data then getCalledCount will return BB_UNITY_WEIGHT (100) -// otherwise it returns the number of times that profile data says the method was called. -// -// static -weight_t BasicBlock::getCalledCount(Compiler* comp) -{ - // when we don't have profile data then fgCalledCount will be BB_UNITY_WEIGHT (100) - weight_t calledCount = comp->fgCalledCount; - - // If we haven't yet reach the place where we setup fgCalledCount it could still be zero - // so return a reasonable value to use until we set it. - // - if (calledCount == 0) - { - if (comp->fgIsUsingProfileWeights()) - { - // When we use profile data block counts we have exact counts, - // not multiples of BB_UNITY_WEIGHT (100) - calledCount = 1; - } - else - { - calledCount = comp->fgFirstBB->bbWeight; - - if (calledCount == 0) - { - calledCount = BB_UNITY_WEIGHT; - } - } - } - return calledCount; -} - -// getBBWeight -- get the normalized weight of this block -weight_t BasicBlock::getBBWeight(Compiler* comp) -{ - if (this->bbWeight == BB_ZERO_WEIGHT) - { - return BB_ZERO_WEIGHT; - } - else - { - weight_t calledCount = getCalledCount(comp); - - // Normalize the bbWeights by multiplying by BB_UNITY_WEIGHT and dividing by the calledCount. - // - weight_t fullResult = this->bbWeight * BB_UNITY_WEIGHT / calledCount; - - return fullResult; - } -} - // LclVarDsc "less" comparer used to compare the weight of two locals, when optimizing for small code. class LclVarDsc_SmallCode_Less { diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp index 1aa1eb4fb62b17..03c5b3c9168cfb 100644 --- a/src/coreclr/jit/liveness.cpp +++ b/src/coreclr/jit/liveness.cpp @@ -93,28 +93,23 @@ void Compiler::fgMarkUseDef(GenTreeLclVarCommon* tree) if (promotionType != PROMOTION_TYPE_NONE) { - VARSET_TP bitMask(VarSetOps::MakeEmpty(this)); - for (unsigned i = varDsc->lvFieldLclStart; i < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++i) { - noway_assert(lvaTable[i].lvIsStructField); - if (lvaTable[i].lvTracked) + if (!lvaTable[i].lvTracked) { - noway_assert(lvaTable[i].lvVarIndex < lvaTrackedCount); - VarSetOps::AddElemD(this, bitMask, lvaTable[i].lvVarIndex); + continue; } - } - // For pure defs (i.e. not an "update" def which is also a use), add to the (all) def set. - if (!isUse) - { - assert(isDef); - VarSetOps::UnionD(this, fgCurDefSet, bitMask); - } - else if (!VarSetOps::IsSubset(this, bitMask, fgCurDefSet)) - { - // Mark as used any struct fields that are not yet defined. - VarSetOps::UnionD(this, fgCurUseSet, bitMask); + unsigned varIndex = lvaTable[i].lvVarIndex; + if (isUse && !VarSetOps::IsMember(this, fgCurDefSet, varIndex)) + { + VarSetOps::AddElemD(this, fgCurUseSet, varIndex); + } + + if (isDef) + { + VarSetOps::AddElemD(this, fgCurDefSet, varIndex); + } } } } @@ -242,11 +237,6 @@ void Compiler::fgPerNodeLocalVarLiveness(GenTree* tree) } break; - // These should have been morphed away to become GT_INDs: - case GT_FIELD: - unreached(); - break; - case GT_ASG: // An indirect store defines a memory location. if (!tree->AsOp()->gtGetOp1()->OperIsLocal()) @@ -2101,6 +2091,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR case GT_STORE_BLK: case GT_STORE_DYN_BLK: case GT_JCMP: + case GT_JTEST: case GT_JCC: case GT_JTRUE: case GT_RETURN: @@ -2732,7 +2723,7 @@ void Compiler::fgInterBlockLocalVarLiveness() { for (GenTree* cur = stmt->GetTreeListEnd(); cur != nullptr;) { - assert(cur->OperIsLocal() || cur->OperIs(GT_LCL_ADDR)); + assert(cur->OperIsAnyLocal()); bool isDef = ((cur->gtFlags & GTF_VAR_DEF) != 0) && ((cur->gtFlags & GTF_VAR_USEASG) == 0); bool conditional = cur != dst; // Ignore conditional defs that would otherwise @@ -2758,7 +2749,7 @@ void Compiler::fgInterBlockLocalVarLiveness() { for (GenTree* cur = stmt->GetTreeListEnd(); cur != nullptr;) { - assert(cur->OperIsLocal() || cur->OperIs(GT_LCL_ADDR)); + assert(cur->OperIsAnyLocal()); if (!fgComputeLifeLocal(life, keepAliveVars, cur)) { cur = cur->gtPrev; diff --git a/src/coreclr/jit/loopcloning.cpp b/src/coreclr/jit/loopcloning.cpp index 0f28c613470919..ced457b5a02028 100644 --- a/src/coreclr/jit/loopcloning.cpp +++ b/src/coreclr/jit/loopcloning.cpp @@ -146,8 +146,7 @@ GenTree* LC_Ident::ToGenTree(Compiler* comp, BasicBlock* bb) comp->gtNewIconNode(static_cast(indirOffs), TYP_I_IMPL)); } - GenTree* const indir = comp->gtNewIndir(TYP_I_IMPL, addr); - indir->gtFlags |= GTF_IND_INVARIANT; + GenTree* const indir = comp->gtNewIndir(TYP_I_IMPL, addr, GTF_IND_INVARIANT); return indir; } case MethodAddr: @@ -160,9 +159,7 @@ GenTree* LC_Ident::ToGenTree(Compiler* comp, BasicBlock* bb) { GenTreeIntCon* slot = comp->gtNewIconHandleNode((size_t)methAddr, GTF_ICON_FTN_ADDR); INDEBUG(slot->gtTargetHandle = (size_t)targetMethHnd); - GenTree* indir = comp->gtNewIndir(TYP_I_IMPL, slot); - indir->gtFlags |= GTF_IND_NONFAULTING | GTF_IND_INVARIANT; - indir->gtFlags &= ~GTF_EXCEPT; + GenTree* indir = comp->gtNewIndir(TYP_I_IMPL, slot, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); return indir; } default: diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 2d0a2fcef1d821..de2cd661d7f250 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -823,7 +823,7 @@ GenTree* Lowering::LowerSwitch(GenTree* node) unsigned lclNum = comp->lvaGrabTemp(true DEBUGARG("Lowering is creating a new local variable")); comp->lvaTable[lclNum].lvType = rhs->TypeGet(); - GenTreeLclVar* store = comp->gtNewStoreLclVar(lclNum, rhs); + GenTreeLclVar* store = comp->gtNewStoreLclVarNode(lclNum, rhs); switchBBRange.InsertAfter(node, store); switchBBRange.Remove(node); @@ -1053,7 +1053,7 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // |____ (switchIndex) (The temp variable) // |____ (ICon) (The actual case constant) GenTree* gtCaseCond = comp->gtNewOperNode(GT_EQ, TYP_INT, comp->gtNewLclvNode(tempLclNum, tempLclType), - comp->gtNewIconNode(i, tempLclType)); + comp->gtNewIconNode(i, genActualType(tempLclType))); GenTree* gtCaseBranch = comp->gtNewOperNode(GT_JTRUE, TYP_VOID, gtCaseCond); LIR::Range caseRange = LIR::SeqTree(comp, gtCaseBranch); currentBBRange->InsertAtEnd(std::move(caseRange)); @@ -1825,7 +1825,6 @@ GenTree* Lowering::LowerCallMemmove(GenTreeCall* call) // TODO-CQ: Try to create an addressing mode GenTreeIndir* srcBlk = comp->gtNewIndir(TYP_STRUCT, srcAddr); - srcBlk->gtFlags |= GTF_GLOB_REF; srcBlk->SetContained(); GenTreeBlk* storeBlk = new (comp, GT_STORE_BLK) @@ -2718,7 +2717,7 @@ void Lowering::RehomeArgForFastTailCall(unsigned int lclNum, { comp->lvaSetStruct(tmpLclNum, comp->lvaGetDesc(lclNum)->GetLayout(), false); } - GenTreeLclVar* storeLclVar = comp->gtNewStoreLclVar(tmpLclNum, value); + GenTreeLclVar* storeLclVar = comp->gtNewStoreLclVarNode(tmpLclNum, value); BlockRange().InsertBefore(insertTempBefore, LIR::SeqTree(comp, storeLclVar)); ContainCheckRange(value, storeLclVar); LowerNode(storeLclVar); @@ -3727,42 +3726,42 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue) { GenTree* relopOp1 = cond->gtGetOp1(); GenTree* relopOp2 = cond->gtGetOp2(); - bool useJCMP = false; - GenTreeFlags flags = GTF_EMPTY; + genTreeOps newOper = GT_COUNT; + GenCondition cc; if (cond->OperIs(GT_EQ, GT_NE) && relopOp2->IsIntegralConst(0)) { // Codegen will use cbz or cbnz in codegen which do not affect the flag register - flags = cond->OperIs(GT_EQ) ? GTF_JCMP_EQ : GTF_EMPTY; - useJCMP = true; + newOper = GT_JCMP; + cc = GenCondition::FromRelop(cond); } else if (cond->OperIs(GT_LT, GT_GE) && !cond->IsUnsigned() && relopOp2->IsIntegralConst(0)) { // Codegen will use tbnz or tbz in codegen which do not affect the flag register - flags = GTF_JCMP_TST | (cond->OperIs(GT_LT) ? GTF_EMPTY : GTF_JCMP_EQ); - useJCMP = true; + newOper = GT_JTEST; + cc = cond->OperIs(GT_LT) ? GenCondition(GenCondition::NE) : GenCondition(GenCondition::EQ); + // x < 0 => (x & signBit) != 0. Update the constant to be the sign bit. relopOp2->AsIntConCommon()->SetIntegralValue( (static_cast(1) << (8 * genTypeSize(genActualType(relopOp1)) - 1))); } else if (cond->OperIs(GT_TEST_EQ, GT_TEST_NE) && isPow2(relopOp2->AsIntCon()->IconValue())) { // Codegen will use tbz or tbnz in codegen which do not affect the flag register - flags = GTF_JCMP_TST | (cond->OperIs(GT_TEST_EQ) ? GTF_JCMP_EQ : GTF_EMPTY); - useJCMP = true; + newOper = GT_JTEST; + cc = GenCondition::FromRelop(cond); } - if (useJCMP) + if (newOper != GT_COUNT) { - jtrue->SetOper(GT_JCMP); - jtrue->gtFlags &= ~(GTF_JCMP_TST | GTF_JCMP_EQ); - jtrue->gtOp1 = relopOp1; - jtrue->gtOp2 = relopOp2; - jtrue->gtFlags |= flags; + jtrue->ChangeOper(newOper); + jtrue->gtOp1 = relopOp1; + jtrue->gtOp2 = relopOp2; + jtrue->AsOpCC()->gtCondition = cc; relopOp2->SetContained(); BlockRange().Remove(cond); - JITDUMP("Lowered to JCMP\n"); + JITDUMP("Lowered to %s\n", GenTree::OpName(newOper)); return nullptr; } } @@ -3775,7 +3774,7 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue) jtrue->AsCC()->gtCondition = condCode; } - JITDUMP("Result:\n"); + JITDUMP("Lowering JTRUE Result:\n"); DISPTREERANGE(BlockRange(), jtrue); JITDUMP("\n"); @@ -3876,6 +3875,10 @@ GenTree* Lowering::LowerSelect(GenTreeConditional* select) // bool Lowering::TryLowerConditionToFlagsNode(GenTree* parent, GenTree* condition, GenCondition* cond) { + JITDUMP("Lowering condition:\n"); + DISPTREERANGE(BlockRange(), condition); + JITDUMP("\n"); + if (condition->OperIsCompare()) { if (!IsInvariantInRange(condition, parent)) @@ -4748,9 +4751,7 @@ GenTreeLclVar* Lowering::SpillStructCallResult(GenTreeCall* call) const comp->lvaSetVarDoNotEnregister(spillNum DEBUGARG(DoNotEnregisterReason::LocalField)); CORINFO_CLASS_HANDLE retClsHnd = call->gtRetClsHnd; comp->lvaSetStruct(spillNum, retClsHnd, false); - GenTreeLclFld* spill = new (comp, GT_STORE_LCL_FLD) GenTreeLclFld(GT_STORE_LCL_FLD, call->gtType, spillNum, 0); - spill->gtOp1 = call; - spill->gtFlags |= GTF_VAR_DEF; + GenTreeLclFld* spill = comp->gtNewStoreLclFldNode(spillNum, call->TypeGet(), 0, call); BlockRange().InsertAfter(call, spill); ContainCheckStoreLoc(spill); @@ -4951,7 +4952,7 @@ GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call) GenTree* newThisAddr = new (comp, GT_LEA) GenTreeAddrMode(TYP_BYREF, thisExpr, nullptr, 0, comp->eeGetEEInfo()->offsetOfDelegateInstance); - GenTree* newThis = comp->gtNewOperNode(GT_IND, TYP_REF, newThisAddr); + GenTree* newThis = comp->gtNewIndir(TYP_REF, newThisAddr); BlockRange().InsertAfter(thisExpr, newThisAddr, newThis); @@ -5201,10 +5202,9 @@ void Lowering::InsertPInvokeMethodProlog() // -------------------------------------------------------- // InlinedCallFrame.m_pCallSiteSP = @RSP; - GenTreeLclFld* storeSP = new (comp, GT_STORE_LCL_FLD) - GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfCallSiteSP); - storeSP->gtOp1 = PhysReg(REG_SPBASE); - storeSP->gtFlags |= GTF_VAR_DEF; + GenTree* spValue = PhysReg(REG_SPBASE); + GenTreeLclFld* storeSP = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL, + callFrameInfo.offsetOfCallSiteSP, spValue); assert(inlinedPInvokeDsc->lvDoNotEnregister); firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeSP)); @@ -5218,14 +5218,11 @@ void Lowering::InsertPInvokeMethodProlog() // -------------------------------------------------------- // InlinedCallFrame.m_pCalleeSavedEBP = @RBP; - GenTreeLclFld* storeFP = - new (comp, GT_STORE_LCL_FLD) GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, - callFrameInfo.offsetOfCalleeSavedFP); + GenTree* fpValue = PhysReg(REG_FPBASE); + GenTreeLclFld* storeFP = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL, + callFrameInfo.offsetOfCalleeSavedFP, fpValue); assert(inlinedPInvokeDsc->lvDoNotEnregister); - storeFP->gtOp1 = PhysReg(REG_FPBASE); - storeFP->gtFlags |= GTF_VAR_DEF; - firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeFP)); DISPTREERANGE(firstBlockRange, storeFP); #endif // !defined(TARGET_ARM) @@ -5420,11 +5417,8 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call) if (src != nullptr) { // Store into InlinedCallFrame.m_Datum, the offset of which is given by offsetOfCallTarget. - GenTreeLclFld* store = - new (comp, GT_STORE_LCL_FLD) GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, - callFrameInfo.offsetOfCallTarget); - store->gtOp1 = src; - store->gtFlags |= GTF_VAR_DEF; + GenTreeLclFld* store = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL, + callFrameInfo.offsetOfCallTarget, src); InsertTreeBeforeAndContainCheck(insertBefore, store); } @@ -5434,11 +5428,9 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call) // ---------------------------------------------------------------------------------- // InlinedCallFrame.m_pCallSiteSP = SP - GenTreeLclFld* storeCallSiteSP = new (comp, GT_STORE_LCL_FLD) - GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfCallSiteSP); - - storeCallSiteSP->gtOp1 = PhysReg(REG_SPBASE); - storeCallSiteSP->gtFlags |= GTF_VAR_DEF; + GenTree* callSiteSP = PhysReg(REG_SPBASE); + GenTreeLclFld* storeCallSiteSP = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL, + callFrameInfo.offsetOfCallSiteSP, callSiteSP); InsertTreeBeforeAndContainCheck(insertBefore, storeCallSiteSP); @@ -5447,12 +5439,9 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call) // ---------------------------------------------------------------------------------- // InlinedCallFrame.m_pCallerReturnAddress = &label (the address of the instruction immediately following the call) - GenTreeLclFld* storeLab = - new (comp, GT_STORE_LCL_FLD) GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, - callFrameInfo.offsetOfReturnAddress); - - storeLab->gtOp1 = new (comp, GT_LABEL) GenTree(GT_LABEL, TYP_I_IMPL); - storeLab->gtFlags |= GTF_VAR_DEF; + GenTree* label = new (comp, GT_LABEL) GenTree(GT_LABEL, TYP_I_IMPL); + GenTreeLclFld* storeLab = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL, + callFrameInfo.offsetOfReturnAddress, label); InsertTreeBeforeAndContainCheck(insertBefore, storeLab); @@ -5551,16 +5540,11 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call) // ---------------------------------------------------------------------------------- // InlinedCallFrame.m_pCallerReturnAddress = nullptr - GenTreeLclFld* const storeCallSiteTracker = - new (comp, GT_STORE_LCL_FLD) GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, - callFrameInfo.offsetOfReturnAddress); + GenTreeIntCon* const zero = comp->gtNewIconNode(0, TYP_I_IMPL); + GenTreeLclFld* const storeCallSiteTracker = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL, + callFrameInfo.offsetOfReturnAddress, zero); - GenTreeIntCon* const constantZero = new (comp, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, 0); - - storeCallSiteTracker->gtOp1 = constantZero; - storeCallSiteTracker->gtFlags |= GTF_VAR_DEF; - - BlockRange().InsertBefore(insertionPoint, constantZero, storeCallSiteTracker); + BlockRange().InsertBefore(insertionPoint, zero, storeCallSiteTracker); ContainCheckStoreLoc(storeCallSiteTracker); #endif // USE_PER_FRAME_PINVOKE_INIT } @@ -5812,7 +5796,7 @@ GenTree* Lowering::LowerVirtualVtableCall(GenTreeCall* call) GenTree* tmpTree = comp->gtNewLclvNode(lclNumTmp, result->TypeGet()); tmpTree = Offset(tmpTree, vtabOffsOfIndirection); - tmpTree = comp->gtNewOperNode(GT_IND, TYP_I_IMPL, tmpTree); + tmpTree = Ind(tmpTree); GenTree* offs = comp->gtNewIconNode(vtabOffsOfIndirection + vtabOffsAfterIndirection, TYP_INT); result = comp->gtNewOperNode(GT_ADD, TYP_I_IMPL, comp->gtNewLclvNode(lclNumTmp, result->TypeGet()), offs); @@ -6612,14 +6596,16 @@ bool Lowering::LowerUnsignedDivOrMod(GenTreeOp* divMod) // // Arguments: // node - pointer to the DIV or MOD node +// nextNode - out parameter for the next node in the transformed node sequence that needs to be lowered // // Returns: -// nullptr if no transformation is done, or the next node in the transformed node sequence that -// needs to be lowered. +// false if no transformation is done, true if a transformation is done // -GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) +bool Lowering::TryLowerConstIntDivOrMod(GenTree* node, GenTree** nextNode) { assert((node->OperGet() == GT_DIV) || (node->OperGet() == GT_MOD)); + assert(nextNode != nullptr); + GenTree* divMod = node; GenTree* dividend = divMod->gtGetOp1(); GenTree* divisor = divMod->gtGetOp2(); @@ -6634,14 +6620,15 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) if (divMod->OperIs(GT_MOD) && divisor->IsIntegralConstPow2()) { LowerModPow2(node); - return node->gtNext; + *nextNode = node->gtNext; + return true; } assert(node->OperGet() != GT_MOD); #endif // TARGET_ARM64 if (!divisor->IsCnsIntOrI()) { - return nullptr; // no transformations to make + return false; // no transformations to make } if (dividend->IsCnsIntOrI()) @@ -6649,7 +6636,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) // We shouldn't see a divmod with constant operands here but if we do then it's likely // because optimizations are disabled or it's a case that's supposed to throw an exception. // Don't optimize this. - return nullptr; + return false; } ssize_t divisorValue = divisor->AsIntCon()->IconValue(); @@ -6665,7 +6652,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) // case so optimizing this case would break C# code. // A runtime check could be used to handle this case but it's probably too rare to matter. - return nullptr; + return false; } bool isDiv = divMod->OperGet() == GT_DIV; @@ -6677,7 +6664,8 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) // If the divisor is the minimum representable integer value then we can use a compare, // the result is 1 iff the dividend equals divisor. divMod->SetOper(GT_EQ); - return node; + *nextNode = node; + return true; } } @@ -6688,7 +6676,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) { if (comp->opts.MinOpts()) { - return nullptr; + return false; } #if defined(TARGET_XARCH) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) @@ -6790,13 +6778,14 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) divMod->AsOp()->gtOp2 = mul; } - return mulhi; + *nextNode = mulhi; + return true; #elif defined(TARGET_ARM) // Currently there's no GT_MULHI for ARM32 - return nullptr; + return false; #elif defined(TARGET_RISCV64) NYI_RISCV64("-----unimplemented on RISCV64 yet----"); - return nullptr; + return false; #else #error Unsupported or unset target architecture #endif @@ -6806,7 +6795,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) LIR::Use use; if (!BlockRange().TryGetUse(node, &use)) { - return nullptr; + return false; } // We need to use the dividend node multiple times so its value needs to be @@ -6872,7 +6861,8 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) // replace the original divmod node with the new divmod tree use.ReplaceWith(newDivMod); - return newDivMod->gtNext; + *nextNode = newDivMod->gtNext; + return true; } //------------------------------------------------------------------------ // LowerSignedDivOrMod: transform integer GT_DIV/GT_MOD nodes with a power of 2 @@ -6887,20 +6877,19 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) GenTree* Lowering::LowerSignedDivOrMod(GenTree* node) { assert((node->OperGet() == GT_DIV) || (node->OperGet() == GT_MOD)); - GenTree* next = node->gtNext; if (varTypeIsIntegral(node->TypeGet())) { - // LowerConstIntDivOrMod will return nullptr if it doesn't transform the node. - GenTree* newNode = LowerConstIntDivOrMod(node); - if (newNode != nullptr) + GenTree* nextNode = nullptr; + if (TryLowerConstIntDivOrMod(node, &nextNode)) { - return newNode; + return nextNode; } + assert(nextNode == nullptr); } ContainCheckDivOrMod(node->AsOp()); - return next; + return node->gtNext; } //------------------------------------------------------------------------ @@ -7274,7 +7263,7 @@ void Lowering::CheckCallArg(GenTree* arg) { if (!arg->IsValue() && !arg->OperIsPutArgStk()) { - assert(arg->OperIsStore() || arg->OperIsCopyBlkOp()); + assert(arg->OperIsStore()); return; } @@ -7953,16 +7942,13 @@ void Lowering::LowerIndir(GenTreeIndir* ind) #if defined(TARGET_ARM64) // Verify containment safety before creating an LEA that must be contained. // - const bool isContainable = (ind->Addr() != nullptr) && IsInvariantInRange(ind->Addr(), ind); + const bool isContainable = IsInvariantInRange(ind->Addr(), ind); #else const bool isContainable = true; #endif - if (!ind->OperIs(GT_NOP)) - { - TryCreateAddrMode(ind->Addr(), isContainable, ind); - ContainCheckIndir(ind); - } + TryCreateAddrMode(ind->Addr(), isContainable, ind); + ContainCheckIndir(ind); #ifdef TARGET_XARCH if (ind->OperIs(GT_NULLCHECK) || ind->IsUnusedValue()) @@ -8010,15 +7996,6 @@ void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, Bas // assert(ind->OperIs(GT_NULLCHECK, GT_IND, GT_BLK)); - GenTree* const addr = ind->Addr(); - if (!comp->fgAddrCouldBeNull(addr)) - { - addr->SetUnusedValue(); - ind->gtBashToNOP(); - JITDUMP("bash an unused indir [%06u] to NOP.\n", comp->dspTreeID(ind)); - return; - } - ind->ChangeType(comp->gtTypeForNullCheck(ind)); #if defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) @@ -8026,7 +8003,7 @@ void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, Bas #elif defined(TARGET_ARM) bool useNullCheck = false; #else // TARGET_XARCH - bool useNullCheck = !addr->isContained(); + bool useNullCheck = !ind->Addr()->isContained(); ind->ClearDontExtend(); #endif // !TARGET_XARCH @@ -8229,7 +8206,7 @@ bool Lowering::TryTransformStoreObjAsStoreInd(GenTreeBlk* blkNode) // void Lowering::TryRetypingFloatingPointStoreToIntegerStore(GenTree* store) { - assert(store->OperIsStore() && !store->OperIsAtomicOp()); + assert(store->OperIsStore()); if (!varTypeIsFloating(store)) { @@ -8292,8 +8269,6 @@ void Lowering::TryRetypingFloatingPointStoreToIntegerStore(GenTree* store) if (store->OperIs(GT_STORE_LCL_VAR)) { store->SetOper(GT_STORE_LCL_FLD); - store->AsLclFld()->SetLclOffs(0); - store->AsLclFld()->SetLayout(nullptr); } store->ChangeType(type); } diff --git a/src/coreclr/jit/lower.h b/src/coreclr/jit/lower.h index 16677ef3304e92..3e4bd7ddc7292d 100644 --- a/src/coreclr/jit/lower.h +++ b/src/coreclr/jit/lower.h @@ -192,7 +192,7 @@ class Lowering final : public Phase GenTree* Ind(GenTree* tree, var_types type = TYP_I_IMPL) { - return comp->gtNewOperNode(GT_IND, type, tree); + return comp->gtNewIndir(type, tree); } GenTree* PhysReg(regNumber reg, var_types type = TYP_I_IMPL) @@ -312,7 +312,7 @@ class Lowering final : public Phase bool TryLowerAndNegativeOne(GenTreeOp* node, GenTree** nextNode); GenTree* LowerBinaryArithmetic(GenTreeOp* binOp); bool LowerUnsignedDivOrMod(GenTreeOp* divMod); - GenTree* LowerConstIntDivOrMod(GenTree* node); + bool TryLowerConstIntDivOrMod(GenTree* node, GenTree** nextNode); GenTree* LowerSignedDivOrMod(GenTree* node); void LowerBlockStore(GenTreeBlk* blkNode); void LowerBlockStoreCommon(GenTreeBlk* blkNode); @@ -475,7 +475,7 @@ class Lowering final : public Phase } #ifdef TARGET_ARM64 - bool IsContainableBinaryOp(GenTree* parentNode, GenTree* childNode) const; + bool IsContainableUnaryOrBinaryOp(GenTree* parentNode, GenTree* childNode) const; #endif // TARGET_ARM64 #if defined(FEATURE_HW_INTRINSICS) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 7b710aab8eecad..83f7be1b91a016 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -114,7 +114,10 @@ bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const case GT_TEST_NE: return emitter::emitIns_valid_imm_for_alu(immVal, size); case GT_JCMP: - assert(((parentNode->gtFlags & GTF_JCMP_TST) == 0) ? (immVal == 0) : isPow2(immVal)); + assert(immVal == 0); + return true; + case GT_JTEST: + assert(isPow2(immVal)); return true; #elif defined(TARGET_ARM) case GT_EQ: @@ -148,7 +151,7 @@ bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const #ifdef TARGET_ARM64 //------------------------------------------------------------------------ -// IsContainableBinaryOp: Is the child node a binary op that is containable from the parent node? +// IsContainableUnaryOrBinaryOp: Is the child node a unary/binary op that is containable from the parent node? // // Return Value: // True if the child node can be contained. @@ -156,10 +159,20 @@ bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const // Notes: // This can handle the decision to emit 'madd' or 'msub'. // -bool Lowering::IsContainableBinaryOp(GenTree* parentNode, GenTree* childNode) const +bool Lowering::IsContainableUnaryOrBinaryOp(GenTree* parentNode, GenTree* childNode) const { +#ifdef DEBUG // The node we're checking should be one of the two child nodes - assert((parentNode->gtGetOp1() == childNode) || (parentNode->gtGetOp2() == childNode)); + if (parentNode->OperIsBinary()) + { + assert((parentNode->gtGetOp1() == childNode) || (parentNode->gtGetOp2() == childNode)); + } + else + { + assert(parentNode->OperIsUnary()); + assert((parentNode->gtGetOp1() == childNode)); + } +#endif // DEBUG // We cannot contain if the parent node // * is contained @@ -173,7 +186,7 @@ bool Lowering::IsContainableBinaryOp(GenTree* parentNode, GenTree* childNode) co if (!varTypeIsIntegral(parentNode)) return false; - if (parentNode->gtGetOp1()->isContained() || parentNode->gtGetOp2()->isContained()) + if (parentNode->gtGetOp1()->isContained() || (parentNode->OperIsBinary() && parentNode->gtGetOp2()->isContained())) return false; if (parentNode->OperMayOverflow() && parentNode->gtOverflow()) @@ -252,7 +265,7 @@ bool Lowering::IsContainableBinaryOp(GenTree* parentNode, GenTree* childNode) co return false; } - if (parentNode->OperIs(GT_ADD, GT_SUB, GT_AND)) + if (parentNode->OperIs(GT_ADD, GT_SUB, GT_AND, GT_NEG)) { // These operations can still report flags @@ -282,6 +295,33 @@ bool Lowering::IsContainableBinaryOp(GenTree* parentNode, GenTree* childNode) co return false; } + if (childNode->OperIs(GT_NEG)) + { + // If we have a contained LSH, RSH or RSZ, we can still contain NEG if the parent is a EQ or NE. + if (childNode->gtGetOp1()->isContained() && !childNode->gtGetOp1()->OperIs(GT_LSH, GT_RSH, GT_RSZ)) + { + // Cannot contain if the childs op1 is already contained + return false; + } + + if ((parentNode->gtFlags & GTF_SET_FLAGS) != 0) + { + // Cannot contain if the parent operation needs to set flags + return false; + } + + // EQ and NE are the only valid comparison ops that can contain NEG. + if (parentNode->OperIs(GT_EQ, GT_NE)) + { + if (IsInvariantInRange(childNode, parentNode)) + { + return true; + } + } + + return false; + } + if (childNode->OperIs(GT_CAST)) { // Find "a op cast(b)" @@ -2027,7 +2067,7 @@ void Lowering::ContainCheckBinary(GenTreeOp* node) #ifdef TARGET_ARM64 if (comp->opts.OptimizationEnabled()) { - if (IsContainableBinaryOp(node, op2)) + if (IsContainableUnaryOrBinaryOp(node, op2)) { if (op2->OperIs(GT_CAST)) { @@ -2039,7 +2079,7 @@ void Lowering::ContainCheckBinary(GenTreeOp* node) return; } - if (node->OperIsCommutative() && IsContainableBinaryOp(node, op1)) + if (node->OperIsCommutative() && IsContainableUnaryOrBinaryOp(node, op1)) { if (op1->OperIs(GT_CAST)) { @@ -2259,19 +2299,22 @@ void Lowering::ContainCheckCompare(GenTreeOp* cmp) } #ifdef TARGET_ARM64 - if (comp->opts.OptimizationEnabled() && cmp->OperIsCompare()) + if (comp->opts.OptimizationEnabled() && (cmp->OperIsCompare() || cmp->OperIs(GT_CMP))) { - if (IsContainableBinaryOp(cmp, op2)) + if (IsContainableUnaryOrBinaryOp(cmp, op2)) { MakeSrcContained(cmp, op2); return; } - if (IsContainableBinaryOp(cmp, op1)) + if (IsContainableUnaryOrBinaryOp(cmp, op1)) { MakeSrcContained(cmp, op1); std::swap(cmp->gtOp1, cmp->gtOp2); - cmp->SetOper(cmp->SwapRelop(cmp->gtOper)); + if (cmp->OperIsCompare()) + { + cmp->SetOper(cmp->SwapRelop(cmp->gtOper)); + } return; } } @@ -2501,6 +2544,11 @@ void Lowering::ContainCheckNeg(GenTreeOp* neg) MakeSrcContained(neg, childNode); } } + else if (comp->opts.OptimizationEnabled() && childNode->OperIs(GT_LSH, GT_RSH, GT_RSZ) && + IsContainableUnaryOrBinaryOp(neg, childNode)) + { + MakeSrcContained(neg, childNode); + } } //---------------------------------------------------------------------------------------------- diff --git a/src/coreclr/jit/lowerloongarch64.cpp b/src/coreclr/jit/lowerloongarch64.cpp index 08514ed48d7a05..0173f5f42fa42e 100644 --- a/src/coreclr/jit/lowerloongarch64.cpp +++ b/src/coreclr/jit/lowerloongarch64.cpp @@ -84,7 +84,7 @@ bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const case GT_XOR: return emitter::isValidUimm12(immVal); case GT_JCMP: - assert(((parentNode->gtFlags & GTF_JCMP_TST) == 0) ? (immVal == 0) : isPow2(immVal)); + assert(immVal == 0); return true; case GT_STORE_LCL_FLD: @@ -152,13 +152,20 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue) // LA64's float compare and condition-branch instructions, have // condition flags indicating the comparing results. + // For LoongArch64, the floating compare result is saved to the specific register, + // where there are 8 bits for saveing at most eight different results, that is the FCC0 ~ FCC7. + // This is very different with the AArch64 and AMD64. + // For AArch64 and AMD64: | // For LoongArch64 + // cmp $f1, $f2 <--just compare. | fcmp.cond cc,$f1,$f2 <--the condition is here. + // branch.condition <--the condition is here. | branch true or false by the cc flag. if (varTypeIsFloating(cmpOp1)) { op->gtType = TYP_VOID; op->gtFlags |= GTF_SET_FLAGS; assert(op->OperIs(GT_EQ, GT_NE, GT_LT, GT_LE, GT_GE, GT_GT)); + jtrue->SetOper(GT_JCC); - jtrue->AsCC()->gtCondition = cond; + jtrue->AsCC()->gtCondition = GenCondition::NE; // For LA64 is only NE or EQ. return nullptr; } @@ -179,12 +186,10 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue) // for LA64's integer compare and condition-branch instructions, // it's very similar to the IL instructions. - jtrue->SetOper(GT_JCMP); - jtrue->gtOp1 = cmpOp1; - jtrue->gtOp2 = cmpOp2; - - jtrue->gtFlags &= ~(GTF_JCMP_TST | GTF_JCMP_EQ | GTF_JCMP_MASK); - jtrue->gtFlags |= (GenTreeFlags)(cond.GetCode() << 25); + jtrue->ChangeOper(GT_JCMP); + jtrue->gtOp1 = cmpOp1; + jtrue->gtOp2 = cmpOp2; + jtrue->AsOpCC()->gtCondition = cond; if (cmpOp2->IsCnsIntOrI()) { diff --git a/src/coreclr/jit/lowerriscv64.cpp b/src/coreclr/jit/lowerriscv64.cpp index 897d39e1b8618e..8bd0a8003fe34f 100644 --- a/src/coreclr/jit/lowerriscv64.cpp +++ b/src/coreclr/jit/lowerriscv64.cpp @@ -138,7 +138,7 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue) GenTree* cmpOp1; GenTree* cmpOp2; - if (op->OperIsCompare()) + if (op->OperIsCompare() && !varTypeIsFloating(op->gtGetOp1())) { // We do not expect any other relops on LA64 assert(op->OperIs(GT_EQ, GT_NE, GT_LT, GT_LE, GT_GE, GT_GT)); @@ -165,12 +165,10 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue) // for RISCV64's compare and condition-branch instructions, // it's very similar to the IL instructions. - jtrue->SetOper(GT_JCMP); - jtrue->gtOp1 = cmpOp1; - jtrue->gtOp2 = cmpOp2; - - jtrue->gtFlags &= ~(GTF_JCMP_TST | GTF_JCMP_EQ | GTF_JCMP_MASK); - jtrue->gtFlags |= (GenTreeFlags)(cond.GetCode() << 25); + jtrue->ChangeOper(GT_JCMP); + jtrue->gtOp1 = cmpOp1; + jtrue->gtOp2 = cmpOp2; + jtrue->AsOpCC()->gtCondition = cond; if (cmpOp2->IsCnsIntOrI()) { @@ -191,30 +189,6 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue) // GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp) { - if (comp->opts.OptimizationEnabled() && binOp->OperIs(GT_AND)) - { - GenTree* opNode = nullptr; - GenTree* notNode = nullptr; - if (binOp->gtGetOp1()->OperIs(GT_NOT)) - { - notNode = binOp->gtGetOp1(); - opNode = binOp->gtGetOp2(); - } - else if (binOp->gtGetOp2()->OperIs(GT_NOT)) - { - notNode = binOp->gtGetOp2(); - opNode = binOp->gtGetOp1(); - } - - if (notNode != nullptr) - { - binOp->gtOp1 = opNode; - binOp->gtOp2 = notNode->AsUnOp()->gtGetOp1(); - binOp->ChangeOper(GT_AND_NOT); - BlockRange().Remove(notNode); - } - } - ContainCheckBinary(binOp); return binOp->gtNext; diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index f2ab01def6d9e5..a34d7c05924295 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -327,7 +327,6 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) } else { - // The fill value of an initblk is interpreted to hold a // value of (unsigned int8) however a constant of any size // may practically reside on the evaluation stack. So extract @@ -337,38 +336,22 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) ssize_t fill = src->AsIntCon()->IconValue() & 0xFF; - if (fill == 0) + const bool canUseSimd = !blkNode->IsOnHeapAndContainsReferences() && comp->IsBaselineSimdIsaSupported(); + if (size > comp->getUnrollThreshold(Compiler::UnrollKind::Memset, canUseSimd)) { - if (size >= XMM_REGSIZE_BYTES) - { - const bool canUse16BytesSimdMov = !blkNode->IsOnHeapAndContainsReferences(); -#ifdef TARGET_AMD64 - - bool willUseOnlySimdMov = size % XMM_REGSIZE_BYTES == 0; - if (!willUseOnlySimdMov) - { - // If we have a remainder we still might only use SIMD to process it (via overlapping) - // unless it's more efficient to do that via scalar op (for sizes 1,2,4 and 8) - const unsigned remainder = size % XMM_REGSIZE_BYTES; - if (!isPow2(remainder) || (remainder > REGSIZE_BYTES)) - { - willUseOnlySimdMov = true; - } - } -#else - const bool willUseOnlySimdMov = (size % 8 == 0); -#endif - if (willUseOnlySimdMov && canUse16BytesSimdMov) - { - src->SetContained(); - } - else if (size > comp->getUnrollThreshold(Compiler::UnrollKind::Memset, - /*canUseSimd*/ canUse16BytesSimdMov)) - { - // It turns out we can't use SIMD so the default threshold is too big - goto TOO_BIG_TO_UNROLL; - } - } + // It turns out we can't use SIMD so the default threshold is too big + goto TOO_BIG_TO_UNROLL; + } + if (canUseSimd && (size >= XMM_REGSIZE_BYTES)) + { + // We're going to use SIMD (and only SIMD - we don't want to occupy a GPR register + // with a fill value just to handle the remainder when we can do that with + // an overlapped SIMD load). + src->SetContained(); + } + else if (fill == 0) + { + // Leave as is - zero shouldn't be contained when we don't use SIMD. } #ifdef TARGET_AMD64 else if (size >= REGSIZE_BYTES) @@ -1123,6 +1106,11 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) intrinsicId = NI_AVX512F_ExtractVector256; + if ((genTypeSize(simdBaseType) == 4) && !comp->compOpportunisticallyDependsOn(InstructionSet_AVX512DQ)) + { + intrinsicId = NI_AVX512DQ_ExtractVector256; + } + GenTree* op1 = node->Op(1); GenTree* op2 = comp->gtNewIconNode(1); @@ -1176,6 +1164,11 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) intrinsicId = NI_AVX512F_InsertVector256; + if ((genTypeSize(simdBaseType) == 4) && !comp->compOpportunisticallyDependsOn(InstructionSet_AVX512DQ)) + { + intrinsicId = NI_AVX512DQ_InsertVector256; + } + GenTree* op1 = node->Op(1); GenTree* op2 = node->Op(2); @@ -3397,8 +3390,14 @@ void Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) BlockRange().InsertBefore(node, idx); LowerNode(idx); - tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, idx, NI_AVX512F_ExtractVector128, simdBaseJitType, - simdSize); + NamedIntrinsic extractIntrinsicId = NI_AVX512F_ExtractVector128; + + if ((genTypeSize(simdBaseType) == 8) && !comp->compOpportunisticallyDependsOn(InstructionSet_AVX512DQ)) + { + extractIntrinsicId = NI_AVX512DQ_ExtractVector128; + } + + tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, idx, extractIntrinsicId, simdBaseJitType, simdSize); BlockRange().InsertBefore(node, tmp1); LowerNode(tmp1); } @@ -3683,8 +3682,14 @@ GenTree* Lowering::LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node) BlockRange().InsertAfter(op1, idx); LowerNode(idx); - tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, idx, NI_AVX512F_ExtractVector128, simdBaseJitType, - simdSize); + NamedIntrinsic extractIntrinsicId = NI_AVX512F_ExtractVector128; + + if ((genTypeSize(simdBaseType) == 8) && !comp->compOpportunisticallyDependsOn(InstructionSet_AVX512DQ)) + { + extractIntrinsicId = NI_AVX512DQ_ExtractVector128; + } + + tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, idx, extractIntrinsicId, simdBaseJitType, simdSize); BlockRange().InsertAfter(idx, tmp1); LowerNode(tmp1); } @@ -3697,7 +3702,14 @@ GenTree* Lowering::LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node) BlockRange().InsertBefore(node, idx); LowerNode(idx); - node->ResetHWIntrinsicId(NI_AVX512F_InsertVector128, comp, tmp64, result, idx); + NamedIntrinsic insertIntrinsicId = NI_AVX512F_InsertVector128; + + if ((genTypeSize(simdBaseType) == 8) && !comp->compOpportunisticallyDependsOn(InstructionSet_AVX512DQ)) + { + insertIntrinsicId = NI_AVX512DQ_InsertVector128; + } + + node->ResetHWIntrinsicId(insertIntrinsicId, comp, tmp64, result, idx); } else if (intrinsicId == NI_Vector256_WithElement) { @@ -3976,7 +3988,8 @@ GenTree* Lowering::LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node) // Now that we have finalized the shape of the tree, lower the insertion node as well. assert((node->GetHWIntrinsicId() == NI_Vector512_GetLower128) || - (node->GetHWIntrinsicId() == NI_AVX512F_ExtractVector128)); + (node->GetHWIntrinsicId() == NI_AVX512F_ExtractVector128) || + (node->GetHWIntrinsicId() == NI_AVX512DQ_ExtractVector128)); assert(node != result); nextNode = LowerNode(node); @@ -5799,6 +5812,8 @@ void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node) case NI_AVX2_ExtractVector128: case NI_AVX512F_ExtractVector128: case NI_AVX512F_ExtractVector256: + case NI_AVX512DQ_ExtractVector128: + case NI_AVX512DQ_ExtractVector256: { // These intrinsics are "ins reg/mem, xmm, imm8" @@ -5816,6 +5831,9 @@ void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node) } case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32WithSaturation: { if (varTypeIsFloating(simdBaseType)) { @@ -5824,31 +5842,73 @@ void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node) FALLTHROUGH; } + case NI_AVX512F_ConvertToVector128Byte: + case NI_AVX512F_ConvertToVector128ByteWithSaturation: case NI_AVX512F_ConvertToVector128Int16: - case NI_AVX512F_ConvertToVector128Int32: + case NI_AVX512F_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector128SByteWithSaturation: case NI_AVX512F_ConvertToVector128UInt16: - case NI_AVX512F_ConvertToVector128UInt32: + case NI_AVX512F_ConvertToVector128UInt16WithSaturation: case NI_AVX512F_ConvertToVector256Int16: + case NI_AVX512F_ConvertToVector256Int16WithSaturation: + case NI_AVX512F_ConvertToVector256Int32WithSaturation: case NI_AVX512F_ConvertToVector256UInt16: - case NI_AVX512F_ConvertToVector256UInt32: - case NI_AVX512BW_ConvertToVector128Byte: - case NI_AVX512BW_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector256UInt16WithSaturation: + case NI_AVX512F_ConvertToVector256UInt32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Byte: + case NI_AVX512F_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int16: + case NI_AVX512F_VL_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int32: + case NI_AVX512F_VL_ConvertToVector128Int32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128SByte: + case NI_AVX512F_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128UInt16: + case NI_AVX512F_VL_ConvertToVector128UInt16WithSaturation: case NI_AVX512BW_ConvertToVector256Byte: + case NI_AVX512BW_ConvertToVector256ByteWithSaturation: case NI_AVX512BW_ConvertToVector256SByte: + case NI_AVX512BW_ConvertToVector256SByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128Byte: + case NI_AVX512BW_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128SByte: + case NI_AVX512BW_VL_ConvertToVector128SByteWithSaturation: { // These intrinsics are "ins reg/mem, xmm" - unsigned simdSize = hwintrinsic->GetSimdSize(); + instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, simdBaseType); + insTupleType tupleType = comp->GetEmitter()->insTupleTypeInfo(ins); + unsigned simdSize = hwintrinsic->GetSimdSize(); + unsigned memSize = 0; - if (simdSize == 16) + switch (tupleType) { - // For TYP_SIMD16, we produce a TYP_SIMD16 register - // but only store TYP_SIMD8 to memory and so we cannot - // contain without additional work. - isContainable = false; + case INS_TT_HALF_MEM: + { + memSize = simdSize / 2; + break; + } + + case INS_TT_QUARTER_MEM: + { + memSize = simdSize / 4; + break; + } + + case INS_TT_EIGHTH_MEM: + { + memSize = simdSize / 8; + break; + } + + default: + { + unreached(); + } } - else + + if (genTypeSize(node) == memSize) { - assert((simdSize == 32) || (simdSize == 64)); isContainable = true; } break; @@ -6911,6 +6971,9 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX2_Shuffle: case NI_AVX2_ShuffleHigh: case NI_AVX2_ShuffleLow: + case NI_AVX512F_Permute2x64: + case NI_AVX512F_Permute4x32: + case NI_AVX512F_Permute4x64: case NI_AVX512F_ShiftLeftLogical: case NI_AVX512F_ShiftRightArithmetic: case NI_AVX512F_ShiftRightLogical: @@ -6936,6 +6999,8 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX_InsertVector128: case NI_AVX2_InsertVector128: + case NI_AVX512F_InsertVector128: + case NI_AVX512DQ_InsertVector128: { // InsertVector128 is special in that it returns a TYP_SIMD32 but takes a TYP_SIMD16. assert(!supportsSIMDScalarLoads); @@ -6950,6 +7015,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre } case NI_AVX512F_InsertVector256: + case NI_AVX512DQ_InsertVector256: { // InsertVector256 is special in that it returns a TYP_SIMD64 but takes a TYP_SIMD32. assert(!supportsSIMDScalarLoads); @@ -7095,6 +7161,10 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_SSE2_X64_ConvertScalarToVector128Double: case NI_SSE2_X64_ConvertScalarToVector128Int64: case NI_SSE2_X64_ConvertScalarToVector128UInt64: + case NI_AVX512F_ConvertScalarToVector128Double: + case NI_AVX512F_ConvertScalarToVector128Single: + case NI_AVX512F_X64_ConvertScalarToVector128Double: + case NI_AVX512F_X64_ConvertScalarToVector128Single: { if (!varTypeIsIntegral(childNode->TypeGet())) { @@ -7246,23 +7316,55 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre return supportsSIMDScalarLoads; } + case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32WithSaturation: + { + // These ones are not containable as stores when the base + // type is a floating-point type + FALLTHROUGH; + } + case NI_Vector128_GetElement: case NI_AVX_ExtractVector128: case NI_AVX2_ExtractVector128: case NI_AVX512F_ExtractVector128: case NI_AVX512F_ExtractVector256: + case NI_AVX512F_ConvertToVector128Byte: + case NI_AVX512F_ConvertToVector128ByteWithSaturation: case NI_AVX512F_ConvertToVector128Int16: - case NI_AVX512F_ConvertToVector128Int32: + case NI_AVX512F_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector128SByteWithSaturation: case NI_AVX512F_ConvertToVector128UInt16: - case NI_AVX512F_ConvertToVector128UInt32: + case NI_AVX512F_ConvertToVector128UInt16WithSaturation: case NI_AVX512F_ConvertToVector256Int16: - case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256Int16WithSaturation: + case NI_AVX512F_ConvertToVector256Int32WithSaturation: case NI_AVX512F_ConvertToVector256UInt16: - case NI_AVX512F_ConvertToVector256UInt32: - case NI_AVX512BW_ConvertToVector128Byte: - case NI_AVX512BW_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector256UInt16WithSaturation: + case NI_AVX512F_ConvertToVector256UInt32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Byte: + case NI_AVX512F_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int16: + case NI_AVX512F_VL_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int32: + case NI_AVX512F_VL_ConvertToVector128Int32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128SByte: + case NI_AVX512F_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128UInt16: + case NI_AVX512F_VL_ConvertToVector128UInt16WithSaturation: case NI_AVX512BW_ConvertToVector256Byte: + case NI_AVX512BW_ConvertToVector256ByteWithSaturation: case NI_AVX512BW_ConvertToVector256SByte: + case NI_AVX512BW_ConvertToVector256SByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128Byte: + case NI_AVX512BW_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128SByte: + case NI_AVX512BW_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512DQ_ExtractVector128: + case NI_AVX512DQ_ExtractVector256: { // These are only containable as part of a store return false; @@ -7354,6 +7456,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) GenTree* op1 = nullptr; GenTree* op2 = nullptr; GenTree* op3 = nullptr; + GenTree* op4 = nullptr; if (numArgs == 1) { @@ -7385,6 +7488,9 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_SSE41_RoundToNegativeInfinityScalar: case NI_SSE41_RoundToPositiveInfinityScalar: case NI_SSE41_RoundToZeroScalar: + case NI_AVX512F_GetExponentScalar: + case NI_AVX512F_Reciprocal14Scalar: + case NI_AVX512F_ReciprocalSqrt14Scalar: { // These intrinsics have both 1 and 2-operand overloads. // @@ -7467,6 +7573,9 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) } case NI_AVX512F_ConvertToVector256Int32: + case NI_AVX512F_ConvertToVector256UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32: + case NI_AVX512F_VL_ConvertToVector128UInt32WithSaturation: { if (varTypeIsFloating(simdBaseType)) { @@ -7477,17 +7586,38 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) FALLTHROUGH; } + case NI_AVX512F_ConvertToVector128Byte: + case NI_AVX512F_ConvertToVector128ByteWithSaturation: case NI_AVX512F_ConvertToVector128Int16: - case NI_AVX512F_ConvertToVector128Int32: + case NI_AVX512F_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector128SByteWithSaturation: case NI_AVX512F_ConvertToVector128UInt16: - case NI_AVX512F_ConvertToVector128UInt32: + case NI_AVX512F_ConvertToVector128UInt16WithSaturation: case NI_AVX512F_ConvertToVector256Int16: + case NI_AVX512F_ConvertToVector256Int16WithSaturation: + case NI_AVX512F_ConvertToVector256Int32WithSaturation: case NI_AVX512F_ConvertToVector256UInt16: - case NI_AVX512F_ConvertToVector256UInt32: - case NI_AVX512BW_ConvertToVector128Byte: - case NI_AVX512BW_ConvertToVector128SByte: + case NI_AVX512F_ConvertToVector256UInt16WithSaturation: + case NI_AVX512F_ConvertToVector256UInt32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Byte: + case NI_AVX512F_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int16: + case NI_AVX512F_VL_ConvertToVector128Int16WithSaturation: + case NI_AVX512F_VL_ConvertToVector128Int32: + case NI_AVX512F_VL_ConvertToVector128Int32WithSaturation: + case NI_AVX512F_VL_ConvertToVector128SByte: + case NI_AVX512F_VL_ConvertToVector128SByteWithSaturation: + case NI_AVX512F_VL_ConvertToVector128UInt16: + case NI_AVX512F_VL_ConvertToVector128UInt16WithSaturation: case NI_AVX512BW_ConvertToVector256Byte: + case NI_AVX512BW_ConvertToVector256ByteWithSaturation: case NI_AVX512BW_ConvertToVector256SByte: + case NI_AVX512BW_ConvertToVector256SByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128Byte: + case NI_AVX512BW_VL_ConvertToVector128ByteWithSaturation: + case NI_AVX512BW_VL_ConvertToVector128SByte: + case NI_AVX512BW_VL_ConvertToVector128SByteWithSaturation: { // These intrinsics are "ins reg/mem, xmm" and get // contained by the relevant store operation instead. @@ -7588,6 +7718,8 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX2_ExtractVector128: case NI_AVX512F_ExtractVector128: case NI_AVX512F_ExtractVector256: + case NI_AVX512DQ_ExtractVector128: + case NI_AVX512DQ_ExtractVector256: { // These intrinsics are "ins reg/mem, xmm, imm8" and get // contained by the relevant store operation instead. @@ -7652,6 +7784,9 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX2_Permute4x64: case NI_AVX2_ShuffleHigh: case NI_AVX2_ShuffleLow: + case NI_AVX512F_Permute2x64: + case NI_AVX512F_Permute4x32: + case NI_AVX512F_Permute4x64: case NI_AVX512F_Shuffle: case NI_AVX512BW_ShuffleHigh: case NI_AVX512BW_ShuffleLow: @@ -7719,6 +7854,12 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) } case NI_AES_KeygenAssist: + case NI_AVX512F_GetMantissa: + case NI_AVX512F_VL_GetMantissa: + case NI_AVX512F_RoundScale: + case NI_AVX512F_VL_RoundScale: + case NI_AVX512DQ_Reduce: + case NI_AVX512DQ_VL_Reduce: { if (!isContainedImm) { @@ -7758,6 +7899,19 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) break; } + case NI_AVX512F_GetMantissaScalar: + case NI_AVX512F_RoundScaleScalar: + case NI_AVX512DQ_ReduceScalar: + { + // These intrinsics have both 2 and 3-operand overloads. + // + // The 2-operand overload basically does `intrinsic(op1, op1, cns)` + // + // Because of this, the operand must be loaded into a register + // and cannot be contained. + return; + } + default: { assert(!"Unhandled containment for binary hardware intrinsic with immediate operand"); @@ -7838,7 +7992,16 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case HW_Category_SIMDScalar: case HW_Category_Scalar: { - if ((intrinsicId >= NI_FMA_MultiplyAdd) && (intrinsicId <= NI_FMA_MultiplySubtractNegatedScalar)) + bool isFmaIntrinsic = + (intrinsicId >= NI_FMA_MultiplyAdd) && (intrinsicId <= NI_FMA_MultiplySubtractNegatedScalar); + + if (!isFmaIntrinsic) + { + isFmaIntrinsic = (intrinsicId >= NI_AVX512F_FusedMultiplyAdd) && + (intrinsicId <= NI_AVX512F_FusedMultiplySubtractNegated); + } + + if (isFmaIntrinsic) { bool supportsOp1RegOptional = false; bool supportsOp2RegOptional = false; @@ -7993,9 +8156,18 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX2_InsertVector128: case NI_AVX2_MultipleSumAbsoluteDifferences: case NI_AVX2_Permute2x128: + case NI_AVX512F_GetMantissaScalar: + case NI_AVX512F_InsertVector128: case NI_AVX512F_InsertVector256: + case NI_AVX512F_RoundScaleScalar: case NI_AVX512F_Shuffle: case NI_AVX512BW_AlignRight: + case NI_AVX512DQ_InsertVector128: + case NI_AVX512DQ_InsertVector256: + case NI_AVX512DQ_Range: + case NI_AVX512DQ_RangeScalar: + case NI_AVX512DQ_VL_Range: + case NI_AVX512DQ_ReduceScalar: case NI_PCLMULQDQ_CarrylessMultiply: { if (!isContainedImm) @@ -8110,6 +8282,71 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) } } } + else if (numArgs == 4) + { + // four argument intrinsics should not be marked commutative + assert(!isCommutative); + + op1 = node->Op(1); + op2 = node->Op(2); + op3 = node->Op(3); + op4 = node->Op(4); + + switch (category) + { + case HW_Category_IMM: + { + bool supportsRegOptional = false; + + switch (intrinsicId) + { + case NI_AVX512F_Fixup: + case NI_AVX512F_FixupScalar: + case NI_AVX512F_VL_Fixup: + { + if (!isContainedImm) + { + // Don't contain if we're generating a jmp table fallback + break; + } + + if (IsContainableHWIntrinsicOp(node, op3, &supportsRegOptional)) + { + MakeSrcContained(node, op3); + } + else if (supportsRegOptional) + { + MakeSrcRegOptional(node, op3); + } + + if (!node->isRMWHWIntrinsic(comp)) + { + // op1 is never selected by the table so + // we can contain and ignore any register + // allocated to it resulting in better + // non-RMW based codegen. + + MakeSrcContained(node, op1); + } + break; + } + + default: + { + assert(!"Unhandled containment for quaternary hardware intrinsic with immediate operand"); + break; + } + } + break; + } + + default: + { + unreached(); + break; + } + } + } else { unreached(); diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 64fb68cba56c7c..d803ae8fcaff5e 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -3423,15 +3423,11 @@ void LinearScan::spillInterval(Interval* interval, RefPosition* fromRefPosition } } - // Only handle the singledef intervals whose firstRefPosition is RefTypeDef and is not yet marked as spillAfter. - // The singledef intervals whose firstRefPositions are already marked as spillAfter, no need to mark them as - // singleDefSpill because they will always get spilled at firstRefPosition. - // This helps in spilling the singleDef at definition + // Only handle the singledef intervals whose firstRefPosition is RefTypeDef. // // Note: Only mark "singleDefSpill" for those intervals who ever get spilled. The intervals that are never spilled // will not be marked as "singleDefSpill" and hence won't get spilled at the first definition. - if (interval->isSingleDef && RefTypeIsDef(interval->firstRefPosition->refType) && - !interval->firstRefPosition->spillAfter) + if (interval->isSingleDef && RefTypeIsDef(interval->firstRefPosition->refType)) { // TODO-CQ: Check if it is beneficial to spill at def, meaning, if it is a hot block don't worry about // doing the spill. Another option is to track number of refpositions and a interval has more than X @@ -4822,6 +4818,12 @@ void LinearScan::allocateRegisters() copyRegsToFree = RBM_NONE; regsInUseThisLocation = regsInUseNextLocation; regsInUseNextLocation = RBM_NONE; +#ifdef TARGET_ARM64 + if (hasConsecutiveRegister) + { + consecutiveRegsInUseThisLocation = RBM_NONE; + } +#endif if ((regsToFree | delayRegsToFree) != RBM_NONE) { freeRegisters(regsToFree); @@ -5437,6 +5439,7 @@ void LinearScan::allocateRegisters() // It doesn't satisfy, so do a copyReg for the first RefPosition to such a register, so // it would be possible to allocate consecutive registers to the subsequent RefPositions. regNumber copyReg = assignCopyReg(¤tRefPosition); + assignConsecutiveRegisters(¤tRefPosition, copyReg); if (copyReg != assignedRegister) { @@ -5444,6 +5447,16 @@ void LinearScan::allocateRegisters() regMaskTP copyRegMask = getRegMask(copyReg, currentInterval->registerType); regMaskTP assignedRegMask = getRegMask(assignedRegister, currentInterval->registerType); + if ((consecutiveRegsInUseThisLocation & assignedRegMask) != RBM_NONE) + { + // If assigned register is one of the consecutive register we are about to assign + // to the subsequent RefPositions, do not mark it busy otherwise when we allocate + // for that particular subsequent RefPosition, we will not find any candidates + // available. Not marking it busy should be fine because we have already set the + // register assignments for all the consecutive refpositions. + assignedRegMask = RBM_NONE; + } + // For consecutive register, although it shouldn't matter what the assigned register was, // because we have just assigned it `copyReg` and that's the one in-use, and not the // one that was assigned previously. However, in situation where an upper-vector restore @@ -5484,7 +5497,6 @@ void LinearScan::allocateRegisters() currentRefPosition.registerAssignment = assignedRegBit; } - assignConsecutiveRegisters(¤tRefPosition, copyReg); continue; } } @@ -5542,6 +5554,16 @@ void LinearScan::allocateRegisters() // registers. assignConsecutiveRegisters(¤tRefPosition, copyReg); } + + if ((consecutiveRegsInUseThisLocation & assignedRegMask) != RBM_NONE) + { + // If assigned register is one of the consecutive register we are about to assign + // to the subsequent RefPositions, do not mark it busy otherwise when we allocate + // for that particular subsequent RefPosition, we will not find any candidates + // available. Not marking it busy should be fine because we have already set the + // register assignments for all the consecutive refpositions. + assignedRegMask = RBM_NONE; + } } #endif // For consecutive register, although it shouldn't matter what the assigned register was, @@ -6280,6 +6302,11 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreeLclVar* treeNode, Ref varDsc->SetRegNum(REG_STK); interval->physReg = REG_NA; writeLocalReg(treeNode->AsLclVar(), interval->varNum, REG_NA); + + if (currentRefPosition->singleDefSpill) + { + varDsc->lvSpillAtSingleDef = true; + } } else // Not reload and Not pure-def that's spillAfter { @@ -8001,10 +8028,10 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) } LclVarDsc* terminatorNodeLclVarDsc = nullptr; - // Next, if this blocks ends with a switch table, or for Arm64, ends with JCMP instruction, + // Next, if this blocks ends with a switch table, or for Arm64, ends with JCMP/JTEST instruction, // make sure to not copy into the registers that are consumed at the end of this block. // - // Note: Only switches and JCMP (for Arm4) have input regs (and so can be fed by copies), so those + // Note: Only switches and JCMP/JTEST (for Arm4) have input regs (and so can be fed by copies), so those // are the only block-ending branches that need special handling. regMaskTP consumedRegs = RBM_NONE; if (block->bbJumpKind == BBJ_SWITCH) @@ -8033,8 +8060,8 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) consumedRegs |= genRegMask(srcOp1->GetRegNum()); } } - // Next, if this blocks ends with a JCMP/JTRUE, we have to make sure: - // 1. Not to copy into the register that JCMP/JTRUE uses + // Next, if this blocks ends with a JCMP/JTEST/JTRUE, we have to make sure: + // 1. Not to copy into the register that JCMP/JTEST/JTRUE uses // e.g. JCMP w21, BRANCH // 2. Not to copy into the source of JCMP's operand before it is consumed // e.g. Should not use w0 since it will contain wrong value after resolution @@ -8050,7 +8077,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) { GenTree* lastNode = LIR::AsRange(block).LastNode(); - if (lastNode->OperIs(GT_JTRUE, GT_JCMP)) + if (lastNode->OperIs(GT_JTRUE, GT_JCMP, GT_JTEST)) { GenTree* op = lastNode->gtGetOp1(); consumedRegs |= genRegMask(op->GetRegNum()); @@ -8070,7 +8097,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) #if !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64) // TODO-LOONGARCH64: Take into account that on LA64, the second // operand of a JCMP can be in a register too. - assert(!lastNode->OperIs(GT_JCMP) || lastNode->gtGetOp2()->isContained()); + assert(!lastNode->OperIs(GT_JCMP, GT_JTEST) || lastNode->gtGetOp2()->isContained()); #endif } } diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index f9de491dfc199d..d869f8f8a126c6 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1839,6 +1839,9 @@ class LinearScan : public LinearScanInterface regMaskTP regsBusyUntilKill; regMaskTP regsInUseThisLocation; regMaskTP regsInUseNextLocation; +#ifdef TARGET_ARM64 + regMaskTP consecutiveRegsInUseThisLocation; +#endif bool isRegBusy(regNumber reg, var_types regType) { regMaskTP regMask = getRegMask(reg, regType); diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 95dac793de5661..40513da8e56568 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -67,6 +67,7 @@ void LinearScan::assignConsecutiveRegisters(RefPosition* firstRefPosition, regNu assert(firstRefPosition->assignedReg() == firstRegAssigned); assert(firstRefPosition->isFirstRefPositionOfConsecutiveRegisters()); assert(emitter::isVectorRegister(firstRegAssigned)); + assert(consecutiveRegsInUseThisLocation == RBM_NONE); RefPosition* consecutiveRefPosition = getNextConsecutiveRefPosition(firstRefPosition); regNumber regToAssign = firstRegAssigned == REG_FP_LAST ? REG_FP_FIRST : REG_NEXT(firstRegAssigned); @@ -75,7 +76,7 @@ void LinearScan::assignConsecutiveRegisters(RefPosition* firstRefPosition, regNu assert(firstRefPosition->refType != RefTypeUpperVectorRestore); INDEBUG(int refPosCount = 1); - regMaskTP busyConsecutiveRegMask = (((1ULL << firstRefPosition->regCount) - 1) << firstRegAssigned); + consecutiveRegsInUseThisLocation = (((1ULL << firstRefPosition->regCount) - 1) << firstRegAssigned); while (consecutiveRefPosition != nullptr) { @@ -95,7 +96,7 @@ void LinearScan::assignConsecutiveRegisters(RefPosition* firstRefPosition, regNu // RefTypeUpperVectorRestore positions of corresponding variables for which (another criteria) // we are trying to find consecutive registers. - consecutiveRefPosition->registerAssignment &= ~busyConsecutiveRegMask; + consecutiveRefPosition->registerAssignment &= ~consecutiveRegsInUseThisLocation; } consecutiveRefPosition = getNextConsecutiveRefPosition(consecutiveRefPosition); } @@ -937,6 +938,7 @@ int LinearScan::BuildNode(GenTree* tree) case GT_TEST: case GT_CCMP: case GT_JCMP: + case GT_JTEST: srcCount = BuildCmp(tree); break; diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 0b28c1223cb53d..0f11acdadb7019 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -922,7 +922,7 @@ regMaskTP LinearScan::getKillSetForCall(GenTreeCall* call) // regMaskTP LinearScan::getKillSetForBlockStore(GenTreeBlk* blkNode) { - assert(blkNode->OperIsStore()); + assert(blkNode->OperIsStoreBlk()); regMaskTP killMask = RBM_NONE; bool isCopyBlk = varTypeIsStruct(blkNode->Data()); @@ -1683,8 +1683,7 @@ int LinearScan::ComputeOperandDstCount(GenTree* operand) // This must be one of the operand types that are neither contained nor produce a value. // Stores and void-typed operands may be encountered when processing call nodes, which contain // pointers to argument setup stores. - assert(operand->OperIsStore() || operand->OperIsBlkOp() || operand->OperIsPutArgStk() || - operand->TypeIs(TYP_VOID)); + assert(operand->OperIsStore() || operand->OperIsPutArgStk() || operand->TypeIs(TYP_VOID)); return 0; } } @@ -4193,9 +4192,9 @@ int LinearScan::BuildGCWriteBarrier(GenTree* tree) int LinearScan::BuildCmp(GenTree* tree) { #if defined(TARGET_XARCH) - assert(tree->OperIsCompare() || tree->OperIs(GT_CMP, GT_TEST, GT_JCMP, GT_BT)); + assert(tree->OperIsCompare() || tree->OperIs(GT_CMP, GT_TEST, GT_BT)); #elif defined(TARGET_ARM64) - assert(tree->OperIsCompare() || tree->OperIs(GT_CMP, GT_TEST, GT_JCMP, GT_CCMP)); + assert(tree->OperIsCompare() || tree->OperIs(GT_CMP, GT_TEST, GT_JCMP, GT_JTEST, GT_CCMP)); #else assert(tree->OperIsCompare() || tree->OperIs(GT_CMP, GT_TEST, GT_JCMP)); #endif diff --git a/src/coreclr/jit/lsraloongarch64.cpp b/src/coreclr/jit/lsraloongarch64.cpp index fccef004588e5c..e2ce3c35d3636f 100644 --- a/src/coreclr/jit/lsraloongarch64.cpp +++ b/src/coreclr/jit/lsraloongarch64.cpp @@ -928,6 +928,10 @@ int LinearScan::BuildCall(GenTreeCall* call) // Now generate defs and kills. regMaskTP killMask = getKillSetForCall(call); BuildDefsWithKills(call, dstCount, dstCandidates, killMask); + + // No args are placed in registers anymore. + placedArgRegs = RBM_NONE; + numPlacedArgLocals = 0; return srcCount; } diff --git a/src/coreclr/jit/lsrariscv64.cpp b/src/coreclr/jit/lsrariscv64.cpp index 35ad4397b568b3..cef952206acf4f 100644 --- a/src/coreclr/jit/lsrariscv64.cpp +++ b/src/coreclr/jit/lsrariscv64.cpp @@ -1047,8 +1047,79 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) // int LinearScan::BuildPutArgSplit(GenTreePutArgSplit* argNode) { - NYI_RISCV64("BuildPutArgSplit-----unimplemented on RISCV64 yet----"); - return 0; + int srcCount = 0; + assert(argNode->gtOper == GT_PUTARG_SPLIT); + + GenTree* putArgChild = argNode->gtGetOp1(); + + // Registers for split argument corresponds to source + int dstCount = argNode->gtNumRegs; + + regNumber argReg = argNode->GetRegNum(); + regMaskTP argMask = RBM_NONE; + for (unsigned i = 0; i < argNode->gtNumRegs; i++) + { + regNumber thisArgReg = (regNumber)((unsigned)argReg + i); + argMask |= genRegMask(thisArgReg); + argNode->SetRegNumByIdx(thisArgReg, i); + } + + if (putArgChild->OperGet() == GT_FIELD_LIST) + { + // Generated code: + // 1. Consume all of the items in the GT_FIELD_LIST (source) + // 2. Store to target slot and move to target registers (destination) from source + // + unsigned sourceRegCount = 0; + + // To avoid redundant moves, have the argument operand computed in the + // register in which the argument is passed to the call. + + for (GenTreeFieldList::Use& use : putArgChild->AsFieldList()->Uses()) + { + GenTree* node = use.GetNode(); + assert(!node->isContained()); + // The only multi-reg nodes we should see are OperIsMultiRegOp() + assert(!node->IsMultiRegNode()); + + // Consume all the registers, setting the appropriate register mask for the ones that + // go into registers. + regMaskTP sourceMask = RBM_NONE; + if (sourceRegCount < argNode->gtNumRegs) + { + sourceMask = genRegMask((regNumber)((unsigned)argReg + sourceRegCount)); + } + sourceRegCount++; + BuildUse(node, sourceMask, 0); + } + srcCount += sourceRegCount; + assert(putArgChild->isContained()); + } + else + { + assert(putArgChild->TypeGet() == TYP_STRUCT); + assert(putArgChild->OperGet() == GT_BLK); + + // We can use a ld/st sequence so we need an internal register + buildInternalIntRegisterDefForNode(argNode, allRegs(TYP_INT) & ~argMask); + + GenTree* objChild = putArgChild->gtGetOp1(); + if (objChild->IsLclVarAddr()) + { + // We will generate all of the code for the GT_PUTARG_SPLIT, the GT_BLK and the GT_LCL_ADDR<0> + // as one contained operation + // + assert(objChild->isContained()); + } + else + { + srcCount = BuildIndirUses(putArgChild->AsIndir()); + } + assert(putArgChild->isContained()); + } + buildInternalRegisterUses(); + BuildDefs(argNode, dstCount, argMask); + return srcCount; } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index ed6d1d2eb67748..97134c8345b6d4 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -2104,11 +2104,51 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou // to simplify the overall IR handling. As such, we need to "skip" such nodes when present and // get the underlying op1 so that delayFreeUse and other preferencing remains correct. - GenTree* op1 = SkipContainedCreateScalarUnsafe(intrinsicTree->Op(1)); - GenTree* op2 = (numArgs >= 2) ? SkipContainedCreateScalarUnsafe(intrinsicTree->Op(2)) : nullptr; - GenTree* op3 = (numArgs >= 3) ? SkipContainedCreateScalarUnsafe(intrinsicTree->Op(3)) : nullptr; + GenTree* op1 = nullptr; + GenTree* op2 = nullptr; + GenTree* op3 = nullptr; + GenTree* op4 = nullptr; + GenTree* op5 = nullptr; GenTree* lastOp = SkipContainedCreateScalarUnsafe(intrinsicTree->Op(numArgs)); + switch (numArgs) + { + case 5: + { + op5 = SkipContainedCreateScalarUnsafe(intrinsicTree->Op(5)); + FALLTHROUGH; + } + + case 4: + { + op4 = SkipContainedCreateScalarUnsafe(intrinsicTree->Op(4)); + FALLTHROUGH; + } + + case 3: + { + op3 = SkipContainedCreateScalarUnsafe(intrinsicTree->Op(3)); + FALLTHROUGH; + } + + case 2: + { + op2 = SkipContainedCreateScalarUnsafe(intrinsicTree->Op(2)); + FALLTHROUGH; + } + + case 1: + { + op1 = SkipContainedCreateScalarUnsafe(intrinsicTree->Op(1)); + break; + } + + default: + { + unreached(); + } + } + bool buildUses = true; if ((category == HW_Category_IMM) && !HWIntrinsicInfo::NoJmpTableImm(intrinsicId)) @@ -2130,7 +2170,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou bool isRMW = intrinsicTree->isRMWHWIntrinsic(compiler); #if defined(TARGET_AMD64) bool isEvexCompatible = intrinsicTree->isEvexCompatibleHWIntrinsic(); -#endif +#endif // TARGET_AMD64 // Create internal temps, and handle any other special requirements. // Note that the default case for building uses will handle the RMW flag, but if the uses @@ -2355,6 +2395,12 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou case NI_FMA_MultiplySubtractNegated: case NI_FMA_MultiplySubtractNegatedScalar: case NI_FMA_MultiplySubtractScalar: + case NI_AVX512F_FusedMultiplyAdd: + case NI_AVX512F_FusedMultiplyAddNegated: + case NI_AVX512F_FusedMultiplyAddSubtract: + case NI_AVX512F_FusedMultiplySubtract: + case NI_AVX512F_FusedMultiplySubtractAdd: + case NI_AVX512F_FusedMultiplySubtractNegated: { assert(numArgs == 3); assert(isRMW); @@ -2498,9 +2544,6 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou { assert(!isRMW); - GenTree* op4 = intrinsicTree->Op(4); - GenTree* op5 = intrinsicTree->Op(5); - // Any pair of the index, mask, or destination registers should be different srcCount += BuildOperandUses(op1, BuildEvexIncompatibleMask(op1)); srcCount += BuildDelayFreeUses(op2, nullptr, BuildEvexIncompatibleMask(op2)); @@ -2537,15 +2580,14 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou if (buildUses) { - assert((numArgs > 0) && (numArgs < 4)); - regMaskTP op1RegCandidates = RBM_NONE; + #if defined(TARGET_AMD64) if (!isEvexCompatible) { op1RegCandidates = BuildEvexIncompatibleMask(op1); } -#endif +#endif // TARGET_AMD64 if (intrinsicTree->OperIsMemoryLoadOrStore()) { @@ -2564,12 +2606,14 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou if (op2 != nullptr) { regMaskTP op2RegCandidates = RBM_NONE; + #if defined(TARGET_AMD64) if (!isEvexCompatible) { op2RegCandidates = BuildEvexIncompatibleMask(op2); } -#endif +#endif // TARGET_AMD64 + if (op2->OperIs(GT_HWINTRINSIC) && op2->AsHWIntrinsic()->OperIsMemoryLoad() && op2->isContained()) { srcCount += BuildAddrUses(op2->AsHWIntrinsic()->Op(1), op2RegCandidates); @@ -2608,14 +2652,28 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou if (op3 != nullptr) { regMaskTP op3RegCandidates = RBM_NONE; + #if defined(TARGET_AMD64) if (!isEvexCompatible) { op3RegCandidates = BuildEvexIncompatibleMask(op3); } -#endif +#endif // TARGET_AMD64 + srcCount += isRMW ? BuildDelayFreeUses(op3, op1, op3RegCandidates) : BuildOperandUses(op3, op3RegCandidates); + + if (op4 != nullptr) + { + regMaskTP op4RegCandidates = RBM_NONE; + +#if defined(TARGET_AMD64) + assert(isEvexCompatible); +#endif // TARGET_AMD64 + + srcCount += isRMW ? BuildDelayFreeUses(op4, op1, op4RegCandidates) + : BuildOperandUses(op4, op4RegCandidates); + } } } } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index f78b23c963a8be..a583c739816904 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -3180,7 +3180,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) GenTree* argObj = argx->gtEffectiveVal(true /*commaOnly*/); bool makeOutArgCopy = false; - if (isStructArg && varTypeIsStruct(argObj) && !argObj->OperIs(GT_ASG, GT_MKREFANY, GT_FIELD_LIST)) + if (isStructArg && !reMorphing && !argObj->OperIs(GT_MKREFANY)) { unsigned originalSize; if (argObj->TypeGet() == TYP_STRUCT) @@ -3193,6 +3193,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) originalSize = genTypeSize(argx); } + assert(argx->TypeGet() == arg.GetSignatureType()); assert(originalSize == info.compCompHnd->getClassSize(arg.GetSignatureClassHandle())); // First, handle the case where the argument is passed by reference. @@ -3858,10 +3859,6 @@ GenTree* Compiler::fgMorphMultiregStructArg(CallArg* arg) } GenTree* argIndir = gtNewIndir(elems[inx].Type, curAddr); - - // For safety all GT_IND should have at least GT_GLOB_REF set. - argIndir->gtFlags |= GTF_GLOB_REF; - newArg->AddField(this, argIndir, offset, argIndir->TypeGet()); } @@ -3947,9 +3944,8 @@ void Compiler::fgMakeOutgoingStructArgCopy(GenTreeCall* call, CallArg* arg) if (lcl != nullptr) { - const unsigned varNum = lcl->GetLclNum(); - LclVarDsc* const varDsc = lvaGetDesc(varNum); - const unsigned short totalAppearances = varDsc->lvRefCnt(RCS_EARLY); + const unsigned varNum = lcl->GetLclNum(); + LclVarDsc* const varDsc = lvaGetDesc(varNum); // We generally use liveness to figure out if we can omit creating // this copy. However, even without liveness (e.g. due to too many @@ -3963,9 +3959,6 @@ void Compiler::fgMakeOutgoingStructArgCopy(GenTreeCall* call, CallArg* arg) // alias analysis of the call's parameters, or checking if the call // site is not within some try region. // - // * (may not copy) if there is exactly one use of the local in the method, - // and the call is not in loop, this is a last use. - // bool omitCopy = call->IsTailCall(); if (!omitCopy && fgGlobalMorph) @@ -4445,6 +4438,8 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // same values are used in the bounds check and the actual dereference. // Also we allocate the temporary when the expression is sufficiently complex/expensive. // + // TODO-FIELD: review below comment. + // // Note that if the expression is a GT_FIELD, it has not yet been morphed so its true complexity is // not exposed. Without that condition there are cases of local struct fields that were previously, // needlessly, marked as GTF_GLOB_REF, and when that was fixed, there were some regressions that @@ -4456,7 +4451,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // do this here. Likewise for implicit byrefs. if (((arrRef->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || - gtComplexityExceeds(arrRef, MAX_ARR_COMPLEXITY) || arrRef->OperIs(GT_FIELD, GT_LCL_FLD) || + gtComplexityExceeds(arrRef, MAX_ARR_COMPLEXITY) || arrRef->OperIs(GT_LCL_FLD) || (arrRef->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(arrRef->AsLclVar()->GetLclNum()))) { unsigned arrRefTmpNum = lvaGrabTemp(true DEBUGARG("arr expr")); @@ -4471,7 +4466,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) } if (((index->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || - gtComplexityExceeds(index, MAX_ARR_COMPLEXITY) || index->OperIs(GT_FIELD, GT_LCL_FLD) || + gtComplexityExceeds(index, MAX_ARR_COMPLEXITY) || index->OperIs(GT_LCL_FLD) || (index->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(index->AsLclVar()->GetLclNum()))) { unsigned indexTmpNum = lvaGrabTemp(true DEBUGARG("index expr")); @@ -4726,21 +4721,8 @@ GenTree* Compiler::fgMorphExpandStackArgForVarArgs(GenTreeLclVarCommon* lclNode) return argAddr; } - GenTree* argNode; - if (lclNode->TypeIs(TYP_STRUCT)) - { - argNode = gtNewLoadValueNode(lclNode->GetLayout(this), argAddr); - } - else - { - argNode = gtNewIndir(lclNode->TypeGet(), argAddr); - } - - if (varDsc->IsAddressExposed()) - { - argNode->gtFlags |= GTF_GLOB_REF; - } - + GenTree* argNode = lclNode->TypeIs(TYP_STRUCT) ? gtNewBlkIndir(lclNode->GetLayout(this), argAddr) + : gtNewIndir(lclNode->TypeGet(), argAddr); return argNode; } #endif @@ -4862,19 +4844,11 @@ GenTree* Compiler::fgMorphExpandImplicitByRefArg(GenTreeLclVarCommon* lclNode) GenTree* newArgNode; if (!isAddress) { - if (argNodeType == TYP_STRUCT) - { - newArgNode = gtNewLoadValueNode(argNodeLayout, addrNode); - } - else - { - newArgNode = gtNewIndir(argNodeType, addrNode); - } - - // Currently, we have to conservatively treat all indirections off of implicit byrefs as - // global. This is because we lose the information on whether the original local's address - // was exposed when we retype it in "fgRetypeImplicitByRefArgs". - newArgNode->gtFlags |= GTF_GLOB_REF; + // Note: currently, we have to conservatively treat all indirections off of implicit byrefs as global. This + // is because we lose the information on whether the original local's address was exposed when we retype it + // in "fgRetypeImplicitByRefArgs". + newArgNode = + (argNodeType == TYP_STRUCT) ? gtNewBlkIndir(argNodeLayout, addrNode) : gtNewIndir(argNodeType, addrNode); } else { @@ -4971,7 +4945,7 @@ GenTree* Compiler::fgMorphLocalVar(GenTree* tree) // Return Value: // The local number. // -unsigned Compiler::fgGetFieldMorphingTemp(GenTreeField* fieldNode) +unsigned Compiler::fgGetFieldMorphingTemp(GenTreeFieldAddr* fieldNode) { assert(fieldNode->IsInstance()); @@ -5007,29 +4981,24 @@ unsigned Compiler::fgGetFieldMorphingTemp(GenTreeField* fieldNode) } //------------------------------------------------------------------------ -// fgMorphField: Fully morph a FIELD/FIELD_ADDR tree. +// fgMorphFieldAddr: Fully morph a FIELD_ADDR tree. // -// Expands the field node into explicit additions and indirections. +// Expands the field node into explicit additions. // // Arguments: -// tree - The FIELD/FIELD_ADDR tree +// tree - The FIELD_ADDR tree // mac - The morphing context, used to elide adding null checks // // Return Value: // The fully morphed "tree". // -GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) +GenTree* Compiler::fgMorphFieldAddr(GenTree* tree, MorphAddrContext* mac) { - assert(tree->OperIs(GT_FIELD, GT_FIELD_ADDR)); + assert(tree->OperIs(GT_FIELD_ADDR)); - GenTreeField* fieldNode = tree->AsField(); - GenTree* objRef = fieldNode->GetFldObj(); - bool isAddr = tree->OperIs(GT_FIELD_ADDR); - - if (tree->OperIs(GT_FIELD)) - { - noway_assert(((objRef != nullptr) && objRef->OperIs(GT_LCL_ADDR)) || ((tree->gtFlags & GTF_GLOB_REF) != 0)); - } + GenTreeFieldAddr* fieldNode = tree->AsFieldAddr(); + GenTree* objRef = fieldNode->GetFldObj(); + bool isAddr = ((tree->gtFlags & GTF_FLD_DEREFERENCED) == 0); if (fieldNode->IsInstance()) { @@ -5063,20 +5032,19 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) DBEXEC(result == fieldNode, result->gtDebugFlags &= ~GTF_DEBUG_NODE_MORPHED); } - JITDUMP("\nFinal value of Compiler::fgMorphField after morphing:\n"); + JITDUMP("\nFinal value of Compiler::fgMorphFieldAddr after morphing:\n"); DISPTREE(result); return result; } //------------------------------------------------------------------------ -// fgMorphExpandInstanceField: Expand an instance field reference. +// fgMorphExpandInstanceField: Expand an instance field address. // -// Expands the field node into explicit additions and indirections, adding -// explicit null checks if necessary. +// Expands the field node into explicit additions and nullchecks. // // Arguments: -// tree - The FIELD/FIELD_ADDR tree +// tree - The FIELD_ADDR tree // mac - The morphing context, used to elide adding null checks // // Return Value: @@ -5084,31 +5052,26 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) // GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* mac) { - assert(tree->OperIs(GT_FIELD, GT_FIELD_ADDR) && tree->AsField()->IsInstance()); + assert(tree->OperIs(GT_FIELD_ADDR) && tree->AsFieldAddr()->IsInstance()); - GenTree* objRef = tree->AsField()->GetFldObj(); - CORINFO_FIELD_HANDLE fieldHandle = tree->AsField()->gtFldHnd; - unsigned fieldOffset = tree->AsField()->gtFldOffset; + GenTree* objRef = tree->AsFieldAddr()->GetFldObj(); + CORINFO_FIELD_HANDLE fieldHandle = tree->AsFieldAddr()->gtFldHnd; + unsigned fieldOffset = tree->AsFieldAddr()->gtFldOffset; noway_assert(varTypeIsI(genActualType(objRef))); /* Now we have a tree like this: +--------------------+ - | GT_FIELD[_ADDR] | tree + | GT_FIELD_ADDR | tree +----------+---------+ | +--------------+-------------+ - |tree->AsField()->GetFldObj()| + | tree->GetFldObj() | +--------------+-------------+ We want to make it like this (when fldOffset is <= MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT): - +--------------------+ - | GT_IND/GT_BLK | tree (for FIELD) - +---------+----------+ - | - | +---------+----------+ | GT_ADD | addr +---------+----------+ @@ -5164,15 +5127,13 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m if (fgAddrCouldBeNull(objRef)) { - if (tree->OperIs(GT_FIELD)) - { - addExplicitNullCheck = fgIsBigOffset(fieldOffset); - } - else + // A non-null context here implies our [+ some offset] parent is an indirection, one that + // will implicitly null-check the produced address. + addExplicitNullCheck = (mac == nullptr) || fgIsBigOffset(mac->m_totalOffset + fieldOffset); + + if (!addExplicitNullCheck) { - // A non-null context here implies our [+ some offset] parent is an indirection, one that - // will implicitly null-check the produced address. - addExplicitNullCheck = (mac == nullptr) || fgIsBigOffset(mac->m_totalOffset + fieldOffset); + mac->m_used = true; } } @@ -5187,7 +5148,7 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m if (!objRef->OperIs(GT_LCL_VAR) || lvaIsLocalImplicitlyAccessedByRef(objRef->AsLclVar()->GetLclNum())) { - lclNum = fgGetFieldMorphingTemp(tree->AsField()); + lclNum = fgGetFieldMorphingTemp(tree->AsFieldAddr()); // Create the "asg" node asg = gtNewTempAssign(lclNum, objRef); @@ -5224,12 +5185,12 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m } #ifdef FEATURE_READYTORUN - if (tree->AsField()->gtFieldLookup.addr != nullptr) + if (tree->AsFieldAddr()->gtFieldLookup.addr != nullptr) { GenTree* offsetNode = nullptr; - if (tree->AsField()->gtFieldLookup.accessType == IAT_PVALUE) + if (tree->AsFieldAddr()->gtFieldLookup.accessType == IAT_PVALUE) { - offsetNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)tree->AsField()->gtFieldLookup.addr, + offsetNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)tree->AsFieldAddr()->gtFieldLookup.addr, GTF_ICON_CONST_PTR, true); #ifdef DEBUG offsetNode->gtGetOp1()->AsIntCon()->gtTargetHandle = (size_t)fieldHandle; @@ -5246,7 +5207,7 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m // We only need to attach the field offset information for class fields. FieldSeq* fieldSeq = nullptr; - if ((objRefType == TYP_REF) && !tree->AsField()->gtFldMayOverlap) + if ((objRefType == TYP_REF) && !tree->AsFieldAddr()->gtFldMayOverlap) { fieldSeq = GetFieldSeqStore()->Create(fieldHandle, fieldOffset, FieldSeq::FieldKind::Instance); } @@ -5262,35 +5223,12 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m { // Create the "comma2" tree. addr = gtNewOperNode(GT_COMMA, addr->TypeGet(), comma, addr); - } - if (tree->OperIs(GT_FIELD)) - { - if (tree->TypeIs(TYP_STRUCT)) - { - ClassLayout* layout = tree->GetLayout(this); - tree->SetOper(GT_BLK); - tree->AsBlk()->Initialize(layout); - } - else - { - tree->SetOper(GT_IND); - } - - tree->AsIndir()->SetAddr(addr); - } - else // Otherwise, we have a FIELD_ADDR. - { - tree = addr; - } - - if (addExplicitNullCheck) - { JITDUMP("After adding explicit null check:\n"); - DISPTREE(tree); + DISPTREE(addr); } - return tree; + return addr; } //------------------------------------------------------------------------ @@ -5308,11 +5246,10 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m // GenTree* Compiler::fgMorphExpandTlsFieldAddr(GenTree* tree) { - // Note we do not support "FIELD"s for TLS statics, for simplicity. - assert(tree->OperIs(GT_FIELD_ADDR) && tree->AsField()->IsTlsStatic()); + assert(tree->OperIs(GT_FIELD_ADDR) && tree->AsFieldAddr()->IsTlsStatic()); - CORINFO_FIELD_HANDLE fieldHandle = tree->AsField()->gtFldHnd; - int fieldOffset = tree->AsField()->gtFldOffset; + CORINFO_FIELD_HANDLE fieldHandle = tree->AsFieldAddr()->gtFldHnd; + int fieldOffset = tree->AsFieldAddr()->gtFldOffset; // Thread Local Storage static field reference // @@ -5367,13 +5304,6 @@ GenTree* Compiler::fgMorphExpandTlsFieldAddr(GenTree* tree) // Mark this ICON as a TLS_HDL, codegen will use FS:[cns] GenTree* tlsRef = gtNewIconHandleNode(WIN32_TLS_SLOTS, GTF_ICON_TLS_HDL); - // Translate GTF_FLD_INITCLASS to GTF_ICON_INITCLASS - if ((tree->gtFlags & GTF_FLD_INITCLASS) != 0) - { - tree->gtFlags &= ~GTF_FLD_INITCLASS; - tlsRef->gtFlags |= GTF_ICON_INITCLASS; - } - tlsRef = gtNewIndir(TYP_I_IMPL, tlsRef, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); if (dllRef != nullptr) @@ -5383,10 +5313,10 @@ GenTree* Compiler::fgMorphExpandTlsFieldAddr(GenTree* tree) } // indirect to have tlsRef point at the base of the DLLs Thread Local Storage. - tlsRef = gtNewOperNode(GT_IND, TYP_I_IMPL, tlsRef); + tlsRef = gtNewIndir(TYP_I_IMPL, tlsRef); // Add the TLS static field offset to the address. - assert(!tree->AsField()->gtFldMayOverlap); + assert(!tree->AsFieldAddr()->gtFldMayOverlap); FieldSeq* fieldSeq = GetFieldSeqStore()->Create(fieldHandle, fieldOffset, FieldSeq::FieldKind::SimpleStatic); GenTree* offsetNode = gtNewIconNode(fieldOffset, fieldSeq); @@ -7086,9 +7016,7 @@ GenTree* Compiler::getRuntimeLookupTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, if (i != 0) { - result = gtNewOperNode(GT_IND, TYP_I_IMPL, result); - result->gtFlags |= GTF_IND_NONFAULTING; - result->gtFlags |= GTF_IND_INVARIANT; + result = gtNewIndir(TYP_I_IMPL, result, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); } if ((i == 1 && pRuntimeLookup->indirectFirstOffset) || (i == 2 && pRuntimeLookup->indirectSecondOffset)) @@ -7105,8 +7033,7 @@ GenTree* Compiler::getRuntimeLookupTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, assert(!pRuntimeLookup->testForNull); if (pRuntimeLookup->indirections > 0) { - result = gtNewOperNode(GT_IND, TYP_I_IMPL, result); - result->gtFlags |= GTF_IND_NONFAULTING; + result = gtNewIndir(TYP_I_IMPL, result, GTF_IND_NONFAULTING); } // Produces GT_COMMA(stmt1, GT_COMMA(stmt2, ... GT_COMMA(stmtN, result))) @@ -7942,32 +7869,28 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) // Either or both of the array and index arguments may have been spilled to temps by `fgMorphArgs`. Copy // the spill trees as well if necessary. - GenTreeOp* argSetup = nullptr; + GenTree* argSetup = nullptr; for (CallArg& arg : call->gtArgs.EarlyArgs()) { - GenTree* const argNode = arg.GetEarlyNode(); - if (argNode->OperGet() != GT_ASG) + if (arg.GetLateNode() == nullptr) { continue; } - assert(argNode != arr); - assert(argNode != index); + GenTree* const setupArgNode = arg.GetEarlyNode(); + assert((setupArgNode != arr) && (setupArgNode != index)); - GenTree* op1 = argSetup; - if (op1 == nullptr) + if (argSetup == nullptr) { - op1 = gtNewNothingNode(); -#if DEBUG - op1->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED; -#endif // DEBUG + argSetup = setupArgNode; } - - argSetup = new (this, GT_COMMA) GenTreeOp(GT_COMMA, TYP_VOID, op1, argNode); - + else + { + argSetup = new (this, GT_COMMA) GenTreeOp(GT_COMMA, TYP_VOID, argSetup, setupArgNode); #if DEBUG - argSetup->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED; + argSetup->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED; #endif // DEBUG + } } #ifdef DEBUG @@ -7981,11 +7904,18 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) fgWalkTreePost(&value, resetMorphedFlag); #endif // DEBUG - GenTree* const arrIndexAddr = gtNewArrayIndexAddr(arr, index, TYP_REF, NO_CLASS_HANDLE); - GenTree* const arrIndex = gtNewIndexIndir(arrIndexAddr->AsIndexAddr()); - GenTree* const arrStore = gtNewAssignNode(arrIndex, value); + GenTree* indexAddr = gtNewArrayIndexAddr(arr, index, TYP_REF, NO_CLASS_HANDLE); + GenTree* store; + if (compAssignmentRationalized) + { + store = gtNewStoreIndNode(TYP_REF, indexAddr, value); + } + else + { + store = gtNewAssignNode(gtNewIndir(TYP_REF, indexAddr), value); + } - GenTree* result = fgMorphTree(arrStore); + GenTree* result = fgMorphTree(store); if (argSetup != nullptr) { result = new (this, GT_COMMA) GenTreeOp(GT_COMMA, TYP_VOID, argSetup, result); @@ -8056,10 +7986,9 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call) &isRelative); // Dereference the this pointer to obtain the method table, it is called vtab below - GenTree* vtab; assert(VPTR_OFFS == 0); // We have to add this value to the thisPtr to get the methodTable - vtab = gtNewOperNode(GT_IND, TYP_I_IMPL, thisPtr); - vtab->gtFlags |= GTF_IND_INVARIANT; + GenTree* vtab = gtNewIndir(TYP_I_IMPL, thisPtr, GTF_IND_INVARIANT); + vtab->gtFlags &= ~GTF_EXCEPT; // TODO-Cleanup: delete this zero-diff quirk. // Get the appropriate vtable chunk if (vtabOffsOfIndirection != CORINFO_VIRTUALCALL_NO_CHUNK) @@ -8094,9 +8023,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call) // [tmp + vtabOffsOfIndirection] GenTree* tmpTree1 = gtNewOperNode(GT_ADD, TYP_I_IMPL, gtNewLclvNode(varNum1, TYP_I_IMPL), gtNewIconNode(vtabOffsOfIndirection, TYP_I_IMPL)); - tmpTree1 = gtNewOperNode(GT_IND, TYP_I_IMPL, tmpTree1); - tmpTree1->gtFlags |= GTF_IND_NONFAULTING; - tmpTree1->gtFlags |= GTF_IND_INVARIANT; + tmpTree1 = gtNewIndir(TYP_I_IMPL, tmpTree1, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); // var1 + vtabOffsOfIndirection + vtabOffsAfterIndirection GenTree* tmpTree2 = @@ -8108,8 +8035,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call) GenTree* asgVar2 = gtNewTempAssign(varNum2, tmpTree2); // var2 = // This last indirection is not invariant, but is non-faulting - result = gtNewOperNode(GT_IND, TYP_I_IMPL, gtNewLclvNode(varNum2, TYP_I_IMPL)); // [var2] - result->gtFlags |= GTF_IND_NONFAULTING; + result = gtNewIndir(TYP_I_IMPL, gtNewLclvNode(varNum2, TYP_I_IMPL), GTF_IND_NONFAULTING); // [var2] result = gtNewOperNode(GT_ADD, TYP_I_IMPL, result, gtNewLclvNode(varNum2, TYP_I_IMPL)); // [var2] + var2 @@ -8121,9 +8047,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call) { // result = [vtab + vtabOffsOfIndirection] result = gtNewOperNode(GT_ADD, TYP_I_IMPL, vtab, gtNewIconNode(vtabOffsOfIndirection, TYP_I_IMPL)); - result = gtNewOperNode(GT_IND, TYP_I_IMPL, result); - result->gtFlags |= GTF_IND_NONFAULTING; - result->gtFlags |= GTF_IND_INVARIANT; + result = gtNewIndir(TYP_I_IMPL, result, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); } } else @@ -8138,8 +8062,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call) // result = [result + vtabOffsAfterIndirection] result = gtNewOperNode(GT_ADD, TYP_I_IMPL, result, gtNewIconNode(vtabOffsAfterIndirection, TYP_I_IMPL)); // This last indirection is not invariant, but is non-faulting - result = gtNewOperNode(GT_IND, TYP_I_IMPL, result); - result->gtFlags |= GTF_IND_NONFAULTING; + result = gtNewIndir(TYP_I_IMPL, result, GTF_IND_NONFAULTING); } return result; @@ -8258,11 +8181,7 @@ GenTree* Compiler::fgMorphLeaf(GenTree* tree) indNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)addrInfo.handle, GTF_ICON_CONST_PTR, true); // Add the second indirection - indNode = gtNewOperNode(GT_IND, TYP_I_IMPL, indNode); - // This indirection won't cause an exception. - indNode->gtFlags |= GTF_IND_NONFAULTING; - // This indirection also is invariant. - indNode->gtFlags |= GTF_IND_INVARIANT; + indNode = gtNewIndir(TYP_I_IMPL, indNode, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); break; case IAT_PVALUE: @@ -8347,9 +8266,15 @@ GenTree* Compiler::getSIMDStructFromField(GenTree* tree, unsigned* simdSizeOut, bool ignoreUsedInSIMDIntrinsic /*false*/) { - if (tree->OperIs(GT_FIELD) && tree->AsField()->IsInstance()) + if (tree->OperIs(GT_IND)) { - GenTree* objRef = tree->AsField()->GetFldObj(); + GenTree* addr = tree->AsIndir()->Addr(); + if (!addr->OperIs(GT_FIELD_ADDR) || !addr->AsFieldAddr()->IsInstance()) + { + return nullptr; + } + + GenTree* objRef = addr->AsFieldAddr()->GetFldObj(); if (objRef->IsLclVarAddr()) { LclVarDsc* varDsc = lvaGetDesc(objRef->AsLclVarCommon()); @@ -8357,7 +8282,7 @@ GenTree* Compiler::getSIMDStructFromField(GenTree* tree, { CorInfoType simdBaseJitType = varDsc->GetSimdBaseJitType(); var_types simdBaseType = JITtype2varType(simdBaseJitType); - unsigned fieldOffset = tree->AsField()->gtFldOffset; + unsigned fieldOffset = addr->AsFieldAddr()->gtFldOffset; unsigned baseTypeSize = genTypeSize(simdBaseType); // Below condition is convervative. We don't actually need the two types to @@ -8635,9 +8560,8 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA } break; - case GT_FIELD: case GT_FIELD_ADDR: - return fgMorphField(tree, mac); + return fgMorphFieldAddr(tree, mac); case GT_INDEX_ADDR: return fgMorphIndexAddr(tree->AsIndexAddr()); @@ -9096,24 +9020,6 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA break; #endif - case GT_NULLCHECK: - { - op1 = tree->AsUnOp()->gtGetOp1(); - if (op1->IsCall()) - { - GenTreeCall* const call = op1->AsCall(); - if (call->IsHelperCall() && s_helperCallProperties.NonNullReturn(eeGetHelperNum(call->gtCallMethHnd))) - { - JITDUMP("\nNULLCHECK on [%06u] will always succeed\n", dspTreeID(call)); - - // TODO: Can we also remove the call? - // - return fgMorphTree(call); - } - } - } - break; - default: break; } @@ -9129,7 +9035,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA * Process the first operand, if any */ - if (op1) + if (op1 != nullptr) { // If we are entering the "then" part of a Qmark-Colon we must // save the state of the current copy assignment table @@ -9155,7 +9061,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA MorphAddrContext indMac; if (tree->OperIsIndir()) // TODO-CQ: add more operators here (e. g. atomics). { - // Communicate to address morphing that the parent is an indirection. + // Communicate to FIELD_ADDR morphing that the parent is an indirection. mac = &indMac; } // For additions, if we already have a context, keep track of whether all offsets added @@ -9180,6 +9086,13 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA tree->AsOp()->gtOp1 = op1 = fgMorphTree(op1, mac); + if ((mac != nullptr) && mac->m_used && tree->OperIsIndir()) + { + // This context was used to elide an explicit null check on a FIELD_ADDR, with the expectation that + // this indirection will now be responsible for null-checking (implicitly). + tree->gtFlags &= ~GTF_IND_NONFAULTING; + } + // If we are exiting the "then" part of a Qmark-Colon we must // save the state of the current copy assignment table // so that we can merge this state with the "else" part exit @@ -9200,28 +9113,13 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA thenAssertionTab = nullptr; } } - - // Morphing along with folding and inlining may have changed the - // side effect flags, so we have to reset them - // - // NOTE: Don't reset the exception flags on nodes that may throw - - assert(tree->gtOper != GT_CALL); - - if (!tree->OperRequiresCallFlag(this)) - { - tree->gtFlags &= ~GTF_CALL; - } - - // Propagate the new flags - tree->gtFlags |= (op1->gtFlags & GTF_ALL_EFFECT); - } // if (op1) + } /*------------------------------------------------------------------------- * Process the second operand, if any */ - if (op2) + if (op2 != nullptr) { // If we are entering the "else" part of a Qmark-Colon we must // reset the state of the current copy assignment table @@ -9239,10 +9137,6 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA tree->AsOp()->gtOp2 = op2 = fgMorphTree(op2); - /* Propagate the side effect flags from op2 */ - - tree->gtFlags |= (op2->gtFlags & GTF_ALL_EFFECT); - // If we are exiting the "else" part of a Qmark-Colon we must // merge the state of the current copy assignment table with // that of the exit of the "then" part. @@ -9314,58 +9208,23 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA } } } - } // if (op2) + } #ifndef TARGET_64BIT DONE_MORPHING_CHILDREN: #endif // !TARGET_64BIT - if (tree->OperIsIndirOrArrMetaData()) - { - tree->SetIndirExceptionFlags(this); - } - else - { - if (tree->OperMayThrow(this)) - { - // Mark the tree node as potentially throwing an exception - tree->gtFlags |= GTF_EXCEPT; - } - else - { - if (((op1 == nullptr) || ((op1->gtFlags & GTF_EXCEPT) == 0)) && - ((op2 == nullptr) || ((op2->gtFlags & GTF_EXCEPT) == 0))) - { - tree->gtFlags &= ~GTF_EXCEPT; - } - } - } + gtUpdateNodeOperSideEffects(tree); - if (tree->OperRequiresAsgFlag()) + if (op1 != nullptr) { - tree->gtFlags |= GTF_ASG; + tree->AddAllEffectsFlags(op1); } - else + if (op2 != nullptr) { - if (((op1 == nullptr) || ((op1->gtFlags & GTF_ASG) == 0)) && - ((op2 == nullptr) || ((op2->gtFlags & GTF_ASG) == 0))) - { - tree->gtFlags &= ~GTF_ASG; - } + tree->AddAllEffectsFlags(op2); } - if (tree->OperRequiresCallFlag(this)) - { - tree->gtFlags |= GTF_CALL; - } - else - { - if (((op1 == nullptr) || ((op1->gtFlags & GTF_CALL) == 0)) && - ((op2 == nullptr) || ((op2->gtFlags & GTF_CALL) == 0))) - { - tree->gtFlags &= ~GTF_CALL; - } - } /*------------------------------------------------------------------------- * Now do POST-ORDER processing */ @@ -9923,6 +9782,23 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA } break; + case GT_NULLCHECK: + if (opts.OptimizationEnabled() && !optValnumCSE_phase && !tree->OperMayThrow(this)) + { + JITDUMP("\nNULLCHECK on [%06u] will always succeed\n", dspTreeID(op1)); + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + tree = gtUnusedValNode(op1); + INDEBUG(tree->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED); + } + else + { + tree->gtBashToNOP(); + } + return tree; + } + break; + case GT_COLON: if (fgGlobalMorph) { @@ -11754,6 +11630,10 @@ GenTree* Compiler::fgMorphSmpOpOptional(GenTreeOp* tree, bool* optAssertionPropD switch (oper) { case GT_ASG: + case GT_STOREIND: + case GT_STORE_BLK: + case GT_STORE_LCL_VAR: + case GT_STORE_LCL_FLD: // Make sure we're allowed to do this. if (optValnumCSE_phase) { @@ -11781,6 +11661,11 @@ GenTree* Compiler::fgMorphSmpOpOptional(GenTreeOp* tree, bool* optAssertionPropD } } + if (!tree->OperIs(GT_ASG)) + { + break; + } + if (typ == TYP_LONG) { break; @@ -12234,6 +12119,8 @@ GenTree* Compiler::fgMorphModToSubMulDiv(GenTreeOp* tree) result->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED; #endif + optRecordSsaUses(result, compCurBB); + div->CheckDivideByConstOptimized(this); return result; @@ -14945,6 +14832,7 @@ void Compiler::fgMorphLocalField(GenTree* tree, GenTree* parent) tree->ChangeOper(GT_LCL_VAR); assert(tree->AsLclVarCommon()->GetLclNum() == fieldLclIndex); + tree->gtType = fldVarDsc->TypeGet(); if ((parent->gtOper == GT_ASG) && (parent->AsOp()->gtOp1 == tree)) diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp index 9e78a49456991c..31e6d49fd8bc49 100644 --- a/src/coreclr/jit/morphblock.cpp +++ b/src/coreclr/jit/morphblock.cpp @@ -9,7 +9,7 @@ class MorphInitBlockHelper static GenTree* MorphInitBlock(Compiler* comp, GenTree* tree); protected: - MorphInitBlockHelper(Compiler* comp, GenTree* asg, bool initBlock); + MorphInitBlockHelper(Compiler* comp, GenTree* store, bool initBlock); GenTree* Morph(); @@ -36,9 +36,9 @@ class MorphInitBlockHelper Compiler* m_comp; bool m_initBlock; - GenTreeOp* m_asg = nullptr; - GenTree* m_dst = nullptr; - GenTree* m_src = nullptr; + GenTree* m_asg = nullptr; + GenTree* m_dst = nullptr; + GenTree* m_src = nullptr; unsigned m_blockSize = 0; ClassLayout* m_blockLayout = nullptr; @@ -93,21 +93,12 @@ GenTree* MorphInitBlockHelper::MorphInitBlock(Compiler* comp, GenTree* tree) // Notes: // Most class members are initialized via in-class member initializers. // -MorphInitBlockHelper::MorphInitBlockHelper(Compiler* comp, GenTree* asg, bool initBlock = true) +MorphInitBlockHelper::MorphInitBlockHelper(Compiler* comp, GenTree* store, bool initBlock = true) : m_comp(comp), m_initBlock(initBlock) { - assert(asg->OperIs(GT_ASG)); -#if defined(DEBUG) - if (m_initBlock) - { - assert(asg->OperIsInitBlkOp()); - } - else - { - assert(asg->OperIsCopyBlkOp()); - } -#endif // DEBUG - m_asg = asg->AsOp(); + assert(store->OperIs(GT_ASG) || store->OperIsStore()); + assert((m_initBlock == store->OperIsInitBlkOp()) && (!m_initBlock == store->OperIsCopyBlkOp())); + m_asg = store; } //------------------------------------------------------------------------ @@ -160,7 +151,7 @@ GenTree* MorphInitBlockHelper::Morph() commaPool = commaPool->gtNext; assert(comma->OperIs(GT_COMMA)); - comma->gtType = m_result->TypeGet(); + comma->gtType = TYP_VOID; comma->AsOp()->gtOp1 = sideEffects; comma->AsOp()->gtOp2 = m_result; comma->gtFlags = (sideEffects->gtFlags | m_result->gtFlags) & GTF_ALL_EFFECT; @@ -169,7 +160,7 @@ GenTree* MorphInitBlockHelper::Morph() } else { - m_result = m_comp->gtNewOperNode(GT_COMMA, m_result->TypeGet(), sideEffects, m_result); + m_result = m_comp->gtNewOperNode(GT_COMMA, TYP_VOID, sideEffects, m_result); } INDEBUG(m_result->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED); @@ -188,15 +179,16 @@ GenTree* MorphInitBlockHelper::Morph() // void MorphInitBlockHelper::PrepareDst() { - m_dst = m_asg->gtGetOp1(); + m_dst = m_asg->GetStoreDestination(); // Commas cannot be destinations. assert(!m_dst->OperIs(GT_COMMA)); + // TODO-ASG: delete this retyping. if (m_asg->TypeGet() != m_dst->TypeGet()) { - assert(!m_initBlock && "the asg type should be final for an init block."); - JITDUMP("changing type of assignment from %-6s to %-6s\n", varTypeName(m_asg->TypeGet()), + assert(!m_initBlock && "the store type should be final for an init block."); + JITDUMP("changing type of store from %-6s to %-6s\n", varTypeName(m_asg->TypeGet()), varTypeName(m_dst->TypeGet())); m_asg->ChangeType(m_dst->TypeGet()); @@ -218,7 +210,7 @@ void MorphInitBlockHelper::PrepareDst() else { assert(m_dst == m_dst->gtEffectiveVal() && "the commas were skipped in MorphBlock"); - assert(m_dst->OperIs(GT_IND, GT_BLK) && (!m_dst->OperIs(GT_IND) || !m_dst->TypeIs(TYP_STRUCT))); + assert(m_dst->OperIsIndir() && (!m_dst->isIndir() || !m_dst->TypeIs(TYP_STRUCT))); } if (m_dst->TypeIs(TYP_STRUCT)) @@ -290,7 +282,7 @@ void MorphInitBlockHelper::PropagateExpansionAssertions() // void MorphInitBlockHelper::PrepareSrc() { - m_src = m_asg->gtGetOp2(); + m_src = m_asg->Data(); } //------------------------------------------------------------------------ @@ -330,7 +322,8 @@ void MorphInitBlockHelper::MorphStructCases() if (m_dstVarDsc != nullptr) { - if (m_dst->OperIs(GT_LCL_FLD)) + // TODO-ASG: delete the GT_LCL_FLD check on "m_dst". + if (m_dst->OperIs(GT_LCL_FLD, GT_STORE_LCL_FLD)) { m_comp->lvaSetVarDoNotEnregister(m_dstLclNum DEBUGARG(DoNotEnregisterReason::LocalField)); } @@ -454,7 +447,6 @@ void MorphInitBlockHelper::TryInitFieldByField() LclVarDsc* fieldDesc = m_comp->lvaGetDesc(fieldLclNum); var_types fieldType = fieldDesc->TypeGet(); - GenTree* dest = m_comp->gtNewLclvNode(fieldLclNum, fieldType); GenTree* src; switch (fieldType) @@ -470,7 +462,7 @@ void MorphInitBlockHelper::TryInitFieldByField() FALLTHROUGH; case TYP_INT: { - int64_t mask = (int64_t(1) << (genTypeSize(dest->TypeGet()) * 8)) - 1; + int64_t mask = (int64_t(1) << (genTypeSize(fieldType) * 8)) - 1; src = m_comp->gtNewIconNode(static_cast(initPattern & mask)); break; } @@ -508,20 +500,20 @@ void MorphInitBlockHelper::TryInitFieldByField() unreached(); } - GenTree* asg = m_comp->gtNewAssignNode(dest, src); + GenTree* store = m_comp->gtNewTempAssign(fieldLclNum, src); if (m_comp->optLocalAssertionProp) { - m_comp->optAssertionGen(asg); + m_comp->optAssertionGen(store); } if (tree != nullptr) { - tree = m_comp->gtNewOperNode(GT_COMMA, TYP_VOID, tree, asg); + tree = m_comp->gtNewOperNode(GT_COMMA, TYP_VOID, tree, store); } else { - tree = asg; + tree = store; } } @@ -556,14 +548,26 @@ void MorphInitBlockHelper::TryPrimitiveInit() m_src->BashToZeroConst(lclVarType); } - m_dst->ChangeType(m_dstVarDsc->lvNormalizeOnLoad() ? lclVarType : genActualType(lclVarType)); - m_dst->ChangeOper(GT_LCL_VAR); - m_dst->AsLclVar()->SetLclNum(m_dstLclNum); - m_dst->gtFlags |= GTF_VAR_DEF; + if (m_asg->OperIs(GT_ASG)) + { + m_dst->ChangeType(m_dstVarDsc->lvNormalizeOnLoad() ? lclVarType : genActualType(lclVarType)); + m_dst->ChangeOper(GT_LCL_VAR); + m_dst->AsLclVar()->SetLclNum(m_dstLclNum); + m_dst->gtFlags |= GTF_VAR_DEF; + + m_asg->ChangeType(m_dst->TypeGet()); + m_asg->AsOp()->gtOp1 = m_dst; + m_asg->AsOp()->gtOp2 = m_src; + } + else + { + m_asg->ChangeType(m_dstVarDsc->lvNormalizeOnLoad() ? lclVarType : genActualType(lclVarType)); + m_asg->ChangeOper(GT_STORE_LCL_VAR); + m_asg->AsLclVar()->SetLclNum(m_dstLclNum); + m_asg->gtFlags |= GTF_VAR_DEF; + } + INDEBUG(m_dst->AsLclVar()->ResetLclILoffs()); - m_asg->ChangeType(m_dst->TypeGet()); - m_asg->gtOp1 = m_dst; - m_asg->gtOp2 = m_src; m_result = m_asg; m_transformationDecision = BlockTransformation::OneAsgBlock; } @@ -586,41 +590,41 @@ void MorphInitBlockHelper::TryPrimitiveInit() // We have a tree like the following (note that location-valued commas are // illegal, so there cannot be a comma on the left): // -// ASG -// / \. -// IND COMMA -// | / \. -// B C D +// ASG STOREIND +// / \ / \. +// IND COMMA or B COMMA +// | / \ / \. +// B C D C D // -// We'd like downstream code to just see and be expand ASG(IND(B), D). +// We'd like downstream code to just see and expand ASG(IND(B), D). // We will produce: // -// COMMA -// / \. -// ASG COMMA -// / \ / \. -// tmp B C ASG -// / \. -// IND D +// COMMA COMMA +// / \. / \. +// ASG COMMA STORE_LCL_VAR COMMA +// / \ / \. or / / \. +// tmp B C ASG B C STOREIND +// / \. / \. +// IND D tmp D // | // tmp // -// If the ASG has GTF_REVERSE_OPS then we will produce: +// If the store has GTF_REVERSE_OPS then we will produce: // -// COMMA -// / \. -// C ASG -// / \. -// IND D +// COMMA COMMA +// / \. / \. +// C ASG or C STOREIND +// / \. / \. +// IND D B D // | // B // // While keeping the GTF_REVERSE_OPS. // // Note that the final resulting tree is created in the caller since it also -// needs to propagate side effect flags from the decomposed assignment to all -// the created commas. Therefore this function just returns a linked list of -// the side effects to be used for that purpose. +// needs to propagate side effect flags from the decomposed store to all the +// created commas. Therefore this function just returns a linked list of the +// side effects to be used for that purpose. // GenTree* MorphInitBlockHelper::EliminateCommas(GenTree** commaPool) { @@ -638,44 +642,43 @@ GenTree* MorphInitBlockHelper::EliminateCommas(GenTree** commaPool) *commaPool = comma; }; - GenTree* lhs = m_asg->gtGetOp1(); - assert(lhs->OperIsIndir() || lhs->OperIsLocal()); - - GenTree* rhs = m_asg->gtGetOp2(); + GenTree* dst = m_asg->GetStoreDestination(); + GenTree* src = m_asg->Data(); + assert(dst->OperIsIndir() || dst->OperIsLocal()); if (m_asg->IsReverseOp()) { - while (rhs->OperIs(GT_COMMA)) + while (src->OperIs(GT_COMMA)) { - addComma(rhs); - rhs = rhs->gtGetOp2(); + addComma(src); + src = src->gtGetOp2(); } } else { - if (lhs->OperIsIndir() && rhs->OperIs(GT_COMMA)) + if (dst->OperIsIndir() && src->OperIs(GT_COMMA)) { - GenTree* addr = lhs->gtGetOp1(); - if (((addr->gtFlags & GTF_ALL_EFFECT) != 0) || (((rhs->gtFlags & GTF_ASG) != 0) && !addr->IsInvariant())) + GenTree* addr = dst->AsIndir()->Addr(); + if (((addr->gtFlags & GTF_ALL_EFFECT) != 0) || (((src->gtFlags & GTF_ASG) != 0) && !addr->IsInvariant())) { unsigned lhsAddrLclNum = m_comp->lvaGrabTemp(true DEBUGARG("Block morph LHS addr")); addSideEffect(m_comp->gtNewTempAssign(lhsAddrLclNum, addr)); - lhs->AsUnOp()->gtOp1 = m_comp->gtNewLclvNode(lhsAddrLclNum, genActualType(addr)); - m_comp->gtUpdateNodeSideEffects(lhs); + dst->AsUnOp()->gtOp1 = m_comp->gtNewLclvNode(lhsAddrLclNum, genActualType(addr)); + m_comp->gtUpdateNodeSideEffects(dst); } } - while (rhs->OperIs(GT_COMMA)) + while (src->OperIs(GT_COMMA)) { - addComma(rhs); - rhs = rhs->gtGetOp2(); + addComma(src); + src = src->gtGetOp2(); } } if (sideEffects != nullptr) { - m_asg->gtOp2 = rhs; + m_asg->Data() = src; m_comp->gtUpdateNodeSideEffects(m_asg); } @@ -752,7 +755,7 @@ MorphCopyBlockHelper::MorphCopyBlockHelper(Compiler* comp, GenTree* asg) : Morph // void MorphCopyBlockHelper::PrepareSrc() { - m_src = m_asg->gtGetOp2(); + m_src = m_asg->Data(); if (m_src->IsLocal()) { @@ -762,7 +765,7 @@ void MorphCopyBlockHelper::PrepareSrc() m_srcVarDsc = m_comp->lvaGetDesc(m_srcLclNum); } - // Verify that the types on the LHS and RHS match. + // Verify that the types of the store and data match. assert(m_dst->TypeGet() == m_src->TypeGet()); if (m_dst->TypeIs(TYP_STRUCT)) { @@ -777,7 +780,7 @@ void MorphCopyBlockHelper::TrySpecialCases() { if (m_src->IsMultiRegNode()) { - assert(m_dst->OperIs(GT_LCL_VAR)); + assert(m_dst->OperIsScalarLocal()); m_dstVarDsc->lvIsMultiRegRet = true; @@ -785,7 +788,7 @@ void MorphCopyBlockHelper::TrySpecialCases() m_transformationDecision = BlockTransformation::SkipMultiRegSrc; m_result = m_asg; } - else if (m_src->IsCall() && m_dst->OperIs(GT_LCL_VAR) && m_dstVarDsc->CanBeReplacedWithItsField(m_comp)) + else if (m_src->IsCall() && m_dst->OperIsScalarLocal() && m_dstVarDsc->CanBeReplacedWithItsField(m_comp)) { JITDUMP("Not morphing a single reg call return\n"); m_transformationDecision = BlockTransformation::SkipSingleRegCallSrc; @@ -863,7 +866,8 @@ void MorphCopyBlockHelper::MorphStructCases() // If either src or dest is a reg-sized non-field-addressed struct, keep the copyBlock; // this will avoid having to DNER the enregisterable local when creating LCL_FLD nodes. - if ((m_dst->OperIs(GT_LCL_VAR) && m_dstVarDsc->lvRegStruct) || + // TODO-ASG: delete the GT_LCL_VAR check on "m_dst". + if ((m_dst->OperIs(GT_STORE_LCL_VAR, GT_LCL_VAR) && m_dstVarDsc->lvRegStruct) || (m_src->OperIs(GT_LCL_VAR) && m_srcVarDsc->lvRegStruct)) { requiresCopyBlock = true; @@ -917,14 +921,11 @@ void MorphCopyBlockHelper::MorphStructCases() // A struct with 8 bool fields will require 8 moves instead of one if we do this transformation. // A simple heuristic when field by field copy is preferred: // - if fields can be enregistered; - // - if the struct has GCPtrs (block copy would be done via helper that is expensive); // - if the struct has only one field. bool dstFldIsProfitable = - ((m_dstVarDsc != nullptr) && - (!m_dstVarDsc->lvDoNotEnregister || m_dstVarDsc->HasGCPtr() || (m_dstVarDsc->lvFieldCnt == 1))); + ((m_dstVarDsc != nullptr) && (!m_dstVarDsc->lvDoNotEnregister || (m_dstVarDsc->lvFieldCnt == 1))); bool srcFldIsProfitable = - ((m_srcVarDsc != nullptr) && - (!m_srcVarDsc->lvDoNotEnregister || m_srcVarDsc->HasGCPtr() || (m_srcVarDsc->lvFieldCnt == 1))); + ((m_srcVarDsc != nullptr) && (!m_srcVarDsc->lvDoNotEnregister || (m_srcVarDsc->lvFieldCnt == 1))); // Are both dest and src promoted structs? if (m_dstDoFldAsg && m_srcDoFldAsg && (dstFldIsProfitable || srcFldIsProfitable)) { @@ -1065,7 +1066,8 @@ void MorphCopyBlockHelper::MorphStructCases() // if (!m_dstDoFldAsg && (m_dstVarDsc != nullptr) && !m_dstSingleLclVarAsg) { - if (m_dst->OperIs(GT_LCL_FLD)) + // TODO-ASG: delete the GT_LCL_FLD check on "m_dst". + if (m_dst->OperIs(GT_LCL_FLD, GT_STORE_LCL_FLD)) { m_comp->lvaSetVarDoNotEnregister(m_dstLclNum DEBUGARG(DoNotEnregisterReason::LocalField)); } @@ -1107,10 +1109,10 @@ void MorphCopyBlockHelper::TryPrimitiveCopy() } var_types asgType = TYP_UNDEF; - assert((m_src == m_src->gtEffectiveVal()) && (m_dst == m_dst->gtEffectiveVal())); // Can we use the LHS local directly? - if (m_dst->OperIs(GT_LCL_FLD)) + // TODO-ASG: delete the GT_LCL_FLD check on "m_dst". + if (m_dst->OperIs(GT_LCL_FLD, GT_STORE_LCL_FLD)) { if (m_blockSize == genTypeSize(m_dstVarDsc)) { @@ -1139,30 +1141,31 @@ void MorphCopyBlockHelper::TryPrimitiveCopy() return; } - auto doRetypeNode = [asgType](GenTree* op, LclVarDsc* varDsc) { + auto doRetypeNode = [asgType](GenTree* op, LclVarDsc* varDsc, bool isUse) { if (op->OperIsIndir()) { - op->SetOper(GT_IND); + op->SetOper(isUse ? GT_IND : GT_STOREIND); op->ChangeType(asgType); } else if (varDsc->TypeGet() == asgType) { - op->SetOper(GT_LCL_VAR); + op->SetOper(isUse ? GT_LCL_VAR : GT_STORE_LCL_VAR); op->ChangeType(varDsc->lvNormalizeOnLoad() ? varDsc->TypeGet() : genActualType(varDsc)); op->gtFlags &= ~GTF_VAR_USEASG; } else { - if (op->OperIs(GT_LCL_VAR)) + if (op->OperIsScalarLocal()) { - op->SetOper(GT_LCL_FLD); + op->SetOper(isUse ? GT_LCL_FLD : GT_STORE_LCL_FLD); } op->ChangeType(asgType); } }; - doRetypeNode(m_dst, m_dstVarDsc); - doRetypeNode(m_src, m_srcVarDsc); + doRetypeNode(m_dst, m_dstVarDsc, /* isUse */ m_asg->OperIs(GT_ASG)); + doRetypeNode(m_src, m_srcVarDsc, /* isUse */ true); + // TODO-ASG: delete. m_asg->ChangeType(asgType); m_result = m_asg; @@ -1184,7 +1187,7 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField() GenTree* addrSpill = nullptr; unsigned addrSpillTemp = BAD_VAR_NUM; - GenTree* addrSpillAsg = nullptr; + GenTree* addrSpillStore = nullptr; unsigned fieldCnt = 0; @@ -1290,113 +1293,20 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField() addrSpillTemp = m_comp->lvaGrabTemp(true DEBUGARG("BlockOp address local")); LclVarDsc* addrSpillDsc = m_comp->lvaGetDesc(addrSpillTemp); - addrSpillDsc->lvType = TYP_BYREF; - - GenTreeLclVar* addrSpillNode = m_comp->gtNewLclvNode(addrSpillTemp, TYP_BYREF); - addrSpillAsg = m_comp->gtNewAssignNode(addrSpillNode, addrSpill); + addrSpillDsc->lvType = TYP_BYREF; // TODO-ASG: zero-diff quirk, delete. + addrSpillStore = m_comp->gtNewTempAssign(addrSpillTemp, addrSpill); } // We may have allocated a temp above, and that may have caused the lvaTable to be expanded. // So, beyond this point we cannot rely on the old values of 'm_srcVarDsc' and 'm_dstVarDsc'. - + bool useAsg = m_asg->OperIs(GT_ASG); for (unsigned i = 0; i < fieldCnt; ++i) { - GenTree* dstFld; - if (m_dstDoFldAsg) + if (m_dstDoFldAsg && m_comp->fgGlobalMorph && m_dstLclNode->IsLastUse(i)) { - noway_assert((m_dstLclNum != BAD_VAR_NUM) && (dstAddr == nullptr)); - - unsigned dstFieldLclNum = m_comp->lvaGetDesc(m_dstLclNum)->lvFieldLclStart + i; - if (m_comp->fgGlobalMorph && m_dstLclNode->IsLastUse(i)) - { - JITDUMP("Field-by-field copy skipping write to dead field V%02u\n", dstFieldLclNum); - continue; - } - - dstFld = m_comp->gtNewLclvNode(dstFieldLclNum, m_comp->lvaGetDesc(dstFieldLclNum)->TypeGet()); - - // If it had been labeled a "USEASG", assignments to the individual promoted fields are not. - dstFld->gtFlags |= m_dstLclNode->gtFlags & ~(GTF_NODE_MASK | GTF_VAR_USEASG | GTF_VAR_DEATH_MASK); - - // Don't CSE the lhs of an assignment. - dstFld->gtFlags |= GTF_DONT_CSE; - } - else - { - noway_assert(m_srcDoFldAsg); - - if (m_dstSingleLclVarAsg) - { - noway_assert(fieldCnt == 1); - noway_assert(m_dstVarDsc != nullptr); - noway_assert(addrSpill == nullptr); - - dstFld = m_comp->gtNewLclvNode(m_dstLclNum, m_dstVarDsc->TypeGet()); - } - else - { - GenTree* dstAddrClone = nullptr; - if (!m_dstUseLclFld) - { - // Need address of the destination. - if (addrSpill) - { - assert(addrSpillTemp != BAD_VAR_NUM); - dstAddrClone = m_comp->gtNewLclvNode(addrSpillTemp, TYP_BYREF); - } - else - { - if (result == nullptr) - { - // Reuse the original "dstAddr" tree for the first field. - dstAddrClone = dstAddr; - } - else - { - // We can't clone multiple copies of a tree with persistent side effects - noway_assert((dstAddr->gtFlags & GTF_PERSISTENT_SIDE_EFFECTS) == 0); - - dstAddrClone = m_comp->gtCloneExpr(dstAddr); - noway_assert(dstAddrClone != nullptr); - - JITDUMP("dstAddr - Multiple Fields Clone created:\n"); - DISPTREE(dstAddrClone); - - // Morph the newly created tree - dstAddrClone = m_comp->fgMorphTree(dstAddrClone); - } - } - } - - LclVarDsc* srcVarDsc = m_comp->lvaGetDesc(m_srcLclNum); - unsigned srcFieldLclNum = srcVarDsc->lvFieldLclStart + i; - LclVarDsc* srcFieldVarDsc = m_comp->lvaGetDesc(srcFieldLclNum); - unsigned srcFieldOffset = srcFieldVarDsc->lvFldOffset; - var_types srcType = srcFieldVarDsc->TypeGet(); - - if (!m_dstUseLclFld) - { - if (srcFieldOffset != 0) - { - GenTree* fieldOffsetNode = m_comp->gtNewIconNode(srcFieldVarDsc->lvFldOffset, TYP_I_IMPL); - dstAddrClone = m_comp->gtNewOperNode(GT_ADD, TYP_BYREF, dstAddrClone, fieldOffsetNode); - } - - dstFld = m_comp->gtNewIndir(srcType, dstAddrClone); - } - else - { - assert(dstAddrClone == nullptr); - - // If the dst was a struct type field "B" in a struct "A" then we add - // add offset of ("B" in "A") + current offset in "B". - unsigned totalOffset = m_dstLclOffset + srcFieldOffset; - dstFld = m_comp->gtNewLclFldNode(m_dstLclNum, srcType, totalOffset); - - // TODO-1stClassStructs: remove this and implement storing to a field in a struct in a reg. - m_comp->lvaSetVarDoNotEnregister(m_dstLclNum DEBUGARG(DoNotEnregisterReason::LocalField)); - } - } + INDEBUG(unsigned dstFieldLclNum = m_comp->lvaGetDesc(m_dstLclNum)->lvFieldLclStart + i); + JITDUMP("Field-by-field copy skipping write to dead field V%02u\n", dstFieldLclNum); + continue; } GenTree* srcFld = nullptr; @@ -1509,27 +1419,147 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField() } } assert(srcFld != nullptr); + + GenTree* dstFld; + if (m_dstDoFldAsg) + { + noway_assert((m_dstLclNum != BAD_VAR_NUM) && (dstAddr == nullptr)); + + unsigned dstFieldLclNum = m_comp->lvaGetDesc(m_dstLclNum)->lvFieldLclStart + i; + if (useAsg) + { + dstFld = m_comp->gtNewLclvNode(dstFieldLclNum, m_comp->lvaGetDesc(dstFieldLclNum)->TypeGet()); + + // If it had been labeled a "USEASG", assignments to the individual promoted fields are not. + dstFld->gtFlags |= m_dstLclNode->gtFlags & ~(GTF_NODE_MASK | GTF_VAR_USEASG | GTF_VAR_DEATH_MASK); + + // Don't CSE the lhs of an assignment. + dstFld->gtFlags |= GTF_DONT_CSE; + } + else + { + dstFld = m_comp->gtNewStoreLclVarNode(dstFieldLclNum, srcFld); + } + } + else + { + noway_assert(m_srcDoFldAsg); + + if (m_dstSingleLclVarAsg) + { + noway_assert(fieldCnt == 1); + noway_assert(m_dstVarDsc != nullptr); + noway_assert(addrSpill == nullptr); + + if (useAsg) + { + dstFld = m_comp->gtNewLclvNode(m_dstLclNum, m_dstVarDsc->TypeGet()); + } + else + { + dstFld = m_comp->gtNewStoreLclVarNode(m_dstLclNum, srcFld); + } + } + else + { + GenTree* dstAddrClone = nullptr; + if (!m_dstUseLclFld) + { + // Need address of the destination. + if (addrSpill) + { + assert(addrSpillTemp != BAD_VAR_NUM); + dstAddrClone = m_comp->gtNewLclvNode(addrSpillTemp, TYP_BYREF); + } + else + { + if (result == nullptr) + { + // Reuse the original "dstAddr" tree for the first field. + dstAddrClone = dstAddr; + } + else + { + // We can't clone multiple copies of a tree with persistent side effects + noway_assert((dstAddr->gtFlags & GTF_PERSISTENT_SIDE_EFFECTS) == 0); + + dstAddrClone = m_comp->gtCloneExpr(dstAddr); + noway_assert(dstAddrClone != nullptr); + + JITDUMP("dstAddr - Multiple Fields Clone created:\n"); + DISPTREE(dstAddrClone); + + // Morph the newly created tree + dstAddrClone = m_comp->fgMorphTree(dstAddrClone); + } + } + } + + LclVarDsc* srcVarDsc = m_comp->lvaGetDesc(m_srcLclNum); + unsigned srcFieldLclNum = srcVarDsc->lvFieldLclStart + i; + LclVarDsc* srcFieldVarDsc = m_comp->lvaGetDesc(srcFieldLclNum); + unsigned srcFieldOffset = srcFieldVarDsc->lvFldOffset; + var_types srcType = srcFieldVarDsc->TypeGet(); + + if (!m_dstUseLclFld) + { + if (srcFieldOffset != 0) + { + GenTree* fieldOffsetNode = m_comp->gtNewIconNode(srcFieldOffset, TYP_I_IMPL); + dstAddrClone = m_comp->gtNewOperNode(GT_ADD, TYP_BYREF, dstAddrClone, fieldOffsetNode); + } + + if (useAsg) + { + dstFld = m_comp->gtNewIndir(srcType, dstAddrClone); + } + else + { + dstFld = m_comp->gtNewStoreIndNode(srcType, dstAddrClone, srcFld); + } + } + else + { + assert(dstAddrClone == nullptr); + + // If the dst was a struct type field "B" in a struct "A" then we add + // add offset of ("B" in "A") + current offset in "B". + unsigned totalOffset = m_dstLclOffset + srcFieldOffset; + if (useAsg) + { + dstFld = m_comp->gtNewLclFldNode(m_dstLclNum, srcType, totalOffset); + } + else + { + dstFld = m_comp->gtNewStoreLclFldNode(m_dstLclNum, srcType, totalOffset, srcFld); + } + + // TODO-1stClassStructs: remove this and implement storing to a field in a struct in a reg. + m_comp->lvaSetVarDoNotEnregister(m_dstLclNum DEBUGARG(DoNotEnregisterReason::LocalField)); + } + } + } noway_assert(dstFld->TypeGet() == srcFld->TypeGet()); - GenTreeOp* asgOneFld = m_comp->gtNewAssignNode(dstFld, srcFld); + GenTree* storeOneFld = useAsg ? m_comp->gtNewAssignNode(dstFld, srcFld) : dstFld; if (m_comp->optLocalAssertionProp) { - m_comp->optAssertionGen(asgOneFld); + m_comp->optAssertionGen(storeOneFld); } - if (addrSpillAsg != nullptr) + if (addrSpillStore != nullptr) { - result = m_comp->gtNewOperNode(GT_COMMA, TYP_VOID, addrSpillAsg, asgOneFld)->AsOp(); - addrSpillAsg = nullptr; + result = m_comp->gtNewOperNode(GT_COMMA, TYP_VOID, addrSpillStore, storeOneFld); + addrSpillStore = nullptr; } else if (result != nullptr) { - result = m_comp->gtNewOperNode(GT_COMMA, TYP_VOID, result, asgOneFld)->AsOp(); + result = m_comp->gtNewOperNode(GT_COMMA, TYP_VOID, result, storeOneFld); } else { - result = asgOneFld; + result = storeOneFld; } } @@ -1619,10 +1649,7 @@ GenTree* Compiler::fgMorphStoreDynBlock(GenTreeStoreDynBlk* tree) if ((size != 0) && FitsIn(size)) { ClassLayout* layout = typGetBlkLayout(static_cast(size)); - GenTree* dst = gtNewLoadValueNode(layout, tree->Addr(), tree->gtFlags & GTF_IND_FLAGS); - dst->gtFlags |= GTF_GLOB_REF; - - GenTree* src = tree->Data(); + GenTree* src = tree->Data(); if (src->OperIs(GT_IND)) { assert(src->TypeIs(TYP_STRUCT)); @@ -1630,15 +1657,25 @@ GenTree* Compiler::fgMorphStoreDynBlock(GenTreeStoreDynBlk* tree) src->AsBlk()->Initialize(layout); } - GenTree* asg = gtNewAssignNode(dst, src); - asg->AddAllEffectsFlags(tree); - INDEBUG(asg->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED); + GenTree* store; + if (compAssignmentRationalized) + { + store = gtNewStoreValueNode(layout, tree->Addr(), src, tree->gtFlags & GTF_IND_FLAGS); + } + else + { + GenTree* dst = gtNewLoadValueNode(layout, tree->Addr(), tree->gtFlags & GTF_IND_FLAGS); + dst->gtFlags |= GTF_GLOB_REF; + store = gtNewAssignNode(dst, src); + } + store->AddAllEffectsFlags(tree); + INDEBUG(store->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED); - fgAssignSetVarDef(asg); + fgAssignSetVarDef(store); JITDUMP("MorphStoreDynBlock: transformed STORE_DYN_BLK into ASG(BLK, Data())\n"); - return tree->OperIsCopyBlkOp() ? fgMorphCopyBlock(asg) : fgMorphInitBlock(asg); + return tree->OperIsCopyBlkOp() ? fgMorphCopyBlock(store) : fgMorphInitBlock(store); } } diff --git a/src/coreclr/jit/objectalloc.cpp b/src/coreclr/jit/objectalloc.cpp index e9c6df3e2410a2..80ef539f272c7c 100644 --- a/src/coreclr/jit/objectalloc.cpp +++ b/src/coreclr/jit/objectalloc.cpp @@ -664,7 +664,6 @@ bool ObjectAllocator::CanLclVarEscapeViaParentStack(ArrayStack* parent keepChecking = true; break; - case GT_FIELD: case GT_IND: // Address of the field/ind is not taken so the local doesn't escape. canLclVarEscapeViaParentStack = false; @@ -760,7 +759,6 @@ void ObjectAllocator::UpdateAncestorTypes(GenTree* tree, ArrayStack* p keepChecking = true; break; - case GT_FIELD: case GT_IND: { // The new target could be *not* on the heap. diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 58f5c549a8b505..eb84ce38a50a1e 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -4875,22 +4875,28 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) } // Get hold of the jump target - BasicBlock* bTest = block->bbJumpDest; + BasicBlock* const bTest = block->bbJumpDest; - // Does the block consist of 'jtrue(cond) block' ? + // Does the bTest consist of 'jtrue(cond) block' ? if (bTest->bbJumpKind != BBJ_COND) { return false; } // bTest must be a backwards jump to block->bbNext - if (bTest->bbJumpDest != block->bbNext) + // This will be the top of the loop. + // + BasicBlock* const bTop = bTest->bbJumpDest; + + if (bTop != block->bbNext) { return false; } - // Since test is a BBJ_COND it will have a bbNext - noway_assert(bTest->bbNext != nullptr); + // Since bTest is a BBJ_COND it will have a bbNext + // + BasicBlock* const bJoin = bTest->bbNext; + noway_assert(bJoin != nullptr); // 'block' must be in the same try region as the condition, since we're going to insert a duplicated condition // in a new block after 'block', and the condition might include exception throwing code. @@ -4903,8 +4909,7 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) // The duplicated condition block will branch to bTest->bbNext, so that also better be in the // same try region (or no try region) to avoid generating illegal flow. - BasicBlock* bTestNext = bTest->bbNext; - if (bTestNext->hasTryIndex() && !BasicBlock::sameTryRegion(block, bTestNext)) + if (bJoin->hasTryIndex() && !BasicBlock::sameTryRegion(block, bJoin)) { return false; } @@ -4919,7 +4924,7 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) } // Find the loop termination test at the bottom of the loop. - Statement* condStmt = bTest->lastStmt(); + Statement* const condStmt = bTest->lastStmt(); // Verify the test block ends with a conditional that we can manipulate. GenTree* const condTree = condStmt->GetRootNode(); @@ -4929,6 +4934,9 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) return false; } + JITDUMP("Matched flow pattern for loop inversion: block " FMT_BB " bTop " FMT_BB " bTest " FMT_BB "\n", + block->bbNum, bTop->bbNum, bTest->bbNum); + // Estimate the cost of cloning the entire test block. // // Note: it would help throughput to compute the maximum cost @@ -4956,7 +4964,7 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) bool allProfileWeightsAreValid = false; weight_t const weightBlock = block->bbWeight; weight_t const weightTest = bTest->bbWeight; - weight_t const weightNext = block->bbNext->bbWeight; + weight_t const weightTop = bTop->bbWeight; // If we have profile data then we calculate the number of times // the loop will iterate into loopIterations @@ -4964,35 +4972,45 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) { // Only rely upon the profile weight when all three of these blocks // have good profile weights - if (block->hasProfileWeight() && bTest->hasProfileWeight() && block->bbNext->hasProfileWeight()) + if (block->hasProfileWeight() && bTest->hasProfileWeight() && bTop->hasProfileWeight()) { // If this while loop never iterates then don't bother transforming // - if (weightNext == BB_ZERO_WEIGHT) + if (weightTop == BB_ZERO_WEIGHT) { return true; } - // We generally expect weightTest == weightNext + weightBlock. + // We generally expect weightTest > weightTop // // Tolerate small inconsistencies... // - if (!fgProfileWeightsConsistent(weightBlock + weightNext, weightTest)) + if (!fgProfileWeightsConsistent(weightBlock + weightTop, weightTest)) { JITDUMP("Profile weights locally inconsistent: block " FMT_WT ", next " FMT_WT ", test " FMT_WT "\n", - weightBlock, weightNext, weightTest); + weightBlock, weightTop, weightTest); } else { allProfileWeightsAreValid = true; - // Determine iteration count + // Determine average iteration count // - // weightNext is the number of time this loop iterates - // weightBlock is the number of times that we enter the while loop + // weightTop is the number of time this loop executes + // weightTest is the number of times that we consider entering or remaining in the loop // loopIterations is the average number of times that this loop iterates // - loopIterations = weightNext / weightBlock; + weight_t loopEntries = weightTest - weightTop; + + // If profile is inaccurate, try and use other data to provide a credible estimate. + // The value should at least be >= weightBlock. + // + if (loopEntries < weightBlock) + { + loopEntries = weightBlock; + } + + loopIterations = weightTop / loopEntries; } } else @@ -5132,16 +5150,33 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) // Flag the block that received the copy as potentially having various constructs. bNewCond->bbFlags |= bTest->bbFlags & BBF_COPY_PROPAGATE; - bNewCond->bbJumpDest = bTest->bbNext; + // Fix flow and profile + // + bNewCond->bbJumpDest = bJoin; bNewCond->inheritWeight(block); - // Update bbRefs and bbPreds for 'bNewCond', 'bNewCond->bbNext' 'bTest' and 'bTest->bbNext'. + if (allProfileWeightsAreValid) + { + weight_t const delta = weightTest - weightTop; - fgAddRefPred(bNewCond, block); - fgAddRefPred(bNewCond->bbNext, bNewCond); + // If there is just one outside edge incident on bTest, then ideally delta == block->bbWeight. + // But this might not be the case if profile data is inconsistent. + // + // And if bTest has multiple outside edges we want to account for the weight of them all. + // + if (delta > block->bbWeight) + { + bNewCond->setBBProfileWeight(delta); + } + } + // Update pred info + // + fgAddRefPred(bJoin, bNewCond); + fgAddRefPred(bTop, bNewCond); + + fgAddRefPred(bNewCond, block); fgRemoveRefPred(bTest, block); - fgAddRefPred(bTest->bbNext, bNewCond); // Move all predecessor edges that look like loop entry edges to point to the new cloned condition // block, not the existing condition block. The idea is that if we only move `block` to point to @@ -5151,15 +5186,15 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) // as the proxy for predecessors that are "in" versus "out" of the potential loop. Note that correctness // is maintained no matter which condition block we point to, but we'll lose optimization potential // (and create spaghetti code) if we get it wrong. - + // BlockToBlockMap blockMap(getAllocator(CMK_LoopOpt)); bool blockMapInitialized = false; - unsigned loopFirstNum = bNewCond->bbNext->bbNum; - unsigned loopBottomNum = bTest->bbNum; + unsigned const loopFirstNum = bTop->bbNum; + unsigned const loopBottomNum = bTest->bbNum; for (BasicBlock* const predBlock : bTest->PredBlocks()) { - unsigned bNum = predBlock->bbNum; + unsigned const bNum = predBlock->bbNum; if ((loopFirstNum <= bNum) && (bNum <= loopBottomNum)) { // Looks like the predecessor is from within the potential loop; skip it. @@ -5189,8 +5224,8 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) // cases of stress modes with inconsistent weights. // JITDUMP("Reducing profile weight of " FMT_BB " from " FMT_WT " to " FMT_WT "\n", bTest->bbNum, weightTest, - weightNext); - bTest->inheritWeight(block->bbNext); + weightTop); + bTest->inheritWeight(bTop); // Determine the new edge weights. // @@ -5200,23 +5235,23 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) // Note "next" is the loop top block, not bTest's bbNext, // we'll call this latter block "after". // - weight_t const testToNextLikelihood = min(1.0, weightNext / weightTest); + weight_t const testToNextLikelihood = min(1.0, weightTop / weightTest); weight_t const testToAfterLikelihood = 1.0 - testToNextLikelihood; - // Adjust edges out of bTest (which now has weight weightNext) + // Adjust edges out of bTest (which now has weight weightTop) // - weight_t const testToNextWeight = weightNext * testToNextLikelihood; - weight_t const testToAfterWeight = weightNext * testToAfterLikelihood; + weight_t const testToNextWeight = weightTop * testToNextLikelihood; + weight_t const testToAfterWeight = weightTop * testToAfterLikelihood; - FlowEdge* const edgeTestToNext = fgGetPredForBlock(bTest->bbJumpDest, bTest); + FlowEdge* const edgeTestToNext = fgGetPredForBlock(bTop, bTest); FlowEdge* const edgeTestToAfter = fgGetPredForBlock(bTest->bbNext, bTest); - JITDUMP("Setting weight of " FMT_BB " -> " FMT_BB " to " FMT_WT " (iterate loop)\n", bTest->bbNum, - bTest->bbJumpDest->bbNum, testToNextWeight); + JITDUMP("Setting weight of " FMT_BB " -> " FMT_BB " to " FMT_WT " (iterate loop)\n", bTest->bbNum, bTop->bbNum, + testToNextWeight); JITDUMP("Setting weight of " FMT_BB " -> " FMT_BB " to " FMT_WT " (exit loop)\n", bTest->bbNum, bTest->bbNext->bbNum, testToAfterWeight); - edgeTestToNext->setEdgeWeights(testToNextWeight, testToNextWeight, bTest->bbJumpDest); + edgeTestToNext->setEdgeWeights(testToNextWeight, testToNextWeight, bTop); edgeTestToAfter->setEdgeWeights(testToAfterWeight, testToAfterWeight, bTest->bbNext); // Adjust edges out of block, using the same distribution. @@ -7502,13 +7537,7 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack* blo return fgWalkResult::WALK_CONTINUE; } - // Initclass CLS_VARs and IconHandles are the base cases of cctor dependent trees. - // In the IconHandle case, it's of course the dereference, rather than the constant itself, that is - // truly dependent on the cctor. So a more precise approach would be to separately propagate - // isCctorDependent and isAddressWhoseDereferenceWouldBeCctorDependent, but we don't for - // simplicity/throughput; the constant itself would be considered non-hoistable anyway, since - // optIsCSEcandidate returns false for constants. - bool treeIsCctorDependent = tree->OperIs(GT_CNS_INT) && ((tree->gtFlags & GTF_ICON_INITCLASS) != 0); + bool treeIsCctorDependent = tree->OperIsIndir() && ((tree->gtFlags & GTF_IND_INITCLASS) != 0); bool treeIsInvariant = true; bool treeHasHoistableChildren = false; int childCount; @@ -8611,7 +8640,7 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk) { GenTree* arg = lhs->AsIndir()->Addr()->gtEffectiveVal(/*commaOnly*/ true); - if ((tree->gtFlags & GTF_IND_VOLATILE) != 0) + if ((lhs->gtFlags & GTF_IND_VOLATILE) != 0) { memoryHavoc |= memoryKindSet(GcHeap, ByrefExposed); continue; diff --git a/src/coreclr/jit/promotion.cpp b/src/coreclr/jit/promotion.cpp index af25903693dba5..8edde3c598a574 100644 --- a/src/coreclr/jit/promotion.cpp +++ b/src/coreclr/jit/promotion.cpp @@ -91,83 +91,6 @@ struct Access } }; -//------------------------------------------------------------------------ -// BinarySearch: -// Find first entry with an equal offset, or bitwise complement of first -// entry with a higher offset. -// -// Parameters: -// vec - The vector to binary search in -// offset - The offset to search for -// -// Returns: -// Index of the first entry with an equal offset, or bitwise complement of -// first entry with a higher offset. -// -template -static size_t BinarySearch(const jitstd::vector& vec, unsigned offset) -{ - size_t min = 0; - size_t max = vec.size(); - while (min < max) - { - size_t mid = min + (max - min) / 2; - if (vec[mid].*field == offset) - { - while (mid > 0 && vec[mid - 1].*field == offset) - { - mid--; - } - - return mid; - } - if (vec[mid].*field < offset) - { - min = mid + 1; - } - else - { - max = mid; - } - } - - return ~min; -} - -// Represents a single replacement of a (field) access into a struct local. -struct Replacement -{ - unsigned Offset; - var_types AccessType; - unsigned LclNum; - // Is the replacement local (given by LclNum) fresher than the value in the struct local? - bool NeedsWriteBack = true; - // Is the value in the struct local fresher than the replacement local? - bool NeedsReadBack = false; - - Replacement(unsigned offset, var_types accessType, unsigned lclNum) - : Offset(offset), AccessType(accessType), LclNum(lclNum) - { - } - - bool Overlaps(unsigned otherStart, unsigned otherSize) const - { - unsigned end = Offset + genTypeSize(AccessType); - if (end <= otherStart) - { - return false; - } - - unsigned otherEnd = otherStart + otherSize; - if (otherEnd <= Offset) - { - return false; - } - - return true; - } -}; - enum class AccessKindFlags : uint32_t { None = 0, @@ -232,7 +155,7 @@ class LocalUses size_t index = 0; if (m_accesses.size() > 0) { - index = BinarySearch(m_accesses, offs); + index = Promotion::BinarySearch(m_accesses, offs); if ((ssize_t)index >= 0) { do @@ -309,6 +232,8 @@ class LocalUses return; } + JITDUMP("Picking promotions for V%02u\n", lclNum); + assert(*replacements == nullptr); for (size_t i = 0; i < m_accesses.size(); i++) { @@ -342,8 +267,10 @@ class LocalUses new (comp, CMK_Promotion) jitstd::vector(comp->getAllocator(CMK_Promotion)); } - (*replacements)->push_back(Replacement(access.Offset, access.AccessType, newLcl)); + (*replacements)->push_back(Replacement(access.Offset, access.AccessType, newLcl DEBUGARG(bufp))); } + + JITDUMP("\n"); } //------------------------------------------------------------------------ @@ -428,28 +355,28 @@ class LocalUses countOverlappedCallsWtd + countOverlappedReturnsWtd + countOverlappedAssignmentSourceWtd; costWith += countWriteBacksWtd * writeBackCost; - JITDUMP("Evaluating access %s @ %03u\n", varTypeName(access.AccessType), access.Offset); - JITDUMP(" Single write-back cost: " FMT_WT "\n", writeBackCost); - JITDUMP(" Write backs: " FMT_WT "\n", countWriteBacksWtd); - JITDUMP(" Read backs: " FMT_WT "\n", countReadBacksWtd); - JITDUMP(" Cost with: " FMT_WT "\n", costWith); - JITDUMP(" Cost without: " FMT_WT "\n", costWithout); + JITDUMP(" Evaluating access %s @ %03u\n", varTypeName(access.AccessType), access.Offset); + JITDUMP(" Single write-back cost: " FMT_WT "\n", writeBackCost); + JITDUMP(" Write backs: " FMT_WT "\n", countWriteBacksWtd); + JITDUMP(" Read backs: " FMT_WT "\n", countReadBacksWtd); + JITDUMP(" Cost with: " FMT_WT "\n", costWith); + JITDUMP(" Cost without: " FMT_WT "\n", costWithout); if (costWith < costWithout) { - JITDUMP(" Promoting replacement\n"); + JITDUMP(" Promoting replacement\n\n"); return true; } #ifdef DEBUG if (comp->compStressCompile(Compiler::STRESS_PHYSICAL_PROMOTION_COST, 25)) { - JITDUMP(" Promoting replacement due to stress\n"); + JITDUMP(" Promoting replacement due to stress\n\n"); return true; } #endif - JITDUMP(" Disqualifying replacement\n"); + JITDUMP(" Disqualifying replacement\n\n"); return false; } @@ -466,7 +393,8 @@ class LocalUses { if (access.AccessType == TYP_STRUCT) { - printf(" [%03u..%03u)\n", access.Offset, access.Offset + access.Layout->GetSize()); + printf(" [%03u..%03u) as %s\n", access.Offset, access.Offset + access.Layout->GetSize(), + access.Layout->GetClassName()); } else { @@ -594,6 +522,7 @@ class LocalsUseVisitor : public GenTreeVisitor return m_uses[lclNum]; } + //------------------------------------------------------------------------ // ClassifyLocalAccess: // Given a local use and its user, classify information about it. @@ -661,392 +590,396 @@ class LocalsUseVisitor : public GenTreeVisitor } }; -class ReplaceVisitor : public GenTreeVisitor +//------------------------------------------------------------------------ +// Replacement::Overlaps: +// Check if this replacement overlaps the specified range. +// +// Parameters: +// otherStart - Start of the other range. +// otherSize - Size of the other range. +// +// Returns: +// True if they overlap. +// +bool Replacement::Overlaps(unsigned otherStart, unsigned otherSize) const { - Promotion* m_prom; - jitstd::vector** m_replacements; - bool m_madeChanges = false; - -public: - enum - { - DoPostOrder = true, - UseExecutionOrder = true, - }; - - ReplaceVisitor(Promotion* prom, jitstd::vector** replacements) - : GenTreeVisitor(prom->m_compiler), m_prom(prom), m_replacements(replacements) + unsigned end = Offset + genTypeSize(AccessType); + if (end <= otherStart) { + return false; } - bool MadeChanges() + unsigned otherEnd = otherStart + otherSize; + if (otherEnd <= Offset) { - return m_madeChanges; + return false; } - void Reset() - { - m_madeChanges = false; - } + return true; +} - fgWalkResult PostOrderVisit(GenTree** use, GenTree* user) - { - GenTree* tree = *use; +//------------------------------------------------------------------------ +// CreateWriteBack: +// Create IR that writes a replacement local's value back to its struct local: +// +// ASG +// LCL_FLD int V00 [+4] +// LCL_VAR int V01 +// +// Parameters: +// compiler - Compiler instance +// structLclNum - Struct local +// replacement - Information about the replacement +// +// Returns: +// IR node. +// +GenTree* Promotion::CreateWriteBack(Compiler* compiler, unsigned structLclNum, const Replacement& replacement) +{ + GenTree* dst = compiler->gtNewLclFldNode(structLclNum, replacement.AccessType, replacement.Offset); + GenTree* src = compiler->gtNewLclvNode(replacement.LclNum, genActualType(replacement.AccessType)); + GenTree* asg = compiler->gtNewAssignNode(dst, src); + return asg; +} - if (tree->OperIs(GT_ASG)) - { - // If LHS of the ASG was a local then we skipped it as we don't - // want to see it until after the RHS. - if (tree->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) - { - ReplaceLocal(&tree->AsOp()->gtOp1, tree); - } +//------------------------------------------------------------------------ +// CreateReadBack: +// Create IR that reads a replacement local's value back from its struct local: +// +// ASG +// LCL_VAR int V01 +// LCL_FLD int V00 [+4] +// +// Parameters: +// compiler - Compiler instance +// structLclNum - Struct local +// replacement - Information about the replacement +// +// Returns: +// IR node. +// +GenTree* Promotion::CreateReadBack(Compiler* compiler, unsigned structLclNum, const Replacement& replacement) +{ + GenTree* dst = compiler->gtNewLclvNode(replacement.LclNum, genActualType(replacement.AccessType)); + GenTree* src = compiler->gtNewLclFldNode(structLclNum, replacement.AccessType, replacement.Offset); + GenTree* asg = compiler->gtNewAssignNode(dst, src); + return asg; +} - // Assignments can be decomposed directly into accesses of the replacements. - DecomposeAssignment((*use)->AsOp(), user); - return fgWalkResult::WALK_CONTINUE; - } +Compiler::fgWalkResult ReplaceVisitor::PostOrderVisit(GenTree** use, GenTree* user) +{ + GenTree* tree = *use; - if (tree->OperIs(GT_CALL)) + if (tree->OperIs(GT_ASG)) + { + // If LHS of the ASG was a local then we skipped it as we don't + // want to see it until after the RHS. + if (tree->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) { - // Calls need to store replacements back into the struct local for args - // and need to restore replacements from the result (for - // retbufs/returns). - LoadStoreAroundCall((*use)->AsCall(), user); - return fgWalkResult::WALK_CONTINUE; + ReplaceLocal(&tree->AsOp()->gtOp1, tree); } - if (tree->OperIs(GT_RETURN)) - { - // Returns need to store replacements back into the struct local. - StoreBeforeReturn((*use)->AsUnOp()); - return fgWalkResult::WALK_CONTINUE; - } + // Assignments can be decomposed directly into accesses of the replacements. + HandleAssignment(use, user); + return fgWalkResult::WALK_CONTINUE; + } - // Skip the local on the LHS of ASGs when we see it in the normal tree - // visit; we handle it as part of the parent ASG instead. - if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD) && - ((user == nullptr) || !user->OperIs(GT_ASG) || (user->gtGetOp1() != tree))) - { - ReplaceLocal(use, user); - return fgWalkResult::WALK_CONTINUE; - } + if (tree->OperIs(GT_CALL)) + { + // Calls need to store replacements back into the struct local for args + // and need to restore replacements from the result (for + // retbufs/returns). + LoadStoreAroundCall((*use)->AsCall(), user); + return fgWalkResult::WALK_CONTINUE; + } + if (tree->OperIs(GT_RETURN)) + { + // Returns need to store replacements back into the struct local. + StoreBeforeReturn((*use)->AsUnOp()); return fgWalkResult::WALK_CONTINUE; } - //------------------------------------------------------------------------ - // DecomposeAssignment: - // Handle an assignment that may be between struct locals with replacements. - // - // Parameters: - // asg - The assignment - // user - The user of the assignment. - // - void DecomposeAssignment(GenTreeOp* asg, GenTree* user) + // Skip the local on the LHS of ASGs when we see it in the normal tree + // visit; we handle it as part of the parent ASG instead. + if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD) && + ((user == nullptr) || !user->OperIs(GT_ASG) || (user->gtGetOp1() != tree))) { - // TODO-CQ: field-by-field copies and inits. + ReplaceLocal(use, user); + return fgWalkResult::WALK_CONTINUE; + } - if (asg->gtGetOp2()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) - { - GenTreeLclVarCommon* rhsLcl = asg->gtGetOp2()->AsLclVarCommon(); - if (rhsLcl->TypeIs(TYP_STRUCT)) - { - unsigned size = rhsLcl->GetLayout(m_compiler)->GetSize(); - WriteBackBefore(&asg->gtOp2, rhsLcl->GetLclNum(), rhsLcl->GetLclOffs(), size); - } - } + return fgWalkResult::WALK_CONTINUE; +} - if (asg->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) +//------------------------------------------------------------------------ +// LoadStoreAroundCall: +// Handle a call that may involve struct local arguments and that may +// pass a struct local with replacements as the retbuf. +// +// Parameters: +// call - The call +// user - The user of the call. +// +void ReplaceVisitor::LoadStoreAroundCall(GenTreeCall* call, GenTree* user) +{ + CallArg* retBufArg = nullptr; + for (CallArg& arg : call->gtArgs.Args()) + { + if (arg.GetWellKnownArg() == WellKnownArg::RetBuffer) { - GenTreeLclVarCommon* lhsLcl = asg->gtGetOp1()->AsLclVarCommon(); - if (lhsLcl->TypeIs(TYP_STRUCT)) - { - unsigned size = lhsLcl->GetLayout(m_compiler)->GetSize(); - MarkForReadBack(lhsLcl->GetLclNum(), lhsLcl->GetLclOffs(), size, true); - } + retBufArg = &arg; + continue; } - } - //------------------------------------------------------------------------ - // LoadStoreAroundCall: - // Handle a call that may involve struct local arguments and that may - // pass a struct local with replacements as the retbuf. - // - // Parameters: - // call - The call - // user - The user of the call. - // - void LoadStoreAroundCall(GenTreeCall* call, GenTree* user) - { - CallArg* retBufArg = nullptr; - for (CallArg& arg : call->gtArgs.Args()) + if (!arg.GetNode()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) { - if (arg.GetWellKnownArg() == WellKnownArg::RetBuffer) - { - retBufArg = &arg; - continue; - } - - if (!arg.GetNode()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) - { - continue; - } + continue; + } - GenTreeLclVarCommon* argNodeLcl = arg.GetNode()->AsLclVarCommon(); + GenTreeLclVarCommon* argNodeLcl = arg.GetNode()->AsLclVarCommon(); - if (argNodeLcl->TypeIs(TYP_STRUCT)) - { - unsigned size = argNodeLcl->GetLayout(m_compiler)->GetSize(); - WriteBackBefore(&arg.EarlyNodeRef(), argNodeLcl->GetLclNum(), argNodeLcl->GetLclOffs(), size); - } + if (argNodeLcl->TypeIs(TYP_STRUCT)) + { + unsigned size = argNodeLcl->GetLayout(m_compiler)->GetSize(); + WriteBackBefore(&arg.EarlyNodeRef(), argNodeLcl->GetLclNum(), argNodeLcl->GetLclOffs(), size); } + } - if (call->IsOptimizingRetBufAsLocal()) - { - assert(retBufArg != nullptr); - assert(retBufArg->GetNode()->OperIs(GT_LCL_ADDR)); - GenTreeLclVarCommon* retBufLcl = retBufArg->GetNode()->AsLclVarCommon(); - unsigned size = m_compiler->typGetObjLayout(call->gtRetClsHnd)->GetSize(); + if (call->IsOptimizingRetBufAsLocal()) + { + assert(retBufArg != nullptr); + assert(retBufArg->GetNode()->OperIs(GT_LCL_ADDR)); + GenTreeLclVarCommon* retBufLcl = retBufArg->GetNode()->AsLclVarCommon(); + unsigned size = m_compiler->typGetObjLayout(call->gtRetClsHnd)->GetSize(); - MarkForReadBack(retBufLcl->GetLclNum(), retBufLcl->GetLclOffs(), size); - } + MarkForReadBack(retBufLcl->GetLclNum(), retBufLcl->GetLclOffs(), size); } +} - //------------------------------------------------------------------------ - // ReplaceLocal: - // Handle a local that may need to be replaced. - // - // Parameters: - // use - The use of the local - // user - The user of the local. - // - // Notes: - // This usually amounts to making a replacement like - // - // LCL_FLD int V00 [+8] -> LCL_VAR int V10. - // - // In some cases we may have a pending read back, meaning that the - // replacement local is out-of-date compared to the struct local. - // In that case we also need to insert IR to read it back. - // This happens for example if the struct local was just assigned from a - // call or via a block copy. - // - void ReplaceLocal(GenTree** use, GenTree* user) +//------------------------------------------------------------------------ +// ReplaceLocal: +// Handle a local that may need to be replaced. +// +// Parameters: +// use - The use of the local +// user - The user of the local. +// +// Notes: +// This usually amounts to making a replacement like +// +// LCL_FLD int V00 [+8] -> LCL_VAR int V10. +// +// In some cases we may have a pending read back, meaning that the +// replacement local is out-of-date compared to the struct local. +// In that case we also need to insert IR to read it back. +// This happens for example if the struct local was just assigned from a +// call or via a block copy. +// +void ReplaceVisitor::ReplaceLocal(GenTree** use, GenTree* user) +{ + GenTreeLclVarCommon* lcl = (*use)->AsLclVarCommon(); + unsigned lclNum = lcl->GetLclNum(); + if (m_replacements[lclNum] == nullptr) { - GenTreeLclVarCommon* lcl = (*use)->AsLclVarCommon(); - unsigned lclNum = lcl->GetLclNum(); - if (m_replacements[lclNum] == nullptr) - { - return; - } + return; + } - jitstd::vector& replacements = *m_replacements[lclNum]; + jitstd::vector& replacements = *m_replacements[lclNum]; - unsigned offs = lcl->GetLclOffs(); - var_types accessType = lcl->TypeGet(); + unsigned offs = lcl->GetLclOffs(); + var_types accessType = lcl->TypeGet(); #ifdef DEBUG - if (accessType == TYP_STRUCT) + if (accessType == TYP_STRUCT) + { + assert((user == nullptr) || user->OperIs(GT_ASG, GT_CALL, GT_RETURN)); + } + else + { + ClassLayout* accessLayout = accessType == TYP_STRUCT ? lcl->GetLayout(m_compiler) : nullptr; + unsigned accessSize = accessLayout != nullptr ? accessLayout->GetSize() : genTypeSize(accessType); + for (const Replacement& rep : replacements) { - assert((user == nullptr) || user->OperIs(GT_ASG, GT_CALL, GT_RETURN)); + assert(!rep.Overlaps(offs, accessSize) || ((rep.Offset == offs) && (rep.AccessType == accessType))); } - else - { - ClassLayout* accessLayout = accessType == TYP_STRUCT ? lcl->GetLayout(m_compiler) : nullptr; - unsigned accessSize = accessLayout != nullptr ? accessLayout->GetSize() : genTypeSize(accessType); - for (const Replacement& rep : replacements) - { - assert(!rep.Overlaps(offs, accessSize) || ((rep.Offset == offs) && (rep.AccessType == accessType))); - } - assert((accessType != TYP_STRUCT) || (accessLayout != nullptr)); - JITDUMP("Processing use [%06u] of V%02u.[%03u..%03u)\n", Compiler::dspTreeID(lcl), lclNum, offs, - offs + accessSize); - } + assert((accessType != TYP_STRUCT) || (accessLayout != nullptr)); + JITDUMP("Processing use [%06u] of V%02u.[%03u..%03u)\n", Compiler::dspTreeID(lcl), lclNum, offs, + offs + accessSize); + } #endif - if (accessType == TYP_STRUCT) - { - // Will be handled once we get to the parent. - return; - } + if (accessType == TYP_STRUCT) + { + // Will be handled once we get to the parent. + return; + } - size_t index = BinarySearch(replacements, offs); - if ((ssize_t)index < 0) - { - // Access that we don't have a replacement for. - return; - } + size_t index = Promotion::BinarySearch(replacements, offs); + if ((ssize_t)index < 0) + { + // Access that we don't have a replacement for. + return; + } - Replacement& rep = replacements[index]; - assert(accessType == rep.AccessType); - JITDUMP(" ..replaced with promoted lcl V%02u\n", rep.LclNum); - *use = m_compiler->gtNewLclvNode(rep.LclNum, accessType); + Replacement& rep = replacements[index]; + assert(accessType == rep.AccessType); + JITDUMP(" ..replaced with promoted lcl V%02u\n", rep.LclNum); + *use = m_compiler->gtNewLclvNode(rep.LclNum, accessType); - if ((lcl->gtFlags & GTF_VAR_DEF) != 0) - { - rep.NeedsWriteBack = true; - rep.NeedsReadBack = false; - } - else if (rep.NeedsReadBack) - { - GenTree* dst = m_compiler->gtNewLclvNode(rep.LclNum, rep.AccessType); - GenTree* src = m_compiler->gtNewLclFldNode(lclNum, rep.AccessType, rep.Offset); - *use = m_compiler->gtNewOperNode(GT_COMMA, (*use)->TypeGet(), m_compiler->gtNewAssignNode(dst, src), *use); - rep.NeedsReadBack = false; - - // TODO-CQ: Local copy prop does not take into account that the - // uses of LCL_VAR occur at the user, which means it may introduce - // illegally overlapping lifetimes, such as: - // - // └──▌ ADD int - // ├──▌ LCL_VAR int V10 tmp6 -> copy propagated to [V35 tmp31] - // └──▌ COMMA int - // ├──▌ ASG int - // │ ├──▌ LCL_VAR int V35 tmp31 - // │ └──▌ LCL_FLD int V03 loc1 [+4] - // This really ought to be handled by local copy prop, but the way it works during - // morph makes it hard to fix there. - // - // This is the short term fix. Long term fixes may be: - // 1. Fix local copy prop - // 2. Teach LSRA to allow the above cases, simplifying IR concepts (e.g. - // introduce something like GT_COPY on top of LCL_VAR when they - // need to be "defs") - // 3. Change the pass here to avoid creating any embedded assignments by making use - // of gtSplitTree. We will only need to split in very edge cases since the point - // at which the replacement was marked as needing read back is practically always - // going to be in a previous statement, so this shouldn't be too bad for CQ. - - m_compiler->lvaGetDesc(rep.LclNum)->lvRedefinedInEmbeddedStatement = true; - } - - m_madeChanges = true; + if ((lcl->gtFlags & GTF_VAR_DEF) != 0) + { + rep.NeedsWriteBack = true; + rep.NeedsReadBack = false; + } + else if (rep.NeedsReadBack) + { + *use = m_compiler->gtNewOperNode(GT_COMMA, (*use)->TypeGet(), + Promotion::CreateReadBack(m_compiler, lclNum, rep), *use); + rep.NeedsReadBack = false; + + // TODO-CQ: Local copy prop does not take into account that the + // uses of LCL_VAR occur at the user, which means it may introduce + // illegally overlapping lifetimes, such as: + // + // └──▌ ADD int + // ├──▌ LCL_VAR int V10 tmp6 -> copy propagated to [V35 tmp31] + // └──▌ COMMA int + // ├──▌ ASG int + // │ ├──▌ LCL_VAR int V35 tmp31 + // │ └──▌ LCL_FLD int V03 loc1 [+4] + // This really ought to be handled by local copy prop, but the way it works during + // morph makes it hard to fix there. + // + // This is the short term fix. Long term fixes may be: + // 1. Fix local copy prop + // 2. Teach LSRA to allow the above cases, simplifying IR concepts (e.g. + // introduce something like GT_COPY on top of LCL_VAR when they + // need to be "defs") + // 3. Change the pass here to avoid creating any embedded assignments by making use + // of gtSplitTree. We will only need to split in very edge cases since the point + // at which the replacement was marked as needing read back is practically always + // going to be in a previous statement, so this shouldn't be too bad for CQ. + + m_compiler->lvaGetDesc(rep.LclNum)->lvRedefinedInEmbeddedStatement = true; } - //------------------------------------------------------------------------ - // StoreBeforeReturn: - // Handle a return of a potential struct local. - // - // Parameters: - // ret - The GT_RETURN node - // - void StoreBeforeReturn(GenTreeUnOp* ret) + m_madeChanges = true; +} + +//------------------------------------------------------------------------ +// StoreBeforeReturn: +// Handle a return of a potential struct local. +// +// Parameters: +// ret - The GT_RETURN node +// +void ReplaceVisitor::StoreBeforeReturn(GenTreeUnOp* ret) +{ + if (ret->TypeIs(TYP_VOID) || !ret->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) { - if (ret->TypeIs(TYP_VOID) || !ret->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) - { - return; - } + return; + } - GenTreeLclVarCommon* retLcl = ret->gtGetOp1()->AsLclVarCommon(); - if (retLcl->TypeIs(TYP_STRUCT)) - { - unsigned size = retLcl->GetLayout(m_compiler)->GetSize(); - WriteBackBefore(&ret->gtOp1, retLcl->GetLclNum(), retLcl->GetLclOffs(), size); - } + GenTreeLclVarCommon* retLcl = ret->gtGetOp1()->AsLclVarCommon(); + if (retLcl->TypeIs(TYP_STRUCT)) + { + unsigned size = retLcl->GetLayout(m_compiler)->GetSize(); + WriteBackBefore(&ret->gtOp1, retLcl->GetLclNum(), retLcl->GetLclOffs(), size); } +} - //------------------------------------------------------------------------ - // WriteBackBefore: - // Update the use with IR that writes back all necessary overlapping - // replacements into a struct local. - // - // Parameters: - // use - The use, which will be updated with a cascading comma trees of assignments - // lcl - The struct local - // offs - The starting offset into the struct local of the overlapping range to write back to - // size - The size of the overlapping range - // - void WriteBackBefore(GenTree** use, unsigned lcl, unsigned offs, unsigned size) +//------------------------------------------------------------------------ +// WriteBackBefore: +// Update the use with IR that writes back all necessary overlapping +// replacements into a struct local. +// +// Parameters: +// use - The use, which will be updated with a cascading comma trees of assignments +// lcl - The struct local +// offs - The starting offset into the struct local of the overlapping range to write back to +// size - The size of the overlapping range +// +void ReplaceVisitor::WriteBackBefore(GenTree** use, unsigned lcl, unsigned offs, unsigned size) +{ + if (m_replacements[lcl] == nullptr) { - if (m_replacements[lcl] == nullptr) - { - return; - } + return; + } - jitstd::vector& replacements = *m_replacements[lcl]; - size_t index = BinarySearch(replacements, offs); + jitstd::vector& replacements = *m_replacements[lcl]; + size_t index = Promotion::BinarySearch(replacements, offs); - if ((ssize_t)index < 0) + if ((ssize_t)index < 0) + { + index = ~index; + if ((index > 0) && replacements[index - 1].Overlaps(offs, size)) { - index = ~index; - if ((index > 0) && replacements[index - 1].Overlaps(offs, size)) - { - index--; - } + index--; } + } - unsigned end = offs + size; - while ((index < replacements.size()) && (replacements[index].Offset < end)) + unsigned end = offs + size; + while ((index < replacements.size()) && (replacements[index].Offset < end)) + { + Replacement& rep = replacements[index]; + if (rep.NeedsWriteBack) { - Replacement& rep = replacements[index]; - if (rep.NeedsWriteBack) - { - GenTree* dst = m_compiler->gtNewLclFldNode(lcl, rep.AccessType, rep.Offset); - GenTree* src = m_compiler->gtNewLclvNode(rep.LclNum, rep.AccessType); - GenTreeOp* comma = - m_compiler->gtNewOperNode(GT_COMMA, (*use)->TypeGet(), m_compiler->gtNewAssignNode(dst, src), *use); - *use = comma; - use = &comma->gtOp2; - - rep.NeedsWriteBack = false; - m_madeChanges = true; - } + GenTreeOp* comma = m_compiler->gtNewOperNode(GT_COMMA, (*use)->TypeGet(), + Promotion::CreateWriteBack(m_compiler, lcl, rep), *use); + *use = comma; + use = &comma->gtOp2; - index++; + rep.NeedsWriteBack = false; + m_madeChanges = true; } + + index++; } +} - //------------------------------------------------------------------------ - // MarkForReadBack: - // Mark that replacements in the specified struct local need to be read - // back before their next use. - // - // Parameters: - // lcl - The struct local - // offs - The starting offset of the range in the struct local that needs to be read back from. - // size - The size of the range - // conservative - Whether this is a potentially conservative read back - // that we can handle more efficiently in the future (only used for - // logging purposes) - // - void MarkForReadBack(unsigned lcl, unsigned offs, unsigned size, bool conservative = false) +//------------------------------------------------------------------------ +// MarkForReadBack: +// Mark that replacements in the specified struct local need to be read +// back before their next use. +// +// Parameters: +// lcl - The struct local +// offs - The starting offset of the range in the struct local that needs to be read back from. +// size - The size of the range +// +void ReplaceVisitor::MarkForReadBack(unsigned lcl, unsigned offs, unsigned size) +{ + if (m_replacements[lcl] == nullptr) { - if (m_replacements[lcl] == nullptr) - { - return; - } + return; + } - jitstd::vector& replacements = *m_replacements[lcl]; - size_t index = BinarySearch(replacements, offs); + jitstd::vector& replacements = *m_replacements[lcl]; + size_t index = Promotion::BinarySearch(replacements, offs); - if ((ssize_t)index < 0) + if ((ssize_t)index < 0) + { + index = ~index; + if ((index > 0) && replacements[index - 1].Overlaps(offs, size)) { - index = ~index; - if ((index > 0) && replacements[index - 1].Overlaps(offs, size)) - { - index--; - } + index--; } + } - unsigned end = offs + size; - while ((index < replacements.size()) && (replacements[index].Offset < end)) - { - Replacement& rep = replacements[index]; - assert(rep.Overlaps(offs, size)); - rep.NeedsReadBack = true; - rep.NeedsWriteBack = false; - index++; - - if (conservative) - { - JITDUMP("*** NYI: Conservatively marked as read-back\n"); - conservative = false; - } - } + bool result = false; + unsigned end = offs + size; + while ((index < replacements.size()) && (replacements[index].Offset < end)) + { + result = true; + Replacement& rep = replacements[index]; + assert(rep.Overlaps(offs, size)); + rep.NeedsReadBack = true; + rep.NeedsWriteBack = false; + index++; } -}; +} //------------------------------------------------------------------------ // Promotion::Run: @@ -1090,7 +1023,7 @@ PhaseStatus Promotion::Run() } #endif - // Pick promotion based on the use information we just collected. + // Pick promotions based on the use information we just collected. bool anyReplacements = false; jitstd::vector** replacements = new (m_compiler, CMK_Promotion) jitstd::vector*[m_compiler->lvaCount]{}; @@ -1155,13 +1088,13 @@ PhaseStatus Promotion::Run() assert(!rep.NeedsReadBack || !rep.NeedsWriteBack); if (rep.NeedsReadBack) { - JITDUMP("Reading back replacement V%02u.[%03u..%03u) -> V%02u at the end of " FMT_BB "\n", i, + JITDUMP("Reading back replacement V%02u.[%03u..%03u) -> V%02u near the end of " FMT_BB ":\n", i, rep.Offset, rep.Offset + genTypeSize(rep.AccessType), rep.LclNum, bb->bbNum); - GenTree* dst = m_compiler->gtNewLclvNode(rep.LclNum, rep.AccessType); - GenTree* src = m_compiler->gtNewLclFldNode(i, rep.AccessType, rep.Offset); - GenTree* asg = m_compiler->gtNewAssignNode(dst, src); - m_compiler->fgInsertStmtNearEnd(bb, m_compiler->fgNewStmtFromTree(asg)); + GenTree* readBack = CreateReadBack(m_compiler, i, rep); + Statement* stmt = m_compiler->fgNewStmtFromTree(readBack); + DISPSTMT(stmt); + m_compiler->fgInsertStmtNearEnd(bb, stmt); rep.NeedsReadBack = false; } @@ -1214,12 +1147,9 @@ void Promotion::InsertInitialReadBack(unsigned lclNum, { for (unsigned i = 0; i < replacements.size(); i++) { - const Replacement& rep = replacements[i]; - - GenTree* dst = m_compiler->gtNewLclvNode(rep.LclNum, rep.AccessType); - GenTree* src = m_compiler->gtNewLclFldNode(lclNum, rep.AccessType, rep.Offset); - GenTree* asg = m_compiler->gtNewAssignNode(dst, src); - InsertInitStatement(prevStmt, asg); + const Replacement& rep = replacements[i]; + GenTree* readBack = CreateReadBack(m_compiler, lclNum, rep); + InsertInitStatement(prevStmt, readBack); } } diff --git a/src/coreclr/jit/promotion.h b/src/coreclr/jit/promotion.h index 2ae42e3312c0f8..a5ea57a071542d 100644 --- a/src/coreclr/jit/promotion.h +++ b/src/coreclr/jit/promotion.h @@ -7,12 +7,43 @@ #include "compiler.h" #include "vector.h" -struct Replacement; +// Represents a single replacement of a (field) access into a struct local. +struct Replacement +{ + unsigned Offset; + var_types AccessType; + unsigned LclNum; + // Is the replacement local (given by LclNum) fresher than the value in the struct local? + bool NeedsWriteBack = true; + // Is the value in the struct local fresher than the replacement local? + // Note that the invariant is that this is always false at the entrance to + // a basic block, i.e. all predecessors would have read the replacement + // back before transferring control if necessary. + bool NeedsReadBack = false; + // Arbitrary flag bit used e.g. by decomposition. Assumed to be false. + bool Handled = false; +#ifdef DEBUG + const char* Description; +#endif + + Replacement(unsigned offset, var_types accessType, unsigned lclNum DEBUGARG(const char* description)) + : Offset(offset) + , AccessType(accessType) + , LclNum(lclNum) +#ifdef DEBUG + , Description(description) +#endif + { + } + + bool Overlaps(unsigned otherStart, unsigned otherSize) const; +}; class Promotion { Compiler* m_compiler; + friend class LocalUses; friend class LocalsUseVisitor; friend class ReplaceVisitor; @@ -21,6 +52,51 @@ class Promotion const jitstd::vector& replacements, Statement** prevStmt); void InsertInitStatement(Statement** prevStmt, GenTree* tree); + static GenTree* CreateWriteBack(Compiler* compiler, unsigned structLclNum, const Replacement& replacement); + static GenTree* CreateReadBack(Compiler* compiler, unsigned structLclNum, const Replacement& replacement); + + //------------------------------------------------------------------------ + // BinarySearch: + // Find first entry with an equal offset, or bitwise complement of first + // entry with a higher offset. + // + // Parameters: + // vec - The vector to binary search in + // offset - The offset to search for + // + // Returns: + // Index of the first entry with an equal offset, or bitwise complement of + // first entry with a higher offset. + // + template + static size_t BinarySearch(const jitstd::vector& vec, unsigned offset) + { + size_t min = 0; + size_t max = vec.size(); + while (min < max) + { + size_t mid = min + (max - min) / 2; + if (vec[mid].*field == offset) + { + while (mid > 0 && vec[mid - 1].*field == offset) + { + mid--; + } + + return mid; + } + if (vec[mid].*field < offset) + { + min = mid + 1; + } + else + { + max = mid; + } + } + + return ~min; + } public: explicit Promotion(Compiler* compiler) : m_compiler(compiler) @@ -30,4 +106,61 @@ class Promotion PhaseStatus Run(); }; +class DecompositionStatementList; + +class ReplaceVisitor : public GenTreeVisitor +{ + Promotion* m_prom; + jitstd::vector** m_replacements; + bool m_madeChanges = false; + +public: + enum + { + DoPostOrder = true, + UseExecutionOrder = true, + }; + + ReplaceVisitor(Promotion* prom, jitstd::vector** replacements) + : GenTreeVisitor(prom->m_compiler), m_prom(prom), m_replacements(replacements) + { + } + + bool MadeChanges() + { + return m_madeChanges; + } + + void Reset() + { + m_madeChanges = false; + } + + fgWalkResult PostOrderVisit(GenTree** use, GenTree* user); + +private: + void LoadStoreAroundCall(GenTreeCall* call, GenTree* user); + void ReplaceLocal(GenTree** use, GenTree* user); + void StoreBeforeReturn(GenTreeUnOp* ret); + void WriteBackBefore(GenTree** use, unsigned lcl, unsigned offs, unsigned size); + void MarkForReadBack(unsigned lcl, unsigned offs, unsigned size); + + void HandleAssignment(GenTree** use, GenTree* user); + bool OverlappingReplacements(GenTreeLclVarCommon* lcl, + Replacement** firstReplacement, + Replacement** endReplacement = nullptr); + void EliminateCommasInBlockOp(GenTreeOp* asg, DecompositionStatementList* result); + void UpdateEarlyRefCount(GenTree* candidate); + void IncrementRefCount(unsigned lclNum); + void InitFieldByField(Replacement* firstRep, + Replacement* endRep, + unsigned char initVal, + DecompositionStatementList* result); + void CopyIntoFields(Replacement* firstRep, + Replacement* endRep, + GenTreeLclVarCommon* dst, + GenTree* src, + DecompositionStatementList* result); +}; + #endif diff --git a/src/coreclr/jit/promotiondecomposition.cpp b/src/coreclr/jit/promotiondecomposition.cpp new file mode 100644 index 00000000000000..a038e6286b879f --- /dev/null +++ b/src/coreclr/jit/promotiondecomposition.cpp @@ -0,0 +1,593 @@ +#include "jitpch.h" +#include "promotion.h" +#include "jitstd/algorithm.h" + +class DecompositionStatementList +{ + GenTree* m_head = nullptr; + +public: + void AddStatement(GenTree* stmt) + { + stmt->gtNext = m_head; + m_head = stmt; + } + + GenTree* ToCommaTree(Compiler* comp) + { + if (m_head == nullptr) + { + return comp->gtNewNothingNode(); + } + + GenTree* tree = m_head; + + for (GenTree* cur = m_head->gtNext; cur != nullptr; cur = cur->gtNext) + { + tree = comp->gtNewOperNode(GT_COMMA, tree->TypeGet(), cur, tree); + } + + return tree; + } +}; + +//------------------------------------------------------------------------ +// HandleAssignment: +// Handle an assignment that may be between struct locals with replacements. +// +// Parameters: +// asg - The assignment +// user - The user of the assignment. +// +void ReplaceVisitor::HandleAssignment(GenTree** use, GenTree* user) +{ + GenTreeOp* asg = (*use)->AsOp(); + + if (!asg->gtGetOp1()->TypeIs(TYP_STRUCT)) + { + return; + } + + GenTree* dst = asg->gtGetOp1(); + assert(!dst->OperIs(GT_COMMA)); + + GenTree* src = asg->gtGetOp2()->gtEffectiveVal(); + + Replacement* dstFirstRep = nullptr; + Replacement* dstEndRep = nullptr; + bool dstInvolvesReplacements = asg->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD) && + OverlappingReplacements(dst->AsLclVarCommon(), &dstFirstRep, &dstEndRep); + Replacement* srcFirstRep = nullptr; + Replacement* srcEndRep = nullptr; + bool srcInvolvesReplacements = asg->gtGetOp2()->OperIs(GT_LCL_VAR, GT_LCL_FLD) && + OverlappingReplacements(src->AsLclVarCommon(), &srcFirstRep, &srcEndRep); + + if (!dstInvolvesReplacements && !srcInvolvesReplacements) + { + return; + } + + JITDUMP("Processing block operation [%06u] that involves replacements\n", Compiler::dspTreeID(asg)); + + if (dstInvolvesReplacements && (src->OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_BLK) || src->IsConstInitVal())) + { + DecompositionStatementList result; + EliminateCommasInBlockOp(asg, &result); + + if (dstInvolvesReplacements && srcInvolvesReplacements) + { + JITDUMP("Copy [%06u] is between two physically promoted locals with replacements\n", + Compiler::dspTreeID(asg)); + JITDUMP("*** Conservative: Phys<->phys copies not yet supported; inserting conservative write-back\n"); + for (Replacement* rep = srcFirstRep; rep < srcEndRep; rep++) + { + if (rep->NeedsWriteBack) + { + result.AddStatement( + Promotion::CreateWriteBack(m_compiler, src->AsLclVarCommon()->GetLclNum(), *rep)); + rep->NeedsWriteBack = false; + } + } + + srcInvolvesReplacements = false; + } + + if (dstInvolvesReplacements) + { + GenTreeLclVarCommon* dstLcl = dst->AsLclVarCommon(); + unsigned dstLclOffs = dstLcl->GetLclOffs(); + unsigned dstLclSize = dstLcl->GetLayout(m_compiler)->GetSize(); + + if (dstFirstRep->Offset < dstLclOffs) + { + JITDUMP("*** Block operation partially overlaps with %s. Write and read-backs are necessary.\n", + dstFirstRep->Description); + // The value of the replacement will be partially assembled from its old value and this struct + // operation. + // We accomplish this by an initial write back, the struct copy, followed by a later read back. + // TODO-CQ: This is very expensive and unreflected in heuristics, but it is also very rare. + result.AddStatement(Promotion::CreateWriteBack(m_compiler, dstLcl->GetLclNum(), *dstFirstRep)); + + dstFirstRep->NeedsWriteBack = false; + dstFirstRep->NeedsReadBack = true; + dstFirstRep++; + } + + if (dstEndRep > dstFirstRep) + { + Replacement* dstLastRep = dstEndRep - 1; + if (dstLastRep->Offset + genTypeSize(dstLastRep->AccessType) > dstLclOffs + dstLclSize) + { + JITDUMP("*** Block operation partially overlaps with %s. Write and read-backs are necessary.\n", + dstLastRep->Description); + result.AddStatement(Promotion::CreateWriteBack(m_compiler, dstLcl->GetLclNum(), *dstLastRep)); + + dstLastRep->NeedsWriteBack = false; + dstLastRep->NeedsReadBack = true; + dstEndRep--; + } + } + + if (src->IsConstInitVal()) + { + GenTree* cns = src->OperIsInitVal() ? src->gtGetOp1() : src; + InitFieldByField(dstFirstRep, dstEndRep, static_cast(cns->AsIntCon()->IconValue()), + &result); + } + else + { + CopyIntoFields(dstFirstRep, dstEndRep, dstLcl, src, &result); + } + + // At this point all replacements that have Handled = true contain their correct value. + // Check if these cover the entire block operation. + unsigned prevEnd = dstLclOffs; + bool covered = true; + + for (Replacement* rep = dstFirstRep; rep < dstEndRep; rep++) + { + if (!rep->Handled) + { + covered = false; + break; + } + + assert(rep->Offset >= prevEnd); + if (rep->Offset != prevEnd) + { + // Uncovered hole from [lastEnd..rep->Offset). + // TODO-CQ: In many cases it's more efficient to "plug" the holes. However, + // it is made more complicated by the fact that the holes can contain GC pointers in them and + // we cannot (yet) represent custom class layouts with GC pointers in them. + // TODO-CQ: Many of these cases are just padding. We should handle structs with insignificant + // padding here. + covered = false; + break; + } + + prevEnd = rep->Offset + genTypeSize(rep->AccessType); + } + + covered &= prevEnd == dstLclOffs + dstLclSize; + + if (!covered) + { + JITDUMP("Struct operation is not fully covered by replaced fields. Keeping struct operation.\n"); + result.AddStatement(asg); + } + + // For unhandled replacements, mark that they will require a read back before their next access. + // Conversely, the replacements we handled above are now up to date and should not be read back. + // We also keep the invariant that Replacement::Handled == false, so reset it here as well. + + for (Replacement* rep = dstFirstRep; rep < dstEndRep; rep++) + { + rep->NeedsReadBack = !rep->Handled; + rep->NeedsWriteBack = rep->Handled; + rep->Handled = false; + } + } + else + { + assert(srcInvolvesReplacements); + } + + *use = result.ToCommaTree(m_compiler); + m_madeChanges = true; + } + else + { + if (asg->gtGetOp2()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) + { + GenTreeLclVarCommon* rhsLcl = asg->gtGetOp2()->AsLclVarCommon(); + unsigned size = rhsLcl->GetLayout(m_compiler)->GetSize(); + WriteBackBefore(&asg->gtOp2, rhsLcl->GetLclNum(), rhsLcl->GetLclOffs(), size); + } + + if (asg->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD)) + { + GenTreeLclVarCommon* lhsLcl = asg->gtGetOp1()->AsLclVarCommon(); + unsigned size = lhsLcl->GetLayout(m_compiler)->GetSize(); + MarkForReadBack(lhsLcl->GetLclNum(), lhsLcl->GetLclOffs(), size); + } + } +} + +//------------------------------------------------------------------------ +// OverlappingReplacements: +// Find replacements that overlap the specified struct local. +// +// Parameters: +// lcl - A struct local +// firstReplacement - [out] The first replacement that overlaps +// endReplacement - [out, optional] One past the last replacement that overlaps +// +// Returns: +// True if any replacement overlaps; otherwise false. +// +bool ReplaceVisitor::OverlappingReplacements(GenTreeLclVarCommon* lcl, + Replacement** firstReplacement, + Replacement** endReplacement) +{ + if (m_replacements[lcl->GetLclNum()] == nullptr) + { + return false; + } + + jitstd::vector& replacements = *m_replacements[lcl->GetLclNum()]; + + unsigned offs = lcl->GetLclOffs(); + unsigned size = lcl->GetLayout(m_compiler)->GetSize(); + size_t firstIndex = Promotion::BinarySearch(replacements, offs); + if ((ssize_t)firstIndex < 0) + { + firstIndex = ~firstIndex; + if (firstIndex > 0) + { + Replacement& lastRepBefore = replacements[firstIndex - 1]; + if ((lastRepBefore.Offset + genTypeSize(lastRepBefore.AccessType)) > offs) + { + // Overlap with last entry starting before offs. + firstIndex--; + } + else if (firstIndex >= replacements.size()) + { + // Starts after last replacement ends. + return false; + } + } + + const Replacement& first = replacements[firstIndex]; + if (first.Offset >= (offs + size)) + { + // First candidate starts after this ends. + return false; + } + } + + assert(replacements[firstIndex].Overlaps(offs, size)); + *firstReplacement = &replacements[firstIndex]; + + if (endReplacement != nullptr) + { + size_t lastIndex = Promotion::BinarySearch(replacements, offs + size); + if ((ssize_t)lastIndex < 0) + { + lastIndex = ~lastIndex; + } + + // Since we verified above that there is an overlapping replacement + // we know that lastIndex exists and is the next one that does not + // overlap. + assert(lastIndex > 0); + *endReplacement = replacements.data() + lastIndex; + } + + return true; +} + +//------------------------------------------------------------------------ +// EliminateCommasInBlockOp: +// Ensure that the sources of a block op are not commas by extracting side effects. +// +// Parameters: +// asg - The block op +// result - Statement list to add resulting statements to. +// +// Remarks: +// Works similarly to MorphInitBlockHelper::EliminateCommas. +// +void ReplaceVisitor::EliminateCommasInBlockOp(GenTreeOp* asg, DecompositionStatementList* result) +{ + bool any = false; + GenTree* lhs = asg->gtGetOp1(); + assert(lhs->OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_IND, GT_BLK)); + + GenTree* rhs = asg->gtGetOp2(); + + if (asg->IsReverseOp()) + { + while (rhs->OperIs(GT_COMMA)) + { + result->AddStatement(rhs->gtGetOp1()); + rhs = rhs->gtGetOp2(); + any = true; + } + } + else + { + if (lhs->OperIsUnary() && rhs->OperIs(GT_COMMA)) + { + GenTree* addr = lhs->gtGetOp1(); + // Note that GTF_GLOB_REF is not up to date here, hence we need + // a tree walk to find address exposed locals. + if (((addr->gtFlags & GTF_ALL_EFFECT) != 0) || (((rhs->gtFlags & GTF_ASG) != 0) && !addr->IsInvariant()) || + m_compiler->gtHasAddressExposedLocals(addr)) + { + unsigned lhsAddrLclNum = m_compiler->lvaGrabTemp(true DEBUGARG("Block morph LHS addr")); + + result->AddStatement(m_compiler->gtNewTempAssign(lhsAddrLclNum, addr)); + lhs->AsUnOp()->gtOp1 = m_compiler->gtNewLclvNode(lhsAddrLclNum, genActualType(addr)); + m_compiler->gtUpdateNodeSideEffects(lhs); + m_madeChanges = true; + any = true; + } + } + + while (rhs->OperIs(GT_COMMA)) + { + result->AddStatement(rhs->gtGetOp1()); + rhs = rhs->gtGetOp2(); + any = true; + } + } + + if (any) + { + asg->gtOp2 = rhs; + m_compiler->gtUpdateNodeSideEffects(asg); + m_madeChanges = true; + } +} + +//------------------------------------------------------------------------ +// InitFieldByField: +// Initialize the specified replacements with a specified pattern. +// +// Parameters: +// firstRep - The first replacement. +// endRep - End of the replacements. +// initVal - byte pattern to init with +// result - Statement list to add resulting statements to. +// +// Remarks: +// Sets Replacement::Handled if the replacement was handled and IR was +// created to initialize it with the correct value. +// +void ReplaceVisitor::InitFieldByField(Replacement* firstRep, + Replacement* endRep, + unsigned char initVal, + DecompositionStatementList* result) +{ + int64_t initPattern = int64_t(initVal) * 0x0101010101010101LL; + + for (Replacement* rep = firstRep; rep < endRep; rep++) + { + assert(!rep->Handled); + + GenTree* srcVal; + if ((initPattern != 0) && (varTypeIsSIMD(rep->AccessType) || varTypeIsGC(rep->AccessType))) + { + // Leave unhandled, we will do this via a read back on the next access. + continue; + } + + switch (rep->AccessType) + { + case TYP_BOOL: + case TYP_BYTE: + case TYP_UBYTE: + case TYP_SHORT: + case TYP_USHORT: + case TYP_INT: + { + int64_t mask = (int64_t(1) << (genTypeSize(rep->AccessType) * 8)) - 1; + srcVal = m_compiler->gtNewIconNode(static_cast(initPattern & mask)); + break; + } + case TYP_LONG: + srcVal = m_compiler->gtNewLconNode(initPattern); + break; + case TYP_FLOAT: + float floatPattern; + memcpy(&floatPattern, &initPattern, sizeof(floatPattern)); + srcVal = m_compiler->gtNewDconNode(floatPattern, TYP_FLOAT); + break; + case TYP_DOUBLE: + double doublePattern; + memcpy(&doublePattern, &initPattern, sizeof(doublePattern)); + srcVal = m_compiler->gtNewDconNode(doublePattern); + break; + case TYP_REF: + case TYP_BYREF: +#ifdef FEATURE_SIMD + case TYP_SIMD8: + case TYP_SIMD12: + case TYP_SIMD16: +#if defined(TARGET_XARCH) + case TYP_SIMD32: + case TYP_SIMD64: +#endif // TARGET_XARCH +#endif // FEATURE_SIMD + { + assert(initPattern == 0); + srcVal = m_compiler->gtNewZeroConNode(rep->AccessType); + break; + } + default: + unreached(); + } + + GenTree* lcl = m_compiler->gtNewLclvNode(rep->LclNum, rep->AccessType); + GenTree* asg = m_compiler->gtNewAssignNode(lcl, srcVal); + result->AddStatement(asg); + rep->Handled = true; + } +} + +//------------------------------------------------------------------------ +// CopyIntoFields: +// Copy from a specified block source into the specified replacements. +// +// Parameters: +// firstRep - The first replacement. +// endRep - End of the replacements. +// dst - Local containing the replacements. +// src - The block source. +// result - Statement list to add resulting statements to. +// +void ReplaceVisitor::CopyIntoFields(Replacement* firstRep, + Replacement* endRep, + GenTreeLclVarCommon* dst, + GenTree* src, + DecompositionStatementList* result) +{ + assert(src->OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_BLK)); + + GenTreeFlags indirFlags = GTF_EMPTY; + if (src->OperIs(GT_BLK)) + { + GenTree* addr = src->AsIndir()->Addr(); + + if (addr->OperIsLocal() && (addr->AsLclVarCommon()->GetLclNum() != dst->GetLclNum())) + { + // We will introduce more uses of the address local, so it is + // no longer dying here. + addr->gtFlags &= ~GTF_VAR_DEATH; + } + else if (addr->IsInvariant()) + { + // Fall through + } + else + { + // TODO-CQ: Avoid this local if we only use the address once? A + // bit complicated since our caller may use the address too. + unsigned addrLcl = m_compiler->lvaGrabTemp(true DEBUGARG("Spilling address for field-by-field copy")); + result->AddStatement(m_compiler->gtNewTempAssign(addrLcl, addr)); + src->AsUnOp()->gtOp1 = m_compiler->gtNewLclvNode(addrLcl, addr->TypeGet()); + } + + indirFlags = src->gtFlags & (GTF_IND_VOLATILE | GTF_IND_NONFAULTING | GTF_IND_UNALIGNED | GTF_IND_INITCLASS); + } + + LclVarDsc* srcDsc = src->OperIs(GT_LCL_VAR, GT_LCL_FLD) ? m_compiler->lvaGetDesc(src->AsLclVarCommon()) : nullptr; + + for (Replacement* rep = firstRep; rep < endRep; rep++) + { + assert(!rep->Handled); + assert(rep->Offset >= dst->GetLclOffs()); + + unsigned srcOffs = rep->Offset - dst->GetLclOffs(); + + GenTree* dstLcl = m_compiler->gtNewLclvNode(rep->LclNum, rep->AccessType); + GenTree* srcFld = nullptr; + if (srcDsc != nullptr) + { + srcOffs += src->AsLclVarCommon()->GetLclOffs(); + + if (srcDsc->lvPromoted) + { + unsigned fieldLcl = m_compiler->lvaGetFieldLocal(srcDsc, srcOffs); + + if ((fieldLcl != BAD_VAR_NUM) && (m_compiler->lvaGetDesc(fieldLcl)->lvType == rep->AccessType)) + { + srcFld = m_compiler->gtNewLclvNode(fieldLcl, rep->AccessType); + } + } + + if (srcFld == nullptr) + { + srcFld = m_compiler->gtNewLclFldNode(src->AsLclVarCommon()->GetLclNum(), rep->AccessType, srcOffs); + // TODO-CQ: This may be better left as a read back if the + // source is non-physically promoted. + m_compiler->lvaSetVarDoNotEnregister(src->AsLclVarCommon()->GetLclNum() + DEBUGARG(DoNotEnregisterReason::LocalField)); + } + + UpdateEarlyRefCount(srcFld); + } + else + { + if ((rep == firstRep) && m_compiler->fgIsBigOffset(srcOffs) && + m_compiler->fgAddrCouldBeNull(src->AsIndir()->Addr())) + { + GenTree* addrForNullCheck = m_compiler->gtCloneExpr(src->AsIndir()->Addr()); + GenTreeIndir* indir = m_compiler->gtNewIndir(TYP_BYTE, addrForNullCheck); + indir->gtFlags |= indirFlags; + result->AddStatement(indir); + UpdateEarlyRefCount(addrForNullCheck); + } + + GenTree* addr = m_compiler->gtCloneExpr(src->AsIndir()->Addr()); + UpdateEarlyRefCount(addr); + if (srcOffs != 0) + { + var_types addrType = varTypeIsGC(addr) ? TYP_BYREF : TYP_I_IMPL; + addr = + m_compiler->gtNewOperNode(GT_ADD, addrType, addr, m_compiler->gtNewIconNode(srcOffs, TYP_I_IMPL)); + } + + GenTree* dstLcl = m_compiler->gtNewLclvNode(rep->LclNum, rep->AccessType); + srcFld = m_compiler->gtNewIndir(rep->AccessType, addr, indirFlags); + } + + result->AddStatement(m_compiler->gtNewAssignNode(dstLcl, srcFld)); + rep->Handled = true; + } +} + +//------------------------------------------------------------------------ +// UpdateEarlyRefCount: +// Update early ref counts if necessary for the specified IR node. +// +// Parameters: +// candidate - the IR node that may be a local that should have its early ref counts updated. +// +void ReplaceVisitor::UpdateEarlyRefCount(GenTree* candidate) +{ + if (!candidate->OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_LCL_ADDR)) + { + return; + } + + IncrementRefCount(candidate->AsLclVarCommon()->GetLclNum()); + + LclVarDsc* varDsc = m_compiler->lvaGetDesc(candidate->AsLclVarCommon()); + if (varDsc->lvIsStructField) + { + IncrementRefCount(varDsc->lvParentLcl); + } + + if (varDsc->lvPromoted) + { + for (unsigned fldLclNum = varDsc->lvFieldLclStart; fldLclNum < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; + fldLclNum++) + { + IncrementRefCount(fldLclNum); + } + } +} + +//------------------------------------------------------------------------ +// IncrementRefCount: +// Increment the ref count for the specified local. +// +// Parameters: +// lclNum - the local +// +void ReplaceVisitor::IncrementRefCount(unsigned lclNum) +{ + LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); + varDsc->incLvRefCntSaturating(1, RCS_EARLY); +} diff --git a/src/coreclr/jit/rangecheck.cpp b/src/coreclr/jit/rangecheck.cpp index f9ad4c2c365006..b27528e486b62e 100644 --- a/src/coreclr/jit/rangecheck.cpp +++ b/src/coreclr/jit/rangecheck.cpp @@ -70,7 +70,8 @@ RangeCheck::OverflowMap* RangeCheck::GetOverflowMap() int RangeCheck::GetArrLength(ValueNum vn) { ValueNum arrRefVN = m_pCompiler->vnStore->GetArrForLenVn(vn); - return m_pCompiler->vnStore->GetNewArrSize(arrRefVN); + int size; + return m_pCompiler->vnStore->TryGetNewArrSize(arrRefVN, &size) ? size : 0; } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/rationalize.cpp b/src/coreclr/jit/rationalize.cpp index 53f91a76ea32da..fcb4df3129e239 100644 --- a/src/coreclr/jit/rationalize.cpp +++ b/src/coreclr/jit/rationalize.cpp @@ -6,28 +6,6 @@ #pragma hdrstop #endif -// return op that is the store equivalent of the given load opcode -genTreeOps storeForm(genTreeOps loadForm) -{ - switch (loadForm) - { - case GT_LCL_VAR: - return GT_STORE_LCL_VAR; - case GT_LCL_FLD: - return GT_STORE_LCL_FLD; - default: - noway_assert(!"not a data load opcode\n"); - unreached(); - } -} - -// copy the flags determined by mask from src to dst -void copyFlags(GenTree* dst, GenTree* src, GenTreeFlags mask) -{ - dst->gtFlags &= ~mask; - dst->gtFlags |= (src->gtFlags & mask); -} - // RewriteNodeAsCall : Replace the given tree node by a GT_CALL. // // Arguments: @@ -211,30 +189,6 @@ void Rationalizer::SanityCheck() for (Statement* const stmt : block->Statements()) { ValidateStatement(stmt, block); - - for (GenTree* const tree : stmt->TreeList()) - { - // QMARK nodes should have been removed before this phase. - assert(!tree->OperIs(GT_QMARK)); - - if (tree->OperGet() == GT_ASG) - { - if (tree->gtGetOp1()->OperGet() == GT_LCL_VAR) - { - assert(tree->gtGetOp1()->gtFlags & GTF_VAR_DEF); - } - else if (tree->gtGetOp2()->OperGet() == GT_LCL_VAR) - { - assert(!(tree->gtGetOp2()->gtFlags & GTF_VAR_DEF)); - } - - if (tree->OperIsInitBlkOp()) - { - // No SIMD types are allowed for InitBlks (including zero-inits). - assert(tree->TypeIs(TYP_STRUCT) && tree->gtGetOp1()->TypeIs(TYP_STRUCT)); - } - } - } } } } @@ -248,122 +202,6 @@ void Rationalizer::SanityCheckRational() #endif // DEBUG -static void RewriteAssignmentIntoStoreLclCore(GenTreeOp* assignment, - GenTree* location, - GenTree* value, - genTreeOps locationOp) -{ - assert(assignment != nullptr); - assert(assignment->OperGet() == GT_ASG); - assert(location != nullptr); - assert(value != nullptr); - - genTreeOps storeOp = storeForm(locationOp); - -#ifdef DEBUG - JITDUMP("rewriting asg(%s, X) to %s(X)\n", GenTree::OpName(locationOp), GenTree::OpName(storeOp)); -#endif // DEBUG - - assignment->SetOper(storeOp); - GenTreeLclVarCommon* store = assignment->AsLclVarCommon(); - - GenTreeLclVarCommon* var = location->AsLclVarCommon(); - store->SetLclNum(var->GetLclNum()); - store->SetSsaNum(var->GetSsaNum()); - - if (locationOp == GT_LCL_FLD) - { - store->AsLclFld()->SetLclOffs(var->AsLclFld()->GetLclOffs()); - store->AsLclFld()->SetLayout(var->AsLclFld()->GetLayout()); - } - - copyFlags(store, var, (GTF_LIVENESS_MASK | GTF_VAR_MULTIREG)); - store->gtFlags &= ~GTF_REVERSE_OPS; - - store->gtType = var->TypeGet(); - store->gtOp1 = value; - - DISPNODE(store); - JITDUMP("\n"); -} - -void Rationalizer::RewriteAssignmentIntoStoreLcl(GenTreeOp* assignment) -{ - assert(assignment != nullptr); - assert(assignment->OperGet() == GT_ASG); - - GenTree* location = assignment->gtGetOp1(); - GenTree* value = assignment->gtGetOp2(); - - RewriteAssignmentIntoStoreLclCore(assignment, location, value, location->OperGet()); -} - -void Rationalizer::RewriteAssignment(LIR::Use& use) -{ - assert(use.IsInitialized()); - - GenTreeOp* assignment = use.Def()->AsOp(); - assert(assignment->OperGet() == GT_ASG); - - GenTree* location = assignment->gtGetOp1(); - GenTree* value = assignment->gtGetOp2(); - - genTreeOps locationOp = location->OperGet(); - - switch (locationOp) - { - case GT_LCL_VAR: - case GT_LCL_FLD: - RewriteAssignmentIntoStoreLclCore(assignment, location, value, locationOp); - BlockRange().Remove(location); - break; - - case GT_IND: - { - GenTreeStoreInd* store = - new (comp, GT_STOREIND) GenTreeStoreInd(location->TypeGet(), location->gtGetOp1(), value); - - copyFlags(store, assignment, GTF_ALL_EFFECT); - copyFlags(store, location, GTF_IND_FLAGS); - - // TODO: JIT dump - - // Remove the GT_IND node and replace the assignment node with the store - BlockRange().Remove(location); - BlockRange().InsertBefore(assignment, store); - use.ReplaceWith(store); - BlockRange().Remove(assignment); - } - break; - - case GT_BLK: - { - assert(varTypeIsStruct(location)); - JITDUMP("Rewriting GT_ASG(%s(X), Y) to STORE_BLK(X,Y):\n", GenTree::OpName(location->gtOper)); - - GenTreeBlk* storeBlk = location->AsBlk(); - storeBlk->SetOperRaw(GT_STORE_BLK); - storeBlk->gtFlags &= ~GTF_DONT_CSE; - storeBlk->gtFlags |= (assignment->gtFlags & (GTF_ALL_EFFECT | GTF_DONT_CSE)); - storeBlk->AsBlk()->Data() = value; - - // Remove the block node from its current position and replace the assignment node with it - // (now in its store form). - BlockRange().Remove(storeBlk); - BlockRange().InsertBefore(assignment, storeBlk); - use.ReplaceWith(storeBlk); - BlockRange().Remove(assignment); - DISPTREERANGE(BlockRange(), use.Def()); - JITDUMP("\n"); - } - break; - - default: - unreached(); - break; - } -} - Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::GenTreeStack& parentStack) { assert(useEdge != nullptr); @@ -387,10 +225,6 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge assert(node == use.Def()); switch (node->OperGet()) { - case GT_ASG: - RewriteAssignment(use); - break; - case GT_CALL: // In linear order we no longer need to retain the stores in early // args as these have now been sequenced. @@ -508,9 +342,9 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge } else { - if (!node->OperIsStore()) + if (((node->gtFlags & GTF_ASG) != 0) && !node->OperRequiresAsgFlag()) { - // Clear the GTF_ASG flag for all nodes but stores + // Clear the GTF_ASG flag for all nodes that do not require it node->gtFlags &= ~GTF_ASG; } diff --git a/src/coreclr/jit/rationalize.h b/src/coreclr/jit/rationalize.h index 44e2546312c61e..65264f8294582c 100644 --- a/src/coreclr/jit/rationalize.h +++ b/src/coreclr/jit/rationalize.h @@ -29,8 +29,6 @@ class Rationalizer final : public Phase virtual PhaseStatus DoPhase() override; - static void RewriteAssignmentIntoStoreLcl(GenTreeOp* assignment); - private: inline LIR::Range& BlockRange() const { @@ -49,9 +47,6 @@ class Rationalizer final : public Phase void RewriteIntrinsicAsUserCall(GenTree** use, Compiler::GenTreeStack& parents); - // Other transformations - void RewriteAssignment(LIR::Use& use); - #ifdef TARGET_ARM64 void RewriteSubLshDiv(GenTree** use); #endif diff --git a/src/coreclr/jit/redundantbranchopts.cpp b/src/coreclr/jit/redundantbranchopts.cpp index c6cfcf42a2d7d3..d0c0ca98cf7f58 100644 --- a/src/coreclr/jit/redundantbranchopts.cpp +++ b/src/coreclr/jit/redundantbranchopts.cpp @@ -1167,6 +1167,14 @@ bool Compiler::optJumpThreadPhi(BasicBlock* block, GenTree* tree, ValueNum treeN return false; } + // Bypass handler blocks, as they can have unusual PHI args. + // In particular multiple SSA defs coming from the same block. + // + if (bbIsHandlerBeg(block)) + { + return false; + } + // Find occurrences of phi def VNs in the relop VN. // We currently just do one level of func destructuring. // @@ -1273,15 +1281,12 @@ bool Compiler::optJumpThreadPhi(BasicBlock* block, GenTree* tree, ValueNum treeN ValueNum phiArgVN = phiArgNode->GetVN(VNK_Liberal); // We sometimes see cases where phi args do not have VNs. - // (I recall seeing this before... track down why) + // (VN works in RPO, so PHIs from back edges won't have VNs. // if (phiArgVN != ValueNumStore::NoVN) { newRelopArgs[i] = phiArgVN; updatedArg = true; - - // paranoia: keep walking uses to make sure no other - // comes from this pred break; } } diff --git a/src/coreclr/jit/scopeinfo.cpp b/src/coreclr/jit/scopeinfo.cpp index 2278f18655567a..8bc75c50813d6d 100644 --- a/src/coreclr/jit/scopeinfo.cpp +++ b/src/coreclr/jit/scopeinfo.cpp @@ -961,7 +961,7 @@ void CodeGen::psiBegProlog() else { regType = compiler->mangleVarArgsType(lclVarDsc->TypeGet()); -#ifdef TARGET_LOONGARCH +#ifdef TARGET_LOONGARCH64 if (emitter::isGeneralRegisterOrR0(lclVarDsc->GetArgReg()) && isFloatRegType(regType)) { // For LoongArch64's ABI, the float args may be passed by integer register. diff --git a/src/coreclr/jit/sideeffects.cpp b/src/coreclr/jit/sideeffects.cpp index 205166c42c78a7..cf0b3210e38535 100644 --- a/src/coreclr/jit/sideeffects.cpp +++ b/src/coreclr/jit/sideeffects.cpp @@ -174,12 +174,7 @@ AliasSet::NodeInfo::NodeInfo(Compiler* compiler, GenTree* node) // Is the operation a write? If so, set `node` to the location that is being written to. bool isWrite = false; - if (node->OperIs(GT_ASG)) - { - isWrite = true; - node = node->gtGetOp1(); - } - else if (node->OperIsStore() || node->OperIs(GT_MEMORYBARRIER)) + if (node->OperIsStore() || node->OperIs(GT_STORE_DYN_BLK, GT_MEMORYBARRIER)) { isWrite = true; } diff --git a/src/coreclr/jit/simd.cpp b/src/coreclr/jit/simd.cpp index 67c5fa1dd0c3a9..c0294ad3f91fb6 100644 --- a/src/coreclr/jit/simd.cpp +++ b/src/coreclr/jit/simd.cpp @@ -473,23 +473,26 @@ void Compiler::setLclRelatedToSIMDIntrinsic(GenTree* tree) } //------------------------------------------------------------- -// Check if two field nodes reference at the same memory location. -// Notice that this check is just based on pattern matching. +// Check if two field address nodes reference at the same location. +// // Arguments: -// op1 - GenTree*. -// op2 - GenTree*. +// op1 - first field address +// op2 - second field address +// // Return Value: -// If op1's parents node and op2's parents node are at the same location, return true. Otherwise, return false - -bool areFieldsParentsLocatedSame(GenTree* op1, GenTree* op2) +// If op1's parents node and op2's parents node are at the same +// location, return true. Otherwise, return false +// +bool areFieldAddressesTheSame(GenTreeFieldAddr* op1, GenTreeFieldAddr* op2) { - assert(op1->OperGet() == GT_FIELD); - assert(op2->OperGet() == GT_FIELD); + assert(op1->OperIs(GT_FIELD_ADDR) && op2->OperIs(GT_FIELD_ADDR)); - GenTree* op1ObjRef = op1->AsField()->GetFldObj(); - GenTree* op2ObjRef = op2->AsField()->GetFldObj(); - while (op1ObjRef != nullptr && op2ObjRef != nullptr) + GenTree* op1ObjRef = op1->GetFldObj(); + GenTree* op2ObjRef = op2->GetFldObj(); + while ((op1ObjRef != nullptr) && (op2ObjRef != nullptr)) { + assert(varTypeIsI(genActualType(op1ObjRef)) && varTypeIsI(genActualType(op2ObjRef))); + if (op1ObjRef->OperGet() != op2ObjRef->OperGet()) { break; @@ -501,10 +504,18 @@ bool areFieldsParentsLocatedSame(GenTree* op1, GenTree* op2) return true; } - if (op1ObjRef->OperIs(GT_FIELD) && (op1ObjRef->AsField()->gtFldHnd == op2ObjRef->AsField()->gtFldHnd)) + if (op1ObjRef->OperIs(GT_IND)) + { + op1ObjRef = op1ObjRef->AsIndir()->Addr(); + op2ObjRef = op2ObjRef->AsIndir()->Addr(); + continue; + } + + if (op1ObjRef->OperIs(GT_FIELD_ADDR) && + (op1ObjRef->AsFieldAddr()->gtFldHnd == op2ObjRef->AsFieldAddr()->gtFldHnd)) { - op1ObjRef = op1ObjRef->AsField()->GetFldObj(); - op2ObjRef = op2ObjRef->AsField()->GetFldObj(); + op1ObjRef = op1ObjRef->AsFieldAddr()->GetFldObj(); + op2ObjRef = op2ObjRef->AsFieldAddr()->GetFldObj(); continue; } else @@ -517,28 +528,29 @@ bool areFieldsParentsLocatedSame(GenTree* op1, GenTree* op2) } //---------------------------------------------------------------------- -// Check whether two field are contiguous +// areFieldsContiguous: Check whether two fields are contiguous. +// // Arguments: -// first - GenTree*. The Type of the node should be TYP_FLOAT -// second - GenTree*. The Type of the node should be TYP_FLOAT +// op1 - The first field indirection +// op2 - The second field indirection +// // Return Value: -// if the first field is located before second field, and they are located contiguously, -// then return true. Otherwise, return false. - -bool Compiler::areFieldsContiguous(GenTree* first, GenTree* second) +// If the first field is located before second field, and they are +// located contiguously, then return true. Otherwise, return false. +// +bool Compiler::areFieldsContiguous(GenTreeIndir* op1, GenTreeIndir* op2) { - assert(first->OperGet() == GT_FIELD); - assert(second->OperGet() == GT_FIELD); - assert(first->gtType == TYP_FLOAT); - assert(second->gtType == TYP_FLOAT); - - var_types firstFieldType = first->gtType; - var_types secondFieldType = second->gtType; - - unsigned firstFieldEndOffset = first->AsField()->gtFldOffset + genTypeSize(firstFieldType); - unsigned secondFieldOffset = second->AsField()->gtFldOffset; - if (firstFieldEndOffset == secondFieldOffset && firstFieldType == secondFieldType && - areFieldsParentsLocatedSame(first, second)) + assert(op1->OperIs(GT_IND) && op2->OperIs(GT_IND)); + // TODO-1stClassStructs: delete once IND nodes are no more. + assert(!op1->TypeIs(TYP_STRUCT) && !op2->TypeIs(TYP_STRUCT)); + + var_types op1Type = op1->TypeGet(); + var_types op2Type = op2->TypeGet(); + GenTreeFieldAddr* op1Addr = op1->Addr()->AsFieldAddr(); + GenTreeFieldAddr* op2Addr = op2->Addr()->AsFieldAddr(); + unsigned op1EndOffset = op1Addr->gtFldOffset + genTypeSize(op1Type); + unsigned op2Offset = op2Addr->gtFldOffset; + if ((op1Type == op2Type) && (op1EndOffset == op2Offset) && areFieldAddressesTheSame(op1Addr, op2Addr)) { return true; } @@ -594,19 +606,25 @@ bool Compiler::areArrayElementsContiguous(GenTree* op1, GenTree* op2) GenTree* op1IndexNode = op1IndexAddr->Index(); GenTree* op2IndexNode = op2IndexAddr->Index(); if ((op1IndexNode->OperGet() == GT_CNS_INT && op2IndexNode->OperGet() == GT_CNS_INT) && - op1IndexNode->AsIntCon()->gtIconVal + 1 == op2IndexNode->AsIntCon()->gtIconVal) + (op1IndexNode->AsIntCon()->gtIconVal + 1 == op2IndexNode->AsIntCon()->gtIconVal)) { - if (op1ArrayRef->OperIs(GT_FIELD) && op2ArrayRef->OperIs(GT_FIELD) && - areFieldsParentsLocatedSame(op1ArrayRef, op2ArrayRef)) + if (op1ArrayRef->OperIs(GT_IND) && op2ArrayRef->OperIs(GT_IND)) { - return true; + GenTree* op1ArrayRefAddr = op1ArrayRef->AsIndir()->Addr(); + GenTree* op2ArrayRefAddr = op2ArrayRef->AsIndir()->Addr(); + if (op1ArrayRefAddr->OperIs(GT_FIELD_ADDR) && op2ArrayRefAddr->OperIs(GT_FIELD_ADDR) && + areFieldAddressesTheSame(op1ArrayRefAddr->AsFieldAddr(), op2ArrayRefAddr->AsFieldAddr())) + { + return true; + } } else if (op1ArrayRef->OperIs(GT_LCL_VAR) && op2ArrayRef->OperIs(GT_LCL_VAR) && - op1ArrayRef->AsLclVarCommon()->GetLclNum() == op2ArrayRef->AsLclVarCommon()->GetLclNum()) + (op1ArrayRef->AsLclVar()->GetLclNum() == op2ArrayRef->AsLclVar()->GetLclNum())) { return true; } } + return false; } @@ -630,19 +648,25 @@ bool Compiler::areArgumentsContiguous(GenTree* op1, GenTree* op2) assert(!op1->TypeIs(TYP_STRUCT)); - if (op1->OperIs(GT_IND) && op1->AsIndir()->Addr()->OperIs(GT_INDEX_ADDR) && op2->OperIs(GT_IND) && - op2->AsIndir()->Addr()->OperIs(GT_INDEX_ADDR)) - { - return areArrayElementsContiguous(op1, op2); - } - else if (op1->OperIs(GT_FIELD) && op2->OperIs(GT_FIELD)) + if (op1->OperIs(GT_IND) && op2->OperIs(GT_IND)) { - return areFieldsContiguous(op1, op2); + GenTree* op1Addr = op1->AsIndir()->Addr(); + GenTree* op2Addr = op2->AsIndir()->Addr(); + + if (op1Addr->OperIs(GT_INDEX_ADDR) && op2Addr->OperIs(GT_INDEX_ADDR)) + { + return areArrayElementsContiguous(op1, op2); + } + if (op1Addr->OperIs(GT_FIELD_ADDR) && op2Addr->OperIs(GT_FIELD_ADDR)) + { + return areFieldsContiguous(op1->AsIndir(), op2->AsIndir()); + } } else if (op1->OperIs(GT_LCL_FLD) && op2->OperIs(GT_LCL_FLD)) { return areLocalFieldsContiguous(op1->AsLclFld(), op2->AsLclFld()); } + return false; } @@ -659,19 +683,23 @@ bool Compiler::areArgumentsContiguous(GenTree* op1, GenTree* op2) // return the address node. // // TODO-CQ: -// Currently just supports GT_FIELD and GT_IND(GT_INDEX_ADDR), because we can only verify those nodes +// Currently just supports GT_IND(GT_INDEX_ADDR / GT_FIELD_ADDR), because we can only verify those nodes // are located contiguously or not. In future we should support more cases. // GenTree* Compiler::CreateAddressNodeForSimdHWIntrinsicCreate(GenTree* tree, var_types simdBaseType, unsigned simdSize) { + assert(tree->OperIs(GT_IND)); + GenTree* addr = tree->AsIndir()->Addr(); GenTree* byrefNode = nullptr; unsigned offset = 0; var_types baseType = tree->gtType; - if (tree->OperIs(GT_FIELD)) + if (addr->OperIs(GT_FIELD_ADDR)) { - GenTree* objRef = tree->AsField()->GetFldObj(); - if ((objRef != nullptr) && objRef->IsLclVarAddr()) + assert(addr->AsFieldAddr()->IsInstance()); + + GenTree* objRef = addr->AsFieldAddr()->GetFldObj(); + if (objRef->IsLclVarAddr()) { // If the field is directly from a struct, then in this case, // we should set this struct's lvUsedInSIMDIntrinsic as true, @@ -690,17 +718,15 @@ GenTree* Compiler::CreateAddressNodeForSimdHWIntrinsicCreate(GenTree* tree, var_ } } - byrefNode = gtCloneExpr(tree->AsField()->GetFldObj()); + // TODO-FIELD: this seems unnecessary. Simply "return addr;"? + byrefNode = gtCloneExpr(objRef); assert(byrefNode != nullptr); - offset = tree->AsField()->gtFldOffset; + offset = addr->AsFieldAddr()->gtFldOffset; } else { - assert(tree->OperIs(GT_IND) && tree->AsIndir()->Addr()->OperIs(GT_INDEX_ADDR)); - - GenTreeIndexAddr* indexAddr = tree->AsIndir()->Addr()->AsIndexAddr(); - GenTree* arrayRef = indexAddr->Arr(); - GenTree* index = indexAddr->Index(); + GenTree* arrayRef = addr->AsIndexAddr()->Arr(); + GenTree* index = addr->AsIndexAddr()->Index(); assert(index->IsCnsIntOrI()); GenTree* checkIndexExpr = nullptr; @@ -780,12 +806,16 @@ void Compiler::impMarkContiguousSIMDFieldAssignments(Statement* stmt) // Successfully found the pattern, mark the lclvar as UsedInSIMDIntrinsic setLclRelatedToSIMDIntrinsic(srcSimdLclAddr); - if (curDst->OperIs(GT_FIELD) && curDst->AsField()->IsInstance()) + if (curDst->OperIs(GT_IND) && curDst->AsIndir()->Addr()->OperIs(GT_FIELD_ADDR)) { - GenTree* objRef = curDst->AsField()->GetFldObj(); - if (objRef->IsLclVarAddr() && varTypeIsStruct(lvaGetDesc(objRef->AsLclFld()))) + GenTreeFieldAddr* addr = curDst->AsIndir()->Addr()->AsFieldAddr(); + if (addr->IsInstance()) { - setLclRelatedToSIMDIntrinsic(objRef); + GenTree* objRef = addr->GetFldObj(); + if (objRef->IsLclVarAddr() && varTypeIsStruct(lvaGetDesc(objRef->AsLclFld()))) + { + setLclRelatedToSIMDIntrinsic(objRef); + } } } } diff --git a/src/coreclr/jit/simd.h b/src/coreclr/jit/simd.h index bea264d947a392..fcadaf0d9249ad 100644 --- a/src/coreclr/jit/simd.h +++ b/src/coreclr/jit/simd.h @@ -53,7 +53,9 @@ struct simd8_t return {}; } }; +static_assert_no_msg(sizeof(simd8_t) == 8); +#include struct simd12_t { union { @@ -109,6 +111,8 @@ struct simd12_t return {}; } }; +#include +static_assert_no_msg(sizeof(simd12_t) == 12); struct simd16_t { @@ -161,6 +165,7 @@ struct simd16_t return {}; } }; +static_assert_no_msg(sizeof(simd16_t) == 16); #if defined(TARGET_XARCH) struct simd32_t @@ -215,6 +220,7 @@ struct simd32_t return {}; } }; +static_assert_no_msg(sizeof(simd32_t) == 32); struct simd64_t { @@ -269,6 +275,7 @@ struct simd64_t return {}; } }; +static_assert_no_msg(sizeof(simd64_t) == 64); typedef simd64_t simd_t; #else diff --git a/src/coreclr/jit/simdashwintrinsic.cpp b/src/coreclr/jit/simdashwintrinsic.cpp index 516c826c72c636..76ceb5f0749aec 100644 --- a/src/coreclr/jit/simdashwintrinsic.cpp +++ b/src/coreclr/jit/simdashwintrinsic.cpp @@ -1906,7 +1906,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, else if (areArgumentsContiguous(op2, op3)) { GenTree* op2Address = CreateAddressNodeForSimdHWIntrinsicCreate(op2, simdBaseType, 8); - copyBlkSrc = gtNewOperNode(GT_IND, TYP_SIMD8, op2Address); + copyBlkSrc = gtNewIndir(TYP_SIMD8, op2Address); } else { @@ -2046,7 +2046,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, else if (areArgumentsContiguous(op2, op3) && areArgumentsContiguous(op3, op4)) { GenTree* op2Address = CreateAddressNodeForSimdHWIntrinsicCreate(op2, simdBaseType, 12); - copyBlkSrc = gtNewOperNode(GT_IND, TYP_SIMD12, op2Address); + copyBlkSrc = gtNewIndir(TYP_SIMD12, op2Address); } else { @@ -2173,7 +2173,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, areArgumentsContiguous(op4, op5)) { GenTree* op2Address = CreateAddressNodeForSimdHWIntrinsicCreate(op2, simdBaseType, 16); - copyBlkSrc = gtNewOperNode(GT_IND, TYP_SIMD16, op2Address); + copyBlkSrc = gtNewIndir(TYP_SIMD16, op2Address); } else { @@ -2206,9 +2206,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, if (copyBlkDst != nullptr) { assert(copyBlkSrc != nullptr); - GenTree* dest = gtNewLoadValueNode(simdType, copyBlkDst); - dest->gtFlags |= GTF_GLOB_REF; - + GenTree* dest = gtNewLoadValueNode(simdType, copyBlkDst); GenTree* retNode = gtNewBlkOpNode(dest, copyBlkSrc); return retNode; diff --git a/src/coreclr/jit/simdcodegenxarch.cpp b/src/coreclr/jit/simdcodegenxarch.cpp index c01b59bb8606c4..9cfdbde351a1ad 100644 --- a/src/coreclr/jit/simdcodegenxarch.cpp +++ b/src/coreclr/jit/simdcodegenxarch.cpp @@ -511,5 +511,46 @@ void CodeGen::genSimdUpperRestore(GenTreeIntrinsic* node) } } +//----------------------------------------------------------------------------- +// genSimd12UpperClear: Clears the upper 32-bits of a TYP_SIMD12 vector +// +// Arguments: +// tgtReg - The target register for which to clear the upper bits +// +// Return Value: +// None. +// +void CodeGen::genSimd12UpperClear(regNumber tgtReg) +{ + assert(genIsValidFloatReg(tgtReg)); + + if (compiler->compOpportunisticallyDependsOn(InstructionSet_SSE41)) + { + // ZMASK: 0b1000 - Preserve element 0, 1, and 2; Zero element 3 + // COUNT_D: 0b11 - Insert into element 3 + // COUNT_S: 0b11 - Insert from element 3 + + GetEmitter()->emitIns_SIMD_R_R_R_I(INS_insertps, EA_16BYTE, tgtReg, tgtReg, tgtReg, static_cast(0xF8)); + } + else + { + // Preserve element 0, 1, and 2; Zero element 3 + + if (zroSimd12Elm3 == NO_FIELD_HANDLE) + { + simd16_t constValue; + + constValue.u32[0] = 0xFFFFFFFF; + constValue.u32[1] = 0xFFFFFFFF; + constValue.u32[2] = 0xFFFFFFFF; + constValue.u32[3] = 0x00000000; + + zroSimd12Elm3 = GetEmitter()->emitSimd16Const(constValue); + } + + GetEmitter()->emitIns_SIMD_R_R_C(INS_andps, EA_16BYTE, tgtReg, tgtReg, zroSimd12Elm3, 0); + } +} + #endif // FEATURE_SIMD #endif // TARGET_XARCH diff --git a/src/coreclr/jit/ssabuilder.cpp b/src/coreclr/jit/ssabuilder.cpp index b3428e93891fc1..2eb9dddbd927b2 100644 --- a/src/coreclr/jit/ssabuilder.cpp +++ b/src/coreclr/jit/ssabuilder.cpp @@ -551,7 +551,8 @@ void SsaBuilder::InsertPhi(BasicBlock* block, unsigned lclNum) } //------------------------------------------------------------------------ -// AddPhiArg: Add a new GT_PHI_ARG node to an existing GT_PHI node. +// AddPhiArg: Ensure an existing GT_PHI node contains an appropriate PhiArg +// for an ssa def arriving via pred // // Arguments: // block - The block that contains the statement @@ -563,14 +564,32 @@ void SsaBuilder::InsertPhi(BasicBlock* block, unsigned lclNum) void SsaBuilder::AddPhiArg( BasicBlock* block, Statement* stmt, GenTreePhi* phi, unsigned lclNum, unsigned ssaNum, BasicBlock* pred) { -#ifdef DEBUG - // Make sure it isn't already present: we should only add each definition once. + // If there's already a phi arg for this pred, it had better have + // matching ssaNum, unless this block is a handler entry. + // + const bool isHandlerEntry = m_pCompiler->bbIsHandlerBeg(block); + for (GenTreePhi::Use& use : phi->Uses()) { - assert(use.GetNode()->AsPhiArg()->GetSsaNum() != ssaNum); + GenTreePhiArg* const phiArg = use.GetNode()->AsPhiArg(); + + if (phiArg->gtPredBB == pred) + { + if (phiArg->GetSsaNum() == ssaNum) + { + // We already have this (pred, ssaNum) phiArg + return; + } + + // Add another ssaNum for this pred? + // Should only be possible at handler entries. + // + noway_assert(isHandlerEntry); + } } -#endif // DEBUG + // Didn't find a match, add a new phi arg + // var_types type = m_pCompiler->lvaGetDesc(lclNum)->TypeGet(); GenTree* phiArg = new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(type, lclNum, ssaNum, pred); @@ -1186,29 +1205,12 @@ void SsaBuilder::AddPhiArgsToSuccessors(BasicBlock* block) break; } - GenTree* tree = stmt->GetRootNode(); - GenTreePhi* phi = tree->gtGetOp2()->AsPhi(); - - unsigned lclNum = tree->AsOp()->gtOp1->AsLclVar()->GetLclNum(); - unsigned ssaNum = m_renameStack.Top(lclNum); - // Search the arglist for an existing definition for ssaNum. - // (Can we assert that its the head of the list? This should only happen when we add - // during renaming for a definition that occurs within a try, and then that's the last - // value of the var within that basic block.) + GenTree* tree = stmt->GetRootNode(); + GenTreePhi* phi = tree->gtGetOp2()->AsPhi(); + unsigned lclNum = tree->AsOp()->gtOp1->AsLclVar()->GetLclNum(); + unsigned ssaNum = m_renameStack.Top(lclNum); - bool found = false; - for (GenTreePhi::Use& use : phi->Uses()) - { - if (use.GetNode()->AsPhiArg()->GetSsaNum() == ssaNum) - { - found = true; - break; - } - } - if (!found) - { - AddPhiArg(succ, stmt, phi, lclNum, ssaNum, block); - } + AddPhiArg(succ, stmt, phi, lclNum, ssaNum, block); } // Now handle memory. @@ -1333,24 +1335,10 @@ void SsaBuilder::AddPhiArgsToSuccessors(BasicBlock* block) continue; } - GenTreePhi* phi = tree->gtGetOp2()->AsPhi(); - - unsigned ssaNum = m_renameStack.Top(lclNum); + GenTreePhi* phi = tree->gtGetOp2()->AsPhi(); + unsigned ssaNum = m_renameStack.Top(lclNum); - // See if this ssaNum is already an arg to the phi. - bool alreadyArg = false; - for (GenTreePhi::Use& use : phi->Uses()) - { - if (use.GetNode()->AsPhiArg()->GetSsaNum() == ssaNum) - { - alreadyArg = true; - break; - } - } - if (!alreadyArg) - { - AddPhiArg(handlerStart, stmt, phi, lclNum, ssaNum, block); - } + AddPhiArg(handlerStart, stmt, phi, lclNum, ssaNum, block); } // Now handle memory. diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index 605f0cc1d5d465..ad7e5be605199a 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -38,7 +38,7 @@ inline bool compMacOsArm64Abi() } inline bool compFeatureArgSplit() { - return TargetArchitecture::IsLoongArch64 || TargetArchitecture::IsArm32 || + return TargetArchitecture::IsLoongArch64 || TargetArchitecture::IsArm32 || TargetArchitecture::IsRiscv64 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); } inline bool compUnixX86Abi() @@ -378,6 +378,18 @@ inline bool genIsValidIntReg(regNumber reg) return reg >= REG_INT_FIRST && reg <= REG_INT_LAST; } +/***************************************************************************** + * Return true if the register is a valid integer or fake register + */ +inline bool genIsValidIntOrFakeReg(regNumber reg) +{ +#if defined(TARGET_ARM64) + return genIsValidIntReg(reg) || (reg == REG_SP); +#else + return genIsValidIntReg(reg); +#endif +} + /***************************************************************************** * Return true if the register is a valid floating point register */ @@ -386,6 +398,16 @@ inline bool genIsValidFloatReg(regNumber reg) return reg >= REG_FP_FIRST && reg <= REG_FP_LAST; } +#if defined(TARGET_XARCH) +/***************************************************************************** + * Return true if the register is a valid mask register + */ +inline bool genIsValidMaskReg(regNumber reg) +{ + return reg >= REG_MASK_FIRST && reg <= REG_MASK_LAST; +} +#endif // TARGET_XARCH + #ifdef TARGET_ARM /***************************************************************************** diff --git a/src/coreclr/jit/unwindamd64.cpp b/src/coreclr/jit/unwindamd64.cpp index b5fdf604e55ed8..549c4e9910567c 100644 --- a/src/coreclr/jit/unwindamd64.cpp +++ b/src/coreclr/jit/unwindamd64.cpp @@ -86,6 +86,8 @@ short Compiler::mapRegNumToDwarfReg(regNumber reg) // void Compiler::unwindBegProlog() { + assert(!compGeneratingUnwindProlog); + compGeneratingUnwindProlog = true; #ifdef UNIX_AMD64_ABI if (generateCFIUnwindCodes()) { @@ -129,6 +131,8 @@ void Compiler::unwindBegPrologWindows() void Compiler::unwindEndProlog() { assert(compGeneratingProlog); + assert(compGeneratingUnwindProlog); + compGeneratingUnwindProlog = false; } //------------------------------------------------------------------------ @@ -138,6 +142,8 @@ void Compiler::unwindEndProlog() void Compiler::unwindBegEpilog() { assert(compGeneratingEpilog); + assert(!compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = true; } //------------------------------------------------------------------------ @@ -147,6 +153,8 @@ void Compiler::unwindBegEpilog() void Compiler::unwindEndEpilog() { assert(compGeneratingEpilog); + assert(compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = false; } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/unwindarm.cpp b/src/coreclr/jit/unwindarmarch.cpp similarity index 99% rename from src/coreclr/jit/unwindarm.cpp rename to src/coreclr/jit/unwindarmarch.cpp index bec57b68670dd2..b54ce016c16a52 100644 --- a/src/coreclr/jit/unwindarm.cpp +++ b/src/coreclr/jit/unwindarmarch.cpp @@ -126,8 +126,6 @@ short Compiler::mapRegNumToDwarfReg(regNumber reg) } #endif // TARGET_ARM && FEATURE_CFI_SUPPORT -#ifdef TARGET_ARMARCH - /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX XX @@ -140,6 +138,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void Compiler::unwindBegProlog() { assert(compGeneratingProlog); + assert(!compGeneratingUnwindProlog); + compGeneratingUnwindProlog = true; #if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) @@ -167,11 +167,15 @@ void Compiler::unwindBegProlog() void Compiler::unwindEndProlog() { assert(compGeneratingProlog); + assert(compGeneratingUnwindProlog); + compGeneratingUnwindProlog = false; } void Compiler::unwindBegEpilog() { assert(compGeneratingEpilog); + assert(!compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = true; #if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) @@ -186,6 +190,8 @@ void Compiler::unwindBegEpilog() void Compiler::unwindEndEpilog() { assert(compGeneratingEpilog); + assert(compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = false; } #if defined(TARGET_ARM) @@ -2579,5 +2585,3 @@ void DumpUnwindInfo(Compiler* comp, #endif // DEBUG #endif // defined(TARGET_ARM) - -#endif // TARGET_ARMARCH diff --git a/src/coreclr/jit/unwindloongarch64.cpp b/src/coreclr/jit/unwindloongarch64.cpp index 2170961aa813c4..3aa5fd668d40c6 100644 --- a/src/coreclr/jit/unwindloongarch64.cpp +++ b/src/coreclr/jit/unwindloongarch64.cpp @@ -891,6 +891,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void Compiler::unwindBegProlog() { assert(compGeneratingProlog); + assert(!compGeneratingUnwindProlog); + compGeneratingUnwindProlog = true; #if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) @@ -918,11 +920,15 @@ void Compiler::unwindBegProlog() void Compiler::unwindEndProlog() { assert(compGeneratingProlog); + assert(compGeneratingUnwindProlog); + compGeneratingUnwindProlog = false; } void Compiler::unwindBegEpilog() { assert(compGeneratingEpilog); + assert(!compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = true; #if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) @@ -937,6 +943,8 @@ void Compiler::unwindBegEpilog() void Compiler::unwindEndEpilog() { assert(compGeneratingEpilog); + assert(compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = false; } // The instructions between the last captured "current state" and the current instruction diff --git a/src/coreclr/jit/unwindriscv64.cpp b/src/coreclr/jit/unwindriscv64.cpp index f151e7f408800a..e1a9eb06f8e153 100644 --- a/src/coreclr/jit/unwindriscv64.cpp +++ b/src/coreclr/jit/unwindriscv64.cpp @@ -669,6 +669,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void Compiler::unwindBegProlog() { assert(compGeneratingProlog); + assert(!compGeneratingUnwindProlog); + compGeneratingUnwindProlog = true; #if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) @@ -696,11 +698,15 @@ void Compiler::unwindBegProlog() void Compiler::unwindEndProlog() { assert(compGeneratingProlog); + assert(compGeneratingUnwindProlog); + compGeneratingUnwindProlog = false; } void Compiler::unwindBegEpilog() { assert(compGeneratingEpilog); + assert(!compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = true; #if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) @@ -715,6 +721,8 @@ void Compiler::unwindBegEpilog() void Compiler::unwindEndEpilog() { assert(compGeneratingEpilog); + assert(compGeneratingUnwindEpilog); + compGeneratingUnwindEpilog = false; } // The instructions between the last captured "current state" and the current instruction @@ -997,7 +1005,22 @@ int UnwindPrologCodes::Match(UnwindEpilogInfo* pEpi) void UnwindPrologCodes::CopyFrom(UnwindPrologCodes* pCopyFrom) { - NYI_RISCV64("CopyFrom-----unimplemented on RISCV64 yet----"); + assert(uwiComp == pCopyFrom->uwiComp); + assert(upcMem == upcMemLocal); + assert(upcMemSize == UPC_LOCAL_COUNT); + assert(upcHeaderSlot == -1); + assert(upcEpilogSlot == -1); + + // Copy the codes + EnsureSize(pCopyFrom->upcMemSize); + assert(upcMemSize == pCopyFrom->upcMemSize); + memcpy_s(upcMem, upcMemSize, pCopyFrom->upcMem, pCopyFrom->upcMemSize); + + // Copy the other data + upcCodeSlot = pCopyFrom->upcCodeSlot; + upcHeaderSlot = pCopyFrom->upcHeaderSlot; + upcEpilogSlot = pCopyFrom->upcEpilogSlot; + upcUnwindBlockSlot = pCopyFrom->upcUnwindBlockSlot; } void UnwindPrologCodes::EnsureSize(int requiredSize) @@ -1230,7 +1253,8 @@ void UnwindFragmentInfo::AddEpilog() void UnwindFragmentInfo::CopyPrologCodes(UnwindFragmentInfo* pCopyFrom) { - NYI_RISCV64("CopyPrologCodes-----unimplemented on RISCV64 yet----"); + ufiPrologCodes.CopyFrom(&pCopyFrom->ufiPrologCodes); + ufiPrologCodes.AddCode(UWC_END_C); } // Split the epilog codes that currently exist in 'pSplitFrom'. The ones that represent @@ -1240,7 +1264,42 @@ void UnwindFragmentInfo::CopyPrologCodes(UnwindFragmentInfo* pCopyFrom) void UnwindFragmentInfo::SplitEpilogCodes(emitLocation* emitLoc, UnwindFragmentInfo* pSplitFrom) { - NYI_RISCV64("SplitEpilogCodes-----unimplemented on RISCV64 yet----"); + UnwindEpilogInfo* pEpiPrev; + UnwindEpilogInfo* pEpi; + + UNATIVE_OFFSET splitOffset = emitLoc->CodeOffset(uwiComp->GetEmitter()); + + for (pEpiPrev = NULL, pEpi = pSplitFrom->ufiEpilogList; pEpi != NULL; pEpiPrev = pEpi, pEpi = pEpi->epiNext) + { + pEpi->FinalizeOffset(); // Get the offset of the epilog from the emitter so we can compare it + if (pEpi->GetStartOffset() >= splitOffset) + { + // This epilog and all following epilogs, which must be in order of increasing offsets, + // get moved to this fragment. + + // Splice in the epilogs to this fragment. Set the head of the epilog + // list to this epilog. + ufiEpilogList = pEpi; // In this case, don't use 'ufiEpilogFirst' + ufiEpilogLast = pSplitFrom->ufiEpilogLast; + + // Splice out the tail of the list from the 'pSplitFrom' epilog list + pSplitFrom->ufiEpilogLast = pEpiPrev; + if (pSplitFrom->ufiEpilogLast == NULL) + { + pSplitFrom->ufiEpilogList = NULL; + } + else + { + pSplitFrom->ufiEpilogLast->epiNext = NULL; + } + + // No more codes should be added once we start splitting + pSplitFrom->ufiCurCodes = NULL; + ufiCurCodes = NULL; + + break; + } + } } // Is this epilog at the end of an unwind fragment? Ask the emitter. @@ -1794,7 +1853,8 @@ void UnwindInfo::Split() /*static*/ void UnwindInfo::EmitSplitCallback(void* context, emitLocation* emitLoc) { - NYI_RISCV64("EmitSplitCallback-----unimplemented on RISCV64 yet----"); + UnwindInfo* puwi = (UnwindInfo*)context; + puwi->AddFragment(emitLoc); } // Reserve space for the unwind info for all fragments @@ -1861,7 +1921,21 @@ void UnwindInfo::CaptureLocation() void UnwindInfo::AddFragment(emitLocation* emitLoc) { - NYI_RISCV64("AddFragment-----unimplemented on RISCV64 yet----"); + assert(uwiInitialized == UWI_INITIALIZED_PATTERN); + assert(uwiFragmentLast != NULL); + + UnwindFragmentInfo* newFrag = new (uwiComp, CMK_UnwindInfo) UnwindFragmentInfo(uwiComp, emitLoc, true); + +#ifdef DEBUG + newFrag->ufiNum = uwiFragmentLast->ufiNum + 1; +#endif // DEBUG + + newFrag->CopyPrologCodes(&uwiFragmentFirst); + newFrag->SplitEpilogCodes(emitLoc, uwiFragmentLast); + + // Link the new fragment in at the end of the fragment list + uwiFragmentLast->ufiNext = newFrag; + uwiFragmentLast = newFrag; } #ifdef DEBUG diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 5dcb315af0a35d..3e5ad119411e2c 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1318,6 +1318,7 @@ void HelperCallProperties::init() case CORINFO_HELP_NEWSFAST_ALIGN8: case CORINFO_HELP_NEWSFAST_ALIGN8_VC: case CORINFO_HELP_NEWFAST: + case CORINFO_HELP_NEWFAST_MAYBEFROZEN: case CORINFO_HELP_NEWSFAST_FINALIZE: case CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE: case CORINFO_HELP_READYTORUN_NEW: @@ -1335,6 +1336,7 @@ void HelperCallProperties::init() case CORINFO_HELP_NEW_MDARR: case CORINFO_HELP_NEW_MDARR_RARE: case CORINFO_HELP_NEWARR_1_DIRECT: + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_READYTORUN_NEWARR_1: @@ -1386,7 +1388,6 @@ void HelperCallProperties::init() noThrow = true; // These return null for a failing cast break; - case CORINFO_HELP_ARE_TYPES_EQUIVALENT: case CORINFO_HELP_GETCURRENTMANAGEDTHREADID: isPure = true; noThrow = true; diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 18c4d946c2736f..692f2d660073b0 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -1876,6 +1876,113 @@ ValueNum ValueNumStore::VNForSimd64Con(simd64_t cnsVal) #endif // TARGET_XARCH #endif // FEATURE_SIMD +ValueNum ValueNumStore::VNForGenericCon(var_types typ, uint8_t* cnsVal) +{ + // For now we only support these primitives, we can extend this list to FP, SIMD and structs in future. + switch (typ) + { +#define READ_VALUE(typ) \ + typ val = {}; \ + memcpy(&val, cnsVal, sizeof(typ)); + + case TYP_BOOL: + case TYP_UBYTE: + { + READ_VALUE(uint8_t); + return VNForIntCon(val); + } + case TYP_BYTE: + { + READ_VALUE(int8_t); + return VNForIntCon(val); + } + case TYP_SHORT: + { + READ_VALUE(int16_t); + return VNForIntCon(val); + } + case TYP_USHORT: + { + READ_VALUE(uint16_t); + return VNForIntCon(val); + } + case TYP_INT: + { + READ_VALUE(int32_t); + return VNForIntCon(val); + } + case TYP_UINT: + { + READ_VALUE(uint32_t); + return VNForIntCon(val); + } + case TYP_LONG: + { + READ_VALUE(int64_t); + return VNForLongCon(val); + } + case TYP_ULONG: + { + READ_VALUE(uint64_t); + return VNForLongCon(val); + } + case TYP_FLOAT: + { + READ_VALUE(float); + return VNForFloatCon(val); + } + case TYP_DOUBLE: + { + READ_VALUE(double); + return VNForDoubleCon(val); + } + case TYP_REF: + { + READ_VALUE(ssize_t); + if (val == 0) + { + return VNForNull(); + } + else + { + return VNForHandle(val, GTF_ICON_OBJ_HDL); + } + } +#if defined(FEATURE_SIMD) + case TYP_SIMD8: + { + READ_VALUE(simd8_t); + return VNForSimd8Con(val); + } + case TYP_SIMD12: + { + READ_VALUE(simd12_t); + return VNForSimd12Con(val); + } + case TYP_SIMD16: + { + READ_VALUE(simd16_t); + return VNForSimd16Con(val); + } +#if defined(TARGET_XARCH) + case TYP_SIMD32: + { + READ_VALUE(simd32_t); + return VNForSimd32Con(val); + } + case TYP_SIMD64: + { + READ_VALUE(simd64_t); + return VNForSimd64Con(val); + } +#endif // TARGET_XARCH +#endif // FEATURE_SIMD + default: + unreached(); + break; + } +} + ValueNum ValueNumStore::VNForCastOper(var_types castToType, bool srcIsUnsigned) { assert(castToType != TYP_STRUCT); @@ -2284,7 +2391,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) { // Case 1: ARR_LENGTH(FROZEN_OBJ) ValueNum addressVN = VNNormalValue(arg0VN); - if (IsVNHandle(addressVN) && (GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) + if (IsVNObjHandle(addressVN)) { size_t handle = CoercedConstantValue(addressVN); int len = m_pComp->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); @@ -2308,8 +2415,8 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) if (field != NULL) { uint8_t buffer[TARGET_POINTER_SIZE] = {0}; - if (m_pComp->info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, - TARGET_POINTER_SIZE, 0, false)) + if (m_pComp->info.compCompHnd->getStaticFieldContent(field, buffer, TARGET_POINTER_SIZE, 0, + false)) { // In case of 64bit jit emitting 32bit codegen this handle will be 64bit // value holding 32bit handle with upper half zeroed (hence, "= NULL"). @@ -2326,6 +2433,14 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) } } } + + // Case 3: ARR_LENGTH(new T[cns]) + // TODO: Add support for MD arrays + int knownSize; + if ((resultVN == NoVN) && TryGetNewArrSize(addressVN, &knownSize)) + { + resultVN = VNForIntCon(knownSize); + } } // Try to perform constant-folding. @@ -5810,6 +5925,11 @@ bool ValueNumStore::IsVNHandle(ValueNum vn) return c->m_attribs == CEA_Handle; } +bool ValueNumStore::IsVNObjHandle(ValueNum vn) +{ + return IsVNHandle(vn) && GetHandleFlags(vn) == GTF_ICON_OBJ_HDL; +} + //------------------------------------------------------------------------ // SwapRelop: return VNFunc for swapped relop // @@ -6379,18 +6499,24 @@ bool ValueNumStore::IsVNNewArr(ValueNum vn, VNFuncApp* funcApp) // TODO-MDArray: support array dimension length of a specific dimension for JitNewMdArr, with a GetNewMDArrSize() // function. -int ValueNumStore::GetNewArrSize(ValueNum vn) +bool ValueNumStore::TryGetNewArrSize(ValueNum vn, int* size) { VNFuncApp funcApp; if (IsVNNewArr(vn, &funcApp)) { ValueNum arg1VN = funcApp.m_args[1]; - if (IsVNConstant(arg1VN) && TypeOfVN(arg1VN) == TYP_INT) + if (IsVNConstant(arg1VN)) { - return ConstantValue(arg1VN); + ssize_t val = CoercedConstantValue(arg1VN); + if ((size_t)val <= INT_MAX) + { + *size = (int)val; + return true; + } } } - return 0; + *size = 0; + return false; } bool ValueNumStore::IsVNArrLen(ValueNum vn) @@ -10165,12 +10291,14 @@ static bool GetStaticFieldSeqAndAddress(ValueNumStore* vnStore, GenTree* tree, s } ssize_t val = 0; - // Special case for NativeAOT: ADD(ICON_STATIC, CNS_INT) where CNS_INT has field sequence corresponding to field's - // offset - if (tree->OperIs(GT_ADD) && tree->gtGetOp1()->IsIconHandle(GTF_ICON_STATIC_HDL) && tree->gtGetOp2()->IsCnsIntOrI()) + // Special cases for NativeAOT: + // ADD(ICON_STATIC, CNS_INT) // nonGC-static base + // ADD(IND(ICON_STATIC_ADDR_PTR), CNS_INT) // GC-static base + // where CNS_INT has field sequence corresponding to field's offset + if (tree->OperIs(GT_ADD) && tree->gtGetOp2()->IsCnsIntOrI() && !tree->gtGetOp2()->IsIconHandle()) { GenTreeIntCon* cns2 = tree->gtGetOp2()->AsIntCon(); - if (cns2->gtFieldSeq != nullptr) + if ((cns2->gtFieldSeq != nullptr) && (cns2->gtFieldSeq->GetKind() == FieldSeq::FieldKind::SimpleStatic)) { *byteOffset = cns2->IconValue() - cns2->gtFieldSeq->GetOffset(); *pFseq = cns2->gtFieldSeq; @@ -10221,6 +10349,61 @@ static bool GetStaticFieldSeqAndAddress(ValueNumStore* vnStore, GenTree* tree, s return false; } +//---------------------------------------------------------------------------------- +// GetObjectHandleAndOffset: Try to obtain a constant object handle with an offset from +// the given tree. +// +// Arguments: +// vnStore - ValueNumStore object +// tree - tree node to inspect +// byteOffset - [Out] resulting byte offset +// pObj - [Out] constant object handle +// +// Return Value: +// true if the given tree is a ObjHandle + CNS +// +static bool GetObjectHandleAndOffset(ValueNumStore* vnStore, + GenTree* tree, + ssize_t* byteOffset, + CORINFO_OBJECT_HANDLE* pObj) +{ + + if (!tree->gtVNPair.BothEqual()) + { + return false; + } + + ValueNum treeVN = tree->gtVNPair.GetLiberal(); + VNFuncApp funcApp; + if (vnStore->GetVNFunc(treeVN, &funcApp) && (funcApp.m_func == (VNFunc)GT_ADD)) + { + // [objHandle + offset] + if (vnStore->IsVNObjHandle(funcApp.m_args[0]) && vnStore->IsVNConstant(funcApp.m_args[1])) + { + *pObj = vnStore->ConstantObjHandle(funcApp.m_args[0]); + *byteOffset = vnStore->ConstantValue(funcApp.m_args[1]); + return true; + } + + // [offset + objHandle] + // TODO: Introduce a general helper to accumulate offsets for + // shapes such as (((X + CNS1) + CNS2) + CNS3) etc. + if (vnStore->IsVNObjHandle(funcApp.m_args[1]) && vnStore->IsVNConstant(funcApp.m_args[0])) + { + *pObj = vnStore->ConstantObjHandle(funcApp.m_args[1]); + *byteOffset = vnStore->ConstantValue(funcApp.m_args[0]); + return true; + } + } + else if (vnStore->IsVNObjHandle(treeVN)) + { + *pObj = vnStore->ConstantObjHandle(treeVN); + *byteOffset = 0; + return true; + } + return false; +} + //---------------------------------------------------------------------------------- // fgValueNumberConstLoad: Try to detect const_immutable_array[cns_index] tree // and apply a constant VN representing given element at cns_index in that array. @@ -10244,139 +10427,45 @@ bool Compiler::fgValueNumberConstLoad(GenTreeIndir* tree) // // sbyte GetVal() => RVA[1]; // fold to '100' // - ssize_t byteOffset = 0; - FieldSeq* fieldSeq = nullptr; + ssize_t byteOffset = 0; + FieldSeq* fieldSeq = nullptr; + CORINFO_OBJECT_HANDLE obj = nullptr; + int size = (int)genTypeSize(tree->TypeGet()); + const int maxElementSize = sizeof(simd_t); + if ((varTypeIsSIMD(tree) || varTypeIsIntegral(tree) || varTypeIsFloating(tree) || tree->TypeIs(TYP_REF)) && GetStaticFieldSeqAndAddress(vnStore, tree->gtGetOp1(), &byteOffset, &fieldSeq)) { - CORINFO_FIELD_HANDLE fieldHandle = fieldSeq->GetFieldHandle(); - int size = (int)genTypeSize(tree->TypeGet()); - const int maxElementSize = sizeof(simd_t); + CORINFO_FIELD_HANDLE fieldHandle = fieldSeq->GetFieldHandle(); if ((fieldHandle != nullptr) && (size > 0) && (size <= maxElementSize) && ((size_t)byteOffset < INT_MAX)) { uint8_t buffer[maxElementSize] = {0}; - if (info.compCompHnd->getReadonlyStaticFieldValue(fieldHandle, (uint8_t*)&buffer, size, (int)byteOffset)) + if (info.compCompHnd->getStaticFieldContent(fieldHandle, buffer, size, (int)byteOffset)) { - // For now we only support these primitives, we can extend this list to FP, SIMD and structs in future. - switch (tree->TypeGet()) + ValueNum vn = vnStore->VNForGenericCon(tree->TypeGet(), buffer); + if (vnStore->IsVNObjHandle(vn)) { -#define READ_VALUE(typ) \ - typ val = {}; \ - memcpy(&val, buffer, sizeof(typ)); - - case TYP_BOOL: - case TYP_UBYTE: - { - READ_VALUE(uint8_t); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(val)); - return true; - } - case TYP_BYTE: - { - READ_VALUE(int8_t); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(val)); - return true; - } - case TYP_SHORT: - { - READ_VALUE(int16_t); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(val)); - return true; - } - case TYP_USHORT: - { - READ_VALUE(uint16_t); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(val)); - return true; - } - case TYP_INT: - { - READ_VALUE(int32_t); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(val)); - return true; - } - case TYP_UINT: - { - READ_VALUE(uint32_t); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(val)); - return true; - } - case TYP_LONG: - { - READ_VALUE(int64_t); - tree->gtVNPair.SetBoth(vnStore->VNForLongCon(val)); - return true; - } - case TYP_ULONG: - { - READ_VALUE(uint64_t); - tree->gtVNPair.SetBoth(vnStore->VNForLongCon(val)); - return true; - } - case TYP_FLOAT: - { - READ_VALUE(float); - tree->gtVNPair.SetBoth(vnStore->VNForFloatCon(val)); - return true; - } - case TYP_DOUBLE: - { - READ_VALUE(double); - tree->gtVNPair.SetBoth(vnStore->VNForDoubleCon(val)); - return true; - } - case TYP_REF: - { - READ_VALUE(ssize_t); - if (val == 0) - { - tree->gtVNPair.SetBoth(vnStore->VNForNull()); - } - else - { - tree->gtVNPair.SetBoth(vnStore->VNForHandle(val, GTF_ICON_OBJ_HDL)); - setMethodHasFrozenObjects(); - } - return true; - } -#if defined(FEATURE_SIMD) - case TYP_SIMD8: - { - READ_VALUE(simd8_t); - tree->gtVNPair.SetBoth(vnStore->VNForSimd8Con(val)); - return true; - } - case TYP_SIMD12: - { - READ_VALUE(simd12_t); - tree->gtVNPair.SetBoth(vnStore->VNForSimd12Con(val)); - return true; - } - case TYP_SIMD16: - { - READ_VALUE(simd16_t); - tree->gtVNPair.SetBoth(vnStore->VNForSimd16Con(val)); - return true; - } -#if defined(TARGET_XARCH) - case TYP_SIMD32: - { - READ_VALUE(simd32_t); - tree->gtVNPair.SetBoth(vnStore->VNForSimd32Con(val)); - return true; - } - case TYP_SIMD64: - { - READ_VALUE(simd64_t); - tree->gtVNPair.SetBoth(vnStore->VNForSimd64Con(val)); - return true; - } -#endif // TARGET_XARCH -#endif // FEATURE_SIMD - default: - assert(!varTypeIsSIMD(tree)); - break; + setMethodHasFrozenObjects(); } + tree->gtVNPair.SetBoth(vn); + return true; + } + } + } + else if ((varTypeIsSIMD(tree) || varTypeIsIntegral(tree) || varTypeIsFloating(tree)) && + GetObjectHandleAndOffset(vnStore, tree->gtGetOp1(), &byteOffset, &obj)) + { + // See if we can fold IND(ADD(FrozenObj, CNS)) to a constant + assert(obj != nullptr); + if ((size > 0) && (size <= maxElementSize) && ((size_t)byteOffset < INT_MAX)) + { + uint8_t buffer[maxElementSize] = {0}; + if (info.compCompHnd->getObjectContent(obj, buffer, size, (int)byteOffset)) + { + ValueNum vn = vnStore->VNForGenericCon(tree->TypeGet(), buffer); + assert(!vnStore->IsVNObjHandle(vn)); + tree->gtVNPair.SetBoth(vn); + return true; } } } @@ -10396,10 +10485,9 @@ bool Compiler::fgValueNumberConstLoad(GenTreeIndir* tree) // Is given VN representing a frozen object handle auto isCnsObjHandle = [](ValueNumStore* vnStore, ValueNum vn, CORINFO_OBJECT_HANDLE* handle) -> bool { - if (vnStore->IsVNHandle(vn) && (vnStore->GetHandleFlags(vn) == GTF_ICON_OBJ_HDL)) + if (vnStore->IsVNObjHandle(vn)) { - const size_t obj = vnStore->CoercedConstantValue(vn); - *handle = reinterpret_cast(obj); + *handle = vnStore->ConstantObjHandle(vn); return true; } return false; @@ -10633,28 +10721,58 @@ void Compiler::fgValueNumberTree(GenTree* tree) ValueNumPair addrXvnp; vnStore->VNPUnpackExc(addr->gtVNPair, &addrNvnp, &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); + } // Is the dereference immutable? If so, model it as referencing the read-only heap. - if (tree->gtFlags & GTF_IND_INVARIANT) + else if (tree->gtFlags & GTF_IND_INVARIANT) { assert(!isVolatile); // We don't expect both volatile and invariant - // Are we dereferencing the method table slot of some newly allocated object? - // - bool wasNewobj = false; - if ((oper == GT_IND) && (addr->TypeGet() == TYP_REF) && (tree->TypeGet() == TYP_I_IMPL)) + bool returnsTypeHandle = false; + if ((oper == GT_IND) && addr->TypeIs(TYP_REF) && tree->TypeIs(TYP_I_IMPL)) { - VNFuncApp funcApp; - const bool addrIsVNFunc = vnStore->GetVNFunc(addrNvnp.GetLiberal(), &funcApp); - - if (addrIsVNFunc && (funcApp.m_func == VNF_JitNew) && addrNvnp.BothEqual()) + // We try to access GC object's type, let's see if we know the exact type already + // First, we're trying to do that via gtGetClassHandle. + // + bool isExact = false; + bool isNonNull = false; + CORINFO_CLASS_HANDLE handle = gtGetClassHandle(addr, &isExact, &isNonNull); + if (isExact && (handle != NO_CLASS_HANDLE)) { - tree->gtVNPair = - vnStore->VNPWithExc(ValueNumPair(funcApp.m_args[0], funcApp.m_args[0]), addrXvnp); - wasNewobj = true; + JITDUMP("IND(obj) is actually a class handle for %s\n", eeGetClassName(handle)); + // Filter out all shared generic instantiations + if ((info.compCompHnd->getClassAttribs(handle) & CORINFO_FLG_SHAREDINST) == 0) + { + void* pEmbedClsHnd; + void* embedClsHnd = (void*)info.compCompHnd->embedClassHandle(handle, &pEmbedClsHnd); + if (pEmbedClsHnd == nullptr) + { + // Skip indirect handles for now since this path is mostly for PGO scenarios + assert(embedClsHnd != nullptr); + ValueNum handleVN = vnStore->VNForHandle((ssize_t)embedClsHnd, GTF_ICON_CLASS_HDL); + tree->gtVNPair = vnStore->VNPWithExc(ValueNumPair(handleVN, handleVN), addrXvnp); + returnsTypeHandle = true; + } + } + } + else + { + // Then, let's see if we can find JitNew at least + VNFuncApp funcApp; + const bool addrIsVNFunc = vnStore->GetVNFunc(addrNvnp.GetLiberal(), &funcApp); + if (addrIsVNFunc && (funcApp.m_func == VNF_JitNew) && addrNvnp.BothEqual()) + { + tree->gtVNPair = + vnStore->VNPWithExc(ValueNumPair(funcApp.m_args[0], funcApp.m_args[0]), addrXvnp); + returnsTypeHandle = true; + } } } - if (!wasNewobj) + if (!returnsTypeHandle) { // Indirections off of addresses for boxed statics represent bases for // the address of the static itself. Here we will use "nullptr" for the @@ -10709,9 +10827,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) ValueNum newUniq = vnStore->VNForExpr(compCurBB, tree->TypeGet()); tree->gtVNPair = vnStore->VNPWithExc(ValueNumPair(newUniq, newUniq), addrXvnp); } - // In general we skip GT_IND nodes on that are the LHS of an assignment. (We labeled these earlier.) - // We will "evaluate" this as part of the assignment. - else if ((tree->gtFlags & GTF_IND_ASG_LHS) == 0) + else { var_types loadType = tree->TypeGet(); ssize_t offset = 0; @@ -10754,12 +10870,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) { @@ -12077,6 +12187,14 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) vnf = VNF_JitReadyToRunNewArr; break; + case CORINFO_HELP_NEWFAST_MAYBEFROZEN: + vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNew : VNF_JitNew; + break; + + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: + vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNewArr : VNF_JitNewArr; + break; + case CORINFO_HELP_GETGENERICS_GCSTATIC_BASE: vnf = VNF_GetgenericsGcstaticBase; break; @@ -12195,10 +12313,6 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) vnf = VNF_TypeHandleToRuntimeTypeHandle; break; - case CORINFO_HELP_ARE_TYPES_EQUIVALENT: - vnf = VNF_AreTypesEquivalent; - break; - case CORINFO_HELP_READYTORUN_ISINSTANCEOF: vnf = VNF_ReadyToRunIsInstanceOf; break; diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 31ebe77ed9a18e..d0155008182251 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -442,6 +442,7 @@ class ValueNumStore ValueNum VNForSimd64Con(simd64_t cnsVal); #endif // TARGET_XARCH #endif // FEATURE_SIMD + ValueNum VNForGenericCon(var_types typ, uint8_t* cnsVal); #ifdef TARGET_64BIT ValueNum VNForPtrSizeIntCon(INT64 cnsVal) @@ -945,8 +946,8 @@ class ValueNumStore // Check if "vn" is "new [] (type handle, size)" bool IsVNNewArr(ValueNum vn, VNFuncApp* funcApp); - // Check if "vn" IsVNNewArr and return <= 0 if arr size cannot be determined, else array size. - int GetNewArrSize(ValueNum vn); + // Check if "vn" IsVNNewArr and return false if arr size cannot be determined. + bool TryGetNewArrSize(ValueNum vn, int* size); // Check if "vn" is "a.Length" or "a.GetLength(n)" bool IsVNArrLen(ValueNum vn); @@ -990,6 +991,9 @@ class ValueNumStore // Returns true iff the VN represents a handle constant. bool IsVNHandle(ValueNum vn); + // Returns true iff the VN represents an object handle constant. + bool IsVNObjHandle(ValueNum vn); + // Returns true iff the VN represents a relop bool IsVNRelop(ValueNum vn); @@ -1120,6 +1124,12 @@ class ValueNumStore return ConstantValueInternal(vn DEBUGARG(true)); } + CORINFO_OBJECT_HANDLE ConstantObjHandle(ValueNum vn) + { + assert(IsVNObjHandle(vn)); + return reinterpret_cast(CoercedConstantValue(vn)); + } + // Requires "mthFunc" to be an intrinsic math function (one of the allowable values for the "gtMath" field // of a GenTreeMath node). For unary ops, return the value number for the application of this function to // "arg0VN". For binary ops, return the value number for the application of this function to "arg0VN" and diff --git a/src/coreclr/jit/valuenumfuncs.h b/src/coreclr/jit/valuenumfuncs.h index 6551be8772a2a4..df804121eb98a1 100644 --- a/src/coreclr/jit/valuenumfuncs.h +++ b/src/coreclr/jit/valuenumfuncs.h @@ -41,8 +41,6 @@ ValueNumFuncDef(ReadyToRunIsInstanceOf, 2, false, false, false) // Args: 0 ValueNumFuncDef(TypeHandleToRuntimeType, 1, false, false, false) // Args: 0: TypeHandle to translate ValueNumFuncDef(TypeHandleToRuntimeTypeHandle, 1, false, false, false) // Args: 0: TypeHandle to translate -ValueNumFuncDef(AreTypesEquivalent, 2, false, false, false) // Args: 0: first TypeHandle, 1: second TypeHandle - ValueNumFuncDef(LdElemA, 3, false, false, false) // Args: 0: array value; 1: index value; 2: type handle of element. ValueNumFuncDef(ByrefExposedLoad, 3, false, false, false) // Args: 0: type handle/id, 1: pointer value; 2: ByrefExposed heap value diff --git a/src/coreclr/nativeaot/BuildIntegration/BuildFrameworkNativeObjects.proj b/src/coreclr/nativeaot/BuildIntegration/BuildFrameworkNativeObjects.proj index f4fde7991f5610..1b073e27e9b880 100644 --- a/src/coreclr/nativeaot/BuildIntegration/BuildFrameworkNativeObjects.proj +++ b/src/coreclr/nativeaot/BuildIntegration/BuildFrameworkNativeObjects.proj @@ -13,8 +13,7 @@ <_targetArchitecture>$(TargetArchitecture) - - + <_targetOS Condition="$(_targetOS.StartsWith('linux'))">linux - - true @@ -33,22 +31,23 @@ SetupProperties - - + + + $([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName($([System.IO.Path]::GetDirectoryName($(ILCompilerTargetsPath))))))) - - + - + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 27955fd6bc22c1..bb457c8c166bc8 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -62,8 +62,7 @@ The .NET Foundation licenses this file to you under the MIT license. - - + @@ -204,15 +203,15 @@ The .NET Foundation licenses this file to you under the MIT license. + Text="Symbol stripping tool ('$(ObjCopyName)' or '$(ObjCopyNameAlternative)') not found in PATH. Try installing appropriate package for $(ObjCopyName) or $(ObjCopyNameAlternative) to resolve the problem or set the StripSymbols property to false to disable symbol stripping." /> + Text="Symbol stripping tool ('$(ObjCopyName)') not found in PATH. Make sure '$(ObjCopyName)' is available in PATH or set the StripSymbols property to false to disable symbol stripping." /> + Text="Symbol stripping tools ('dsymutil' and 'strip') not found in PATH. Make sure 'dsymutil' and 'strip' are available in PATH or set the StripSymbols property to false to disable symbol stripping." /> diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index 7a2bad65a5d49c..42b5da45b97d62 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -23,7 +23,7 @@ The .NET Foundation licenses this file to you under the MIT license. bootstrapper bootstrapperdll Runtime.VxsortEnabled - Runtime.VxsortDisabled + Runtime.VxsortDisabled wmainCRTStartup WINDOWS CONSOLE diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index a0c5cbae672ebe..fbcadcc71b5977 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -16,6 +16,7 @@ The .NET Foundation licenses this file to you under the MIT license. + true Shared $(IntermediateOutputPath)native\ $(OutputPath)native\ @@ -25,6 +26,7 @@ The .NET Foundation licenses this file to you under the MIT license. false true + true false <_IsiOSLikePlatform Condition="'$(_targetOS)' == 'maccatalyst' or $(_targetOS.StartsWith('ios')) or $(_targetOS.StartsWith('tvos'))">true <_IsApplePlatform Condition="'$(_targetOS)' == 'osx' or '$(_IsiOSLikePlatform)' == 'true'">true @@ -87,7 +89,7 @@ The .NET Foundation licenses this file to you under the MIT license. $(FrameworkLibPath)\Framework$(LibFileExt) $(FrameworkLibPath)\libframework$(LibFileExt) - SetupProperties + SetupProperties @@ -221,8 +223,8 @@ The .NET Foundation licenses this file to you under the MIT license. - - + + diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs index f74422403796c9..4debbad687ed12 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs @@ -19,45 +19,6 @@ internal struct ObjHeader private IntPtr _objHeaderContents; } - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct EEInterfaceInfo - { - [StructLayout(LayoutKind.Explicit)] - private unsafe struct InterfaceTypeUnion - { - [FieldOffset(0)] - public MethodTable* _pInterfaceEEType; - [FieldOffset(0)] - public MethodTable** _ppInterfaceEETypeViaIAT; - } - - private InterfaceTypeUnion _interfaceType; - - internal MethodTable* InterfaceType - { - get - { - if ((unchecked((uint)_interfaceType._pInterfaceEEType) & IndirectionConstants.IndirectionCellPointer) != 0) - { -#if TARGET_64BIT - MethodTable** ppInterfaceEETypeViaIAT = (MethodTable**)(((ulong)_interfaceType._ppInterfaceEETypeViaIAT) - IndirectionConstants.IndirectionCellPointer); -#else - MethodTable** ppInterfaceEETypeViaIAT = (MethodTable**)(((uint)_interfaceType._ppInterfaceEETypeViaIAT) - IndirectionConstants.IndirectionCellPointer); -#endif - return *ppInterfaceEETypeViaIAT; - } - - return _interfaceType._pInterfaceEEType; - } -#if TYPE_LOADER_IMPLEMENTATION - set - { - _interfaceType._pInterfaceEEType = value; - } -#endif - } - } - [StructLayout(LayoutKind.Sequential)] internal unsafe struct DispatchMap { @@ -179,20 +140,10 @@ private unsafe struct RelatedTypeUnion // Kinds.CanonicalEEType [FieldOffset(0)] public MethodTable* _pBaseType; - [FieldOffset(0)] - public MethodTable** _ppBaseTypeViaIAT; - - // Kinds.ClonedEEType - [FieldOffset(0)] - public MethodTable* _pCanonicalType; - [FieldOffset(0)] - public MethodTable** _ppCanonicalTypeViaIAT; // Kinds.ArrayEEType [FieldOffset(0)] public MethodTable* _pRelatedParameterType; - [FieldOffset(0)] - public MethodTable** _ppRelatedParameterTypeViaIAT; } private static unsafe class OptionalFieldsReader @@ -311,7 +262,7 @@ internal ushort ComponentSize #endif } - internal ushort GenericArgumentCount + internal ushort GenericParameterCount { get { @@ -572,36 +523,10 @@ internal MethodTable* GenericDefinition #endif } - [StructLayout(LayoutKind.Sequential)] - private readonly struct GenericComposition - { - public readonly ushort Arity; - - private readonly EETypeRef _genericArgument1; - public EETypeRef* GenericArguments - { - get - { - return (EETypeRef*)Unsafe.AsPointer(ref Unsafe.AsRef(in _genericArgument1)); - } - } - - public GenericVariance* GenericVariance - { - get - { - // Generic variance directly follows the last generic argument - return (GenericVariance*)(GenericArguments + Arity); - } - } - } - #if TYPE_LOADER_IMPLEMENTATION - internal static int GetGenericCompositionSize(int numArguments, bool hasVariance) + internal static int GetGenericCompositionSize(int numArguments) { - return IntPtr.Size - + numArguments * IntPtr.Size - + (hasVariance ? numArguments * sizeof(GenericVariance) : 0); + return numArguments * IntPtr.Size; } internal void SetGenericComposition(IntPtr data) @@ -620,31 +545,34 @@ internal uint GenericArity get { Debug.Assert(IsGeneric); - if (IsDynamicType || !SupportsRelativePointers) - return GetField>(EETypeField.ETF_GenericComposition).Value->Arity; - - return GetField>(EETypeField.ETF_GenericComposition).Value->Arity; - } -#if TYPE_LOADER_IMPLEMENTATION - set - { - Debug.Assert(IsDynamicType); - // GenericComposition is a readonly struct, so we just blit the bytes over. Asserts guard changes to the layout. - *((ushort*)GetField>(EETypeField.ETF_GenericComposition).Value) = checked((ushort)value); - Debug.Assert(GenericArity == (ushort)value); + return GenericDefinition->GenericParameterCount; } -#endif } - internal EETypeRef* GenericArguments + internal MethodTableList GenericArguments { get { Debug.Assert(IsGeneric); - if (IsDynamicType || !SupportsRelativePointers) - return GetField>(EETypeField.ETF_GenericComposition).Value->GenericArguments; - return GetField>(EETypeField.ETF_GenericComposition).Value->GenericArguments; + void* pField = (byte*)Unsafe.AsPointer(ref this) + GetFieldOffset(EETypeField.ETF_GenericComposition); + uint arity = GenericArity; + + // If arity is 1, the field value is the component. For arity > 1, components are stored out-of-line + // and are shared. + if (IsDynamicType || !SupportsRelativePointers) + { + // This is a full pointer [that points to a list of full pointers] + MethodTable* pListStart = arity == 1 ? (MethodTable*)pField : *(MethodTable**)pField; + return new MethodTableList(pListStart); + } + else + { + // This is a relative pointer [that points to a list of relative pointers] + RelativePointer* pListStart = arity == 1 ? + (RelativePointer*)pField : (RelativePointer*)((RelativePointer*)pField)->Value; + return new MethodTableList(pListStart); + } } } @@ -657,10 +585,13 @@ internal GenericVariance* GenericVariance if (!HasGenericVariance) return null; + if (IsGeneric) + return GenericDefinition->GenericVariance; + if (IsDynamicType || !SupportsRelativePointers) - return GetField>(EETypeField.ETF_GenericComposition).Value->GenericVariance; + return GetField>(EETypeField.ETF_GenericComposition).Value; - return GetField>(EETypeField.ETF_GenericComposition).Value->GenericVariance; + return GetField>(EETypeField.ETF_GenericComposition).Value; } } @@ -688,14 +619,6 @@ internal bool IsInterface } } - internal bool IsAbstract - { - get - { - return IsInterface || (RareFlags & EETypeRareFlags.IsAbstractClassFlag) != 0; - } - } - internal bool IsByRefLike { get @@ -748,14 +671,68 @@ internal uint ParameterizedTypeShape #endif } - internal bool IsRelatedTypeViaIAT + internal uint NumFunctionPointerParameters + { + get + { + Debug.Assert(IsFunctionPointerType); + return _uBaseSize & ~FunctionPointerFlags.FlagsMask; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsFunctionPointerType); + _uBaseSize = value | (_uBaseSize & FunctionPointerFlags.FlagsMask); + } +#endif + } + + internal bool IsUnmanagedFunctionPointer + { + get + { + Debug.Assert(IsFunctionPointerType); + return (_uBaseSize & FunctionPointerFlags.IsUnmanaged) != 0; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsFunctionPointerType); + if (value) + _uBaseSize |= FunctionPointerFlags.IsUnmanaged; + else + _uBaseSize &= ~FunctionPointerFlags.IsUnmanaged; + } +#endif + } + + internal MethodTableList FunctionPointerParameters { get { - return ((_uFlags & (uint)EETypeFlags.RelatedTypeViaIATFlag) != 0); + void* pStart = (byte*)Unsafe.AsPointer(ref this) + GetFieldOffset(EETypeField.ETF_FunctionPointerParameters); + if (IsDynamicType || !SupportsRelativePointers) + return new MethodTableList((MethodTable*)pStart); + return new MethodTableList((RelativePointer*)pStart); } } + internal MethodTable* FunctionPointerReturnType + { + get + { + Debug.Assert(IsFunctionPointerType); + return _relatedType._pRelatedParameterType; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType && IsFunctionPointerType); + _relatedType._pRelatedParameterType = value; + } +#endif + } + internal bool RequiresAlign8 { get @@ -768,7 +745,7 @@ internal bool IsIDynamicInterfaceCastable { get { - return ((_uFlags & (uint)EETypeFlags.IDynamicInterfaceCastableFlag) != 0); + return ((ExtendedFlags & (ushort)EETypeFlagsEx.IDynamicInterfaceCastableFlag) != 0); } } @@ -789,6 +766,14 @@ internal bool IsPrimitive } } + internal bool HasSealedVTableEntries + { + get + { + return (_uFlags & (uint)EETypeFlags.HasSealedVTableEntriesFlag) != 0; + } + } + internal bool ContainsGCPointers { get @@ -858,15 +843,12 @@ internal uint ValueTypeSize } } - internal EEInterfaceInfo* InterfaceMap + internal MethodTable** InterfaceMap { get { - fixed (MethodTable* start = &this) - { - // interface info table starts after the vtable and has _usNumInterfaces entries - return (EEInterfaceInfo*)((byte*)start + sizeof(MethodTable) + sizeof(void*) * _usNumVtableSlots); - } + // interface info table starts after the vtable and has _usNumInterfaces entries + return (MethodTable**)((byte*)Unsafe.AsPointer(ref this) + sizeof(MethodTable) + sizeof(void*) * _usNumVtableSlots); } } @@ -874,22 +856,7 @@ internal bool HasDispatchMap { get { - if (NumInterfaces == 0) - return false; - byte* optionalFields = OptionalFieldsPtr; - - const uint NoDispatchMap = 0xffffffff; - uint idxDispatchMap = NoDispatchMap; - if (optionalFields != null) - idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, NoDispatchMap); - - if (idxDispatchMap == NoDispatchMap) - { - if (IsDynamicType) - return DynamicTemplateType->HasDispatchMap; - return false; - } - return true; + return (_uFlags & (uint)EETypeFlags.HasDispatchMap) != 0; } } @@ -897,25 +864,23 @@ internal DispatchMap* DispatchMap { get { - if (NumInterfaces == 0) - return null; - byte* optionalFields = OptionalFieldsPtr; - const uint NoDispatchMap = 0xffffffff; - uint idxDispatchMap = NoDispatchMap; - if (optionalFields != null) - idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, NoDispatchMap); - if (idxDispatchMap == NoDispatchMap) - { - if (IsDynamicType) - return DynamicTemplateType->DispatchMap; + if (!HasDispatchMap) return null; - } - if (SupportsRelativePointers) - return (DispatchMap*)FollowRelativePointer((int*)TypeManager.DispatchMap + idxDispatchMap); - else - return ((DispatchMap**)TypeManager.DispatchMap)[idxDispatchMap]; + if (IsDynamicType || !SupportsRelativePointers) + return GetField>(EETypeField.ETF_DispatchMap).Value; + + return GetField>(EETypeField.ETF_DispatchMap).Value; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType && HasDispatchMap); + + fixed (MethodTable* pThis = &this) + *(DispatchMap**)((byte*)pThis + GetFieldOffset(EETypeField.ETF_DispatchMap)) = value; } +#endif } // Get the address of the finalizer method for finalizable types. @@ -945,7 +910,7 @@ internal MethodTable* BaseType { get { - if (IsParameterizedType) + if (!IsCanonical) { if (IsArray) return GetArrayEEType(); @@ -953,15 +918,7 @@ internal MethodTable* BaseType return null; } - // Function pointers naturally set the base type field to null. - Debug.Assert(!IsFunctionPointerType || (!IsRelatedTypeViaIAT && _relatedType._pBaseType == null)); - - Debug.Assert(IsCanonical); - - if (IsRelatedTypeViaIAT) - return *_relatedType._ppBaseTypeViaIAT; - else - return _relatedType._pBaseType; + return _relatedType._pBaseType; } #if TYPE_LOADER_IMPLEMENTATION set @@ -970,41 +927,18 @@ internal MethodTable* BaseType Debug.Assert(!IsParameterizedType); Debug.Assert(!IsFunctionPointerType); Debug.Assert(IsCanonical); - _uFlags &= (uint)~EETypeFlags.RelatedTypeViaIATFlag; _relatedType._pBaseType = value; } #endif } internal MethodTable* NonArrayBaseType - { - get - { - Debug.Assert(!IsArray, "array type not supported in BaseType"); - Debug.Assert(IsCanonical, "we expect canonical types here"); - - if (IsRelatedTypeViaIAT) - { - return *_relatedType._ppBaseTypeViaIAT; - } - - return _relatedType._pBaseType; - } - } - - // TODO rename? - internal MethodTable* NonClonedNonArrayBaseType { get { Debug.Assert(!IsArray, "array type not supported in NonArrayBaseType"); - Debug.Assert(IsCanonical || IsGenericTypeDefinition, "we expect canonical types here"); - - if (IsRelatedTypeViaIAT) - { - return *_relatedType._ppBaseTypeViaIAT; - } - + Debug.Assert(IsCanonical || IsGenericTypeDefinition, "we expect type definitions here"); + Debug.Assert(!IsGenericTypeDefinition || _relatedType._pBaseType == null, "callers assume this would be null for a generic definition"); return _relatedType._pBaseType; } } @@ -1015,8 +949,6 @@ internal MethodTable* RawBaseType { Debug.Assert(!IsParameterizedType, "array type not supported in NonArrayBaseType"); Debug.Assert(IsCanonical, "we expect canonical types here"); - Debug.Assert(!IsRelatedTypeViaIAT, "Non IAT"); - return _relatedType._pBaseType; } } @@ -1027,7 +959,7 @@ internal MethodTable* NullableType { Debug.Assert(IsNullable); Debug.Assert(GenericArity == 1); - return GenericArguments[0].Value; + return GenericArguments[0]; } } @@ -1058,17 +990,12 @@ internal MethodTable* RelatedParameterType get { Debug.Assert(IsParameterizedType); - - if (IsRelatedTypeViaIAT) - return *_relatedType._ppRelatedParameterTypeViaIAT; - else - return _relatedType._pRelatedParameterType; + return _relatedType._pRelatedParameterType; } #if TYPE_LOADER_IMPLEMENTATION set { Debug.Assert(IsDynamicType && IsParameterizedType); - _uFlags &= ((uint)~EETypeFlags.RelatedTypeViaIATFlag); _relatedType._pRelatedParameterType = value; } #endif @@ -1100,7 +1027,7 @@ private static IntPtr FollowRelativePointer(int* pDist) #endif void* GetSealedVirtualTable() { - Debug.Assert((RareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0); + Debug.Assert(HasSealedVTableEntries); uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots); byte* pThis = (byte*)Unsafe.AsPointer(ref this); @@ -1380,7 +1307,7 @@ public uint GetFieldOffset(EETypeField eField) Debug.Assert(NumInterfaces > 0); return cbOffset; } - cbOffset += (uint)(sizeof(EEInterfaceInfo) * NumInterfaces); + cbOffset += (uint)(sizeof(MethodTable*) * NumInterfaces); uint relativeOrFullPointerOffset = (IsDynamicType || !SupportsRelativePointers ? (uint)IntPtr.Size : 4); @@ -1401,6 +1328,15 @@ public uint GetFieldOffset(EETypeField eField) cbOffset += relativeOrFullPointerOffset; } + // Followed by pointer to the dispatch map + if (eField == EETypeField.ETF_DispatchMap) + { + Debug.Assert(HasDispatchMap); + return cbOffset; + } + if (HasDispatchMap) + cbOffset += relativeOrFullPointerOffset; + // Followed by the pointer to the finalizer method. if (eField == EETypeField.ETF_Finalizer) { @@ -1423,10 +1359,8 @@ public uint GetFieldOffset(EETypeField eField) if (eField == EETypeField.ETF_SealedVirtualSlots) return cbOffset; - EETypeRareFlags rareFlags = RareFlags; - // in the case of sealed vtable entries on static types, we have a UInt sized relative pointer - if ((rareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0) + if (HasSealedVTableEntries) cbOffset += relativeOrFullPointerOffset; if (eField == EETypeField.ETF_GenericDefinition) @@ -1449,6 +1383,16 @@ public uint GetFieldOffset(EETypeField eField) cbOffset += relativeOrFullPointerOffset; } + if (eField == EETypeField.ETF_FunctionPointerParameters) + { + Debug.Assert(IsFunctionPointerType); + return cbOffset; + } + if (IsFunctionPointerType) + { + cbOffset += NumFunctionPointerParameters * relativeOrFullPointerOffset; + } + if (eField == EETypeField.ETF_DynamicTemplateType) { Debug.Assert(IsDynamicType); @@ -1457,6 +1401,7 @@ public uint GetFieldOffset(EETypeField eField) if (IsDynamicType) cbOffset += (uint)IntPtr.Size; + EETypeRareFlags rareFlags = RareFlags; if (eField == EETypeField.ETF_DynamicGcStatics) { Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0); @@ -1497,22 +1442,26 @@ public ref T GetField(uint offset) internal static uint GetSizeofEEType( ushort cVirtuals, ushort cInterfaces, + bool fHasDispatchMap, bool fHasFinalizer, bool fRequiresOptionalFields, bool fHasSealedVirtuals, bool fHasGenericInfo, + int cFunctionPointerTypeParameters, bool fHasNonGcStatics, bool fHasGcStatics, bool fHasThreadStatics) { return (uint)(sizeof(MethodTable) + (IntPtr.Size * cVirtuals) + - (sizeof(EEInterfaceInfo) * cInterfaces) + + (sizeof(MethodTable*) * cInterfaces) + sizeof(IntPtr) + // TypeManager (SupportsWritableData ? sizeof(IntPtr) : 0) + // WritableData + (fHasDispatchMap ? sizeof(UIntPtr) : 0) + (fHasFinalizer ? sizeof(UIntPtr) : 0) + (fRequiresOptionalFields ? sizeof(IntPtr) : 0) + (fHasSealedVirtuals ? sizeof(IntPtr) : 0) + + cFunctionPointerTypeParameters * sizeof(IntPtr) + (fHasGenericInfo ? sizeof(IntPtr)*2 : 0) + // pointers to GenericDefinition and GenericComposition (fHasNonGcStatics ? sizeof(IntPtr) : 0) + // pointer to data (fHasGcStatics ? sizeof(IntPtr) : 0) + // pointer to data @@ -1521,29 +1470,6 @@ internal static uint GetSizeofEEType( #endif } - // Wrapper around MethodTable pointers that may be indirected through the IAT if their low bit is set. - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct EETypeRef - { - private byte* _value; - - public MethodTable* Value - { - get - { - if (((int)_value & IndirectionConstants.IndirectionCellPointer) == 0) - return (MethodTable*)_value; - return *(MethodTable**)(_value - IndirectionConstants.IndirectionCellPointer); - } -#if TYPE_LOADER_IMPLEMENTATION - set - { - _value = (byte*)value; - } -#endif - } - } - // Wrapper around pointers [StructLayout(LayoutKind.Sequential)] internal readonly struct Pointer @@ -1642,4 +1568,46 @@ public T* Value } } } + + // Abstracts a list of MethodTable pointers that could either be relative + // pointers or full pointers. We store the IsRelative bit in the lowest + // bit so this assumes the list is at least 2 byte aligned. + internal readonly unsafe struct MethodTableList + { + private const int IsRelative = 1; + + private readonly void* _pFirst; + + public MethodTableList(MethodTable* pFirst) + { + // If the first element is not aligned, we don't have the spare bit we need + Debug.Assert(((nint)pFirst & IsRelative) == 0); + _pFirst = pFirst; + } + + public MethodTableList(RelativePointer* pFirst) + { + // If the first element is not aligned, we don't have the spare bit we need + Debug.Assert(((nint)pFirst & IsRelative) == 0); + _pFirst = (void*)((nint)pFirst | IsRelative); + } + + public MethodTable* this[int index] + { + get + { + if (((nint)_pFirst & IsRelative) != 0) + return (((RelativePointer*)((nint)_pFirst - IsRelative)) + index)->Value; + + return *((MethodTable**)_pFirst + index); + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(((nint)_pFirst & IsRelative) == 0); + *((MethodTable**)_pFirst + index) = value; + } +#endif + } + } } diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/TypeManagerHandle.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/TypeManagerHandle.cs index 9780acd39f72a9..d1559fce550ea5 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/TypeManagerHandle.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/TypeManagerHandle.cs @@ -20,7 +20,6 @@ private struct TypeManager { public IntPtr OsHandle; public IntPtr ReadyToRunHeader; - public IntPtr DispatchMap; } public TypeManagerHandle(IntPtr handleValue) @@ -48,13 +47,5 @@ public unsafe IntPtr OsModuleBase return _handleValue->OsHandle; } } - - public unsafe IntPtr DispatchMap - { - get - { - return _handleValue->DispatchMap; - } - } } } diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index 799089f2af88dc..7fdf7430ac799d 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -55,8 +55,7 @@ FEATURE_COMINTEROP;$(DefineConstants) - false - true + true false diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs index 505c535659b2b3..349415c743aa9a 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs @@ -123,7 +123,7 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType, Debug.Assert(pTgtType->HasDispatchMap, "Missing dispatch map"); MethodTable* pItfOpenGenericType = null; - EETypeRef* pItfInstantiation = null; + MethodTableList itfInstantiation = default; int itfArity = 0; GenericVariance* pItfVarianceInfo = null; @@ -182,7 +182,7 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType, if (i->_usInterfaceMethodSlot == itfSlotNumber) { MethodTable* pCurEntryType = - pTgtType->InterfaceMap[i->_usInterfaceIndex].InterfaceType; + pTgtType->InterfaceMap[i->_usInterfaceIndex]; if (pCurEntryType == pItfType) { @@ -207,7 +207,7 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType, { pItfOpenGenericType = pItfType->GenericDefinition; itfArity = (int)pItfType->GenericArity; - pItfInstantiation = pItfType->GenericArguments; + itfInstantiation = pItfType->GenericArguments; pItfVarianceInfo = pItfType->GenericVariance; } @@ -219,13 +219,13 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType, continue; // Grab instantiation details for the candidate interface. - EETypeRef* pCurEntryInstantiation = pCurEntryType->GenericArguments; + MethodTableList curEntryInstantiation = pCurEntryType->GenericArguments; // The types represent different instantiations of the same generic type. The // arity of both had better be the same. Debug.Assert(itfArity == (int)pCurEntryType->GenericArity, "arity mismatch between generic instantiations"); - if (TypeCast.TypeParametersAreCompatible(itfArity, pCurEntryInstantiation, pItfInstantiation, pItfVarianceInfo, fArrayCovariance, null)) + if (TypeCast.TypeParametersAreCompatible(itfArity, curEntryInstantiation, itfInstantiation, pItfVarianceInfo, fArrayCovariance, null)) { *pImplSlotNumber = i->_usImplMethodSlot; @@ -250,7 +250,7 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType, { StaticVirtualMethodContextSource.None => null, StaticVirtualMethodContextSource.ContextFromThisClass => pTgtType, - _ => pTgtType->InterfaceMap[usEncodedValue - StaticVirtualMethodContextSource.ContextFromFirstInterface].InterfaceType + _ => pTgtType->InterfaceMap[usEncodedValue - StaticVirtualMethodContextSource.ContextFromFirstInterface] }; } } diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index 1f0bf451771b0d..31f21abf28361f 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -850,8 +850,17 @@ private static bool FindFirstPassHandler(object exception, uint idxStart, else { byte* pFilterFunclet = ehClause._filterAddress; - bool shouldInvokeHandler = - InternalCalls.RhpCallFilterFunclet(exception, pFilterFunclet, frameIter.RegisterSet); + + bool shouldInvokeHandler = false; + try + { + shouldInvokeHandler = + InternalCalls.RhpCallFilterFunclet(exception, pFilterFunclet, frameIter.RegisterSet); + } + catch when (true) + { + // Prevent leaking any exception from the filter funclet + } if (shouldInvokeHandler) { diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/MethodTable.Runtime.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/MethodTable.Runtime.cs index 26f9f103b5177f..d46c8372633554 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/MethodTable.Runtime.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/MethodTable.Runtime.cs @@ -46,7 +46,7 @@ internal IntPtr GetClasslibFunction(ClassLibFunctionId id) } /// - /// Return true if type is good for simple casting : canonical, no related type via IAT, no generic variance + /// Return true if type is good for simple casting : canonical, no generic variance /// internal bool SimpleCasting() { diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs index 4c3afabd7d20ad..a4577708748da3 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs @@ -137,7 +137,7 @@ public static unsafe object RhBoxAny(ref byte data, MethodTable* pEEType) private static unsafe bool UnboxAnyTypeCompare(MethodTable* pEEType, MethodTable* ptrUnboxToEEType) { - if (TypeCast.AreTypesEquivalent(pEEType, ptrUnboxToEEType)) + if (pEEType == ptrUnboxToEEType) return true; if (pEEType->ElementType == ptrUnboxToEEType->ElementType) @@ -173,7 +173,7 @@ public static unsafe void RhUnboxAny(object? o, ref byte data, EETypePtr pUnboxT if (ptrUnboxToEEType->IsNullable) { - isValid = (o == null) || TypeCast.AreTypesEquivalent(o.GetMethodTable(), ptrUnboxToEEType->NullableType); + isValid = (o == null) || o.GetMethodTable() == ptrUnboxToEEType->NullableType; } else { @@ -220,7 +220,7 @@ public static unsafe ref byte RhUnbox2(MethodTable* pUnboxToEEType, object obj) [RuntimeExport("RhUnboxNullable")] public static unsafe void RhUnboxNullable(ref byte data, MethodTable* pUnboxToEEType, object obj) { - if ((obj != null) && !TypeCast.AreTypesEquivalent(obj.GetMethodTable(), pUnboxToEEType->NullableType)) + if (obj != null && obj.GetMethodTable() != pUnboxToEEType->NullableType) { throw pUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast); } diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs index 5695b8e6a2a6a2..aad807842c5dfd 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs @@ -55,7 +55,7 @@ public static unsafe object IsInstanceOfClass(MethodTable* pTargetType, object o Debug.Assert(!pTargetType->IsFunctionPointerType, "IsInstanceOfClass called with function pointer MethodTable"); Debug.Assert(!pTargetType->IsInterface, "IsInstanceOfClass called with interface MethodTable"); - // Quick check if both types are good for simple casting: canonical, no related type via IAT, no generic variance + // Quick check if both types are good for simple casting: canonical, no generic variance if (Internal.Runtime.MethodTable.BothSimpleCasting(pObjType, pTargetType)) { // walk the type hierarchy looking for a match @@ -124,7 +124,7 @@ private static unsafe object IsInstanceOfClass_Helper(MethodTable* pTargetType, // walk the type hierarchy looking for a match while (true) { - pObjType = pObjType->NonClonedNonArrayBaseType; + pObjType = pObjType->NonArrayBaseType; if (pObjType == null) { return null; @@ -256,10 +256,10 @@ internal static unsafe bool ImplementsInterface(MethodTable* pObjType, MethodTab Debug.Assert(pTargetType->IsInterface, "IsInstanceOfInterface called with non-interface MethodTable"); int numInterfaces = pObjType->NumInterfaces; - EEInterfaceInfo* interfaceMap = pObjType->InterfaceMap; + MethodTable** interfaceMap = pObjType->InterfaceMap; for (int i = 0; i < numInterfaces; i++) { - MethodTable* pInterfaceType = interfaceMap[i].InterfaceType; + MethodTable* pInterfaceType = interfaceMap[i]; if (pInterfaceType == pTargetType) { return true; @@ -278,7 +278,7 @@ internal static unsafe bool ImplementsInterface(MethodTable* pObjType, MethodTab { // Grab details about the instantiation of the target generic interface. MethodTable* pTargetGenericType = pTargetType->GenericDefinition; - EETypeRef* pTargetInstantiation = pTargetType->GenericArguments; + MethodTableList targetInstantiation = pTargetType->GenericArguments; int targetArity = (int)pTargetType->GenericArity; GenericVariance* pTargetVarianceInfo = pTargetType->GenericVariance; @@ -287,7 +287,7 @@ internal static unsafe bool ImplementsInterface(MethodTable* pObjType, MethodTab for (int i = 0; i < numInterfaces; i++) { - MethodTable* pInterfaceType = interfaceMap[i].InterfaceType; + MethodTable* pInterfaceType = interfaceMap[i]; // We can ignore interfaces which are not also marked as having generic variance // unless we're dealing with array covariance. @@ -303,7 +303,7 @@ internal static unsafe bool ImplementsInterface(MethodTable* pObjType, MethodTab continue; // Grab instantiation details for the candidate interface. - EETypeRef* pInterfaceInstantiation = pInterfaceType->GenericArguments; + MethodTableList interfaceInstantiation = pInterfaceType->GenericArguments; int interfaceArity = (int)pInterfaceType->GenericArity; GenericVariance* pInterfaceVarianceInfo = pInterfaceType->GenericVariance; @@ -315,8 +315,8 @@ internal static unsafe bool ImplementsInterface(MethodTable* pObjType, MethodTab // Compare the instantiations to see if they're compatible taking variance into account. if (TypeParametersAreCompatible(targetArity, - pInterfaceInstantiation, - pTargetInstantiation, + interfaceInstantiation, + targetInstantiation, pTargetVarianceInfo, fArrayCovariance, pVisited)) @@ -339,13 +339,13 @@ private static unsafe bool TypesAreCompatibleViaGenericVariance(MethodTable* pSo { // Get generic instantiation metadata for both types. - EETypeRef* pTargetInstantiation = pTargetType->GenericArguments; + MethodTableList targetInstantiation = pTargetType->GenericArguments; int targetArity = (int)pTargetType->GenericArity; GenericVariance* pTargetVarianceInfo = pTargetType->GenericVariance; Debug.Assert(pTargetVarianceInfo != null, "did not expect empty variance info"); - EETypeRef* pSourceInstantiation = pSourceType->GenericArguments; + MethodTableList sourceInstantiation = pSourceType->GenericArguments; int sourceArity = (int)pSourceType->GenericArity; GenericVariance* pSourceVarianceInfo = pSourceType->GenericVariance; @@ -357,8 +357,8 @@ private static unsafe bool TypesAreCompatibleViaGenericVariance(MethodTable* pSo // Compare the instantiations to see if they're compatible taking variance into account. if (TypeParametersAreCompatible(targetArity, - pSourceInstantiation, - pTargetInstantiation, + sourceInstantiation, + targetInstantiation, pTargetVarianceInfo, false, pVisited)) @@ -376,8 +376,8 @@ private static unsafe bool TypesAreCompatibleViaGenericVariance(MethodTable* pSo // override the defined variance of each parameter and instead assume it is covariant. This is used to // implement covariant array interfaces. internal static unsafe bool TypeParametersAreCompatible(int arity, - EETypeRef* pSourceInstantiation, - EETypeRef* pTargetInstantiation, + MethodTableList sourceInstantiation, + MethodTableList targetInstantiation, GenericVariance* pVarianceInfo, bool fForceCovariance, EETypePairList* pVisited) @@ -386,8 +386,8 @@ internal static unsafe bool TypeParametersAreCompatible(int arity, // of type args. for (int i = 0; i < arity; i++) { - MethodTable* pTargetArgType = pTargetInstantiation[i].Value; - MethodTable* pSourceArgType = pSourceInstantiation[i].Value; + MethodTable* pTargetArgType = targetInstantiation[i]; + MethodTable* pSourceArgType = sourceInstantiation[i]; GenericVariance varType; if (fForceCovariance) @@ -400,7 +400,7 @@ internal static unsafe bool TypeParametersAreCompatible(int arity, case GenericVariance.NonVariant: // Non-variant type params need to be identical. - if (!AreTypesEquivalent(pSourceArgType, pTargetArgType)) + if (pSourceArgType != pTargetArgType) return false; break; @@ -484,7 +484,7 @@ public static unsafe bool AreTypesAssignable(MethodTable* pSourceType, MethodTab { MethodTable* pNullableType = pTargetType->NullableType; - return AreTypesEquivalent(pSourceType, pNullableType); + return pSourceType == pNullableType; } return AreTypesAssignableInternal(pSourceType, pTargetType, AssignmentVariation.BoxedSource, null); @@ -503,7 +503,7 @@ internal static unsafe bool AreTypesAssignableInternalUncached(MethodTable* pSou // // Are the types identical? // - if (AreTypesEquivalent(pSourceType, pTargetType)) + if (pSourceType == pTargetType) return true; // @@ -543,7 +543,7 @@ internal static unsafe bool AreTypesAssignableInternalUncached(MethodTable* pSou if (pSourceRelatedParameterType->IsPointerType) { // If the parameter types are pointers, then only exact matches are correct. - // As we've already called AreTypesEquivalent at the start of this function, + // As we've already compared equality at the start of this function, // return false as the exact match case has already been handled. // int** is not compatible with uint**, nor is int*[] oompatible with uint*[]. return false; @@ -558,7 +558,7 @@ internal static unsafe bool AreTypesAssignableInternalUncached(MethodTable* pSou else if (pSourceRelatedParameterType->IsFunctionPointerType) { // If the parameter types are function pointers, then only exact matches are correct. - // As we've already called AreTypesEquivalent at the start of this function, + // As we've already compared equality at the start of this function, // return false as the exact match case has already been handled. return false; } @@ -697,36 +697,6 @@ public static unsafe void CheckArrayStore(object array, object obj) throw array.GetMethodTable()->GetClasslibException(ExceptionIDs.ArrayTypeMismatch); } - [RuntimeExport("RhTypeCast_CheckVectorElemAddr")] - public static unsafe void CheckVectorElemAddr(MethodTable* elemType, object array) - { - if (array == null) - { - return; - } - - Debug.Assert(array.GetMethodTable()->IsArray, "second argument must be an array"); - - MethodTable* arrayElemType = array.GetMethodTable()->RelatedParameterType; - - if (!AreTypesEquivalent(elemType, arrayElemType) - // In addition to the exactness check, add another check to allow non-exact matches through - // if the element type is a ValueType. The issue here is Universal Generics. The Universal - // Generic codegen will generate a call to this helper for all ldelema opcodes if the exact - // type is not known, and this can include ValueTypes. For ValueTypes, the exact check is not - // desirable as enum's are allowed to pass through this code if they are size matched. - // While this check is overly broad and allows non-enum valuetypes to also skip the check - // that is OK, because in the non-enum case the casting operations are sufficient to ensure - // type safety. - && !elemType->IsValueType) - { - // Throw the array type mismatch exception defined by the classlib, using the input array's MethodTable* - // to find the correct classlib. - - throw array.GetMethodTable()->GetClasslibException(ExceptionIDs.ArrayTypeMismatch); - } - } - internal struct ArrayElement { public object Value; @@ -838,7 +808,7 @@ public static unsafe ref object LdelemaRef(Array array, nint index, IntPtr eleme MethodTable* elemType = (MethodTable*)elementType; MethodTable* arrayElemType = array.GetMethodTable()->RelatedParameterType; - if (AreTypesEquivalent(elemType, arrayElemType)) + if (elemType == arrayElemType) { return ref element; } @@ -859,39 +829,20 @@ internal static unsafe bool IsDerived(MethodTable* pDerivedType, MethodTable* pB Debug.Assert(pDerivedType->IsCanonical || pDerivedType->IsGenericTypeDefinition, "unexpected MethodTable"); // If a generic type definition reaches this function, then the function should return false unless the types are equivalent. - // This works as the NonClonedNonArrayBaseType of a GenericTypeDefinition is always null. + // This works as the NonArrayBaseType of a GenericTypeDefinition is always null. do { if (pDerivedType == pBaseType) return true; - pDerivedType = pDerivedType->NonClonedNonArrayBaseType; + pDerivedType = pDerivedType->NonArrayBaseType; } while (pDerivedType != null); return false; } - // Method to compare two types pointers for type equality - // We cannot just compare the pointers as there can be duplicate type instances - // for cloned and constructed types. - // There are three separate cases here - // 1. The pointers are Equal => true - // 2. Either one or both the types are CLONED, follow to the canonical MethodTable and check - // 3. For Arrays/Pointers, we have to further check for rank and element type equality - [RuntimeExport("RhTypeCast_AreTypesEquivalent")] - public static unsafe bool AreTypesEquivalent(MethodTable* pType1, MethodTable* pType2) - { - if (pType1 == pType2) - return true; - - if (pType1->IsParameterizedType && pType2->IsParameterizedType) - return AreTypesEquivalent(pType1->RelatedParameterType, pType2->RelatedParameterType) && pType1->ParameterizedTypeShape == pType2->ParameterizedTypeShape; - - return false; - } - // this is necessary for shared generic code - Foo may be executing // for T being an interface, an array or a class [RuntimeExport("RhTypeCast_IsInstanceOf")] @@ -927,7 +878,7 @@ public static unsafe bool IsInstanceOfException(MethodTable* pTargetType, object while (true) { - pObjType = pObjType->NonClonedNonArrayBaseType; + pObjType = pObjType->NonArrayBaseType; if (pObjType == null) return false; diff --git a/src/coreclr/nativeaot/Runtime/AsmOffsets.h b/src/coreclr/nativeaot/Runtime/AsmOffsets.h index 9e774d8c0d47f4..e28386e1d3b5b8 100644 --- a/src/coreclr/nativeaot/Runtime/AsmOffsets.h +++ b/src/coreclr/nativeaot/Runtime/AsmOffsets.h @@ -34,6 +34,13 @@ ASM_CONST( 2, 2, STRING_COMPONENT_SIZE) ASM_CONST( E, 16, STRING_BASE_SIZE) ASM_CONST(3FFFFFDF,3FFFFFDF,MAX_STRING_LENGTH) + +#if defined(HOST_ARM64) +// Bit position for the ARM64IntrinsicConstants_Atomics flags, to be used with tbz / tbnz instructions +// ARM64IntrinsicConstants_Atomics = 0x0080 +ASM_CONST( 7, 7, ARM64_ATOMICS_FEATURE_FLAG_BIT) +#endif + ASM_OFFSET( 0, 0, MethodTable, m_usComponentSize) ASM_OFFSET( 0, 0, MethodTable, m_uFlags) ASM_OFFSET( 4, 4, MethodTable, m_uBaseSize) diff --git a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp index 61f7b40f1b6b76..4cceb181ea6719 100644 --- a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp +++ b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp @@ -76,7 +76,7 @@ struct DotNetRuntimeDebugHeader // This counter can be incremented to indicate breaking changes // This field must be encoded little endian, regardless of the typical endianness of // the machine - const uint16_t MajorVersion = 2; + const uint16_t MajorVersion = 3; // This counter can be incremented to indicate back-compatible changes // This field must be encoded little endian, regardless of the typical endianness of @@ -201,11 +201,7 @@ extern "C" void PopulateDebugHeaders() MAKE_DEBUG_FIELD_ENTRY(MethodTable, m_usComponentSize); MAKE_DEBUG_FIELD_ENTRY(MethodTable, m_uFlags); MAKE_DEBUG_ENTRY(MethodTable, m_pBaseType, offsetof(MethodTable, m_RelatedType) + offsetof(MethodTable::RelatedTypeUnion, m_pBaseType)); - MAKE_DEBUG_ENTRY(MethodTable, m_ppBaseTypeViaIAT, offsetof(MethodTable, m_RelatedType) + offsetof(MethodTable::RelatedTypeUnion, m_ppBaseTypeViaIAT)); - MAKE_DEBUG_ENTRY(MethodTable, m_pCanonicalType, offsetof(MethodTable, m_RelatedType) + offsetof(MethodTable::RelatedTypeUnion, m_pCanonicalType)); - MAKE_DEBUG_ENTRY(MethodTable, m_ppCanonicalTypeViaIAT, offsetof(MethodTable, m_RelatedType) + offsetof(MethodTable::RelatedTypeUnion, m_ppCanonicalTypeViaIAT)); MAKE_DEBUG_ENTRY(MethodTable, m_pRelatedParameterType, offsetof(MethodTable, m_RelatedType) + offsetof(MethodTable::RelatedTypeUnion, m_pRelatedParameterType)); - MAKE_DEBUG_ENTRY(MethodTable, m_ppRelatedParameterTypeViaIAT, offsetof(MethodTable, m_RelatedType) + offsetof(MethodTable::RelatedTypeUnion, m_ppRelatedParameterTypeViaIAT)); MAKE_DEBUG_FIELD_ENTRY(MethodTable, m_VTable); MAKE_SIZE_ENTRY(StressLog); @@ -270,7 +266,6 @@ extern "C" void PopulateDebugHeaders() DotNetRuntimeDebugHeader.GlobalEntries = &s_GlobalEntries; static_assert(MethodTable::Flags::EETypeKindMask == 0x00030000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number."); - static_assert(MethodTable::Flags::RelatedTypeViaIATFlag == 0x00040000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number."); static_assert(MethodTable::Flags::HasFinalizerFlag == 0x00100000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number."); static_assert(MethodTable::Flags::HasPointersFlag == 0x00200000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number."); static_assert(MethodTable::Flags::GenericVarianceFlag == 0x00800000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number."); diff --git a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp index 37d593b6c7afc5..28e33fb5a299fd 100644 --- a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp @@ -202,11 +202,10 @@ EXTERN_C int32_t __stdcall RhpPInvokeExceptionGuard(PEXCEPTION_RECORD pExc Thread * pThread = ThreadStore::GetCurrentThread(); - // If the thread is currently in the "do not trigger GC" mode, we must not allocate, we must not reverse pinvoke, or - // return from a pinvoke. All of these things will deadlock with the GC and they all become increasingly likely as - // exception dispatch kicks off. So we just address this as early as possible with a FailFast. The most - // likely case where this occurs is in our GC-callouts for Jupiter lifetime management -- in that case, we have - // managed code that calls to native code (without pinvoking) which might have a bug that causes an AV. + // A thread in DoNotTriggerGc mode has many restrictions that will become increasingly likely to be violated as + // exception dispatch kicks off. So we just address this as early as possible with a FailFast. + // The most likely case where this occurs is in GC-callouts -- in that case, we have + // managed code that runs on behalf of GC, which might have a bug that causes an AV. if (pThread->IsDoNotTriggerGcSet()) RhFailFast(); @@ -286,6 +285,16 @@ EXTERN_C void * RhpCheckedLockCmpXchgAVLocation; EXTERN_C void * RhpCheckedXchgAVLocation; EXTERN_C void * RhpLockCmpXchg32AVLocation; EXTERN_C void * RhpLockCmpXchg64AVLocation; +EXTERN_C void * RhpByRefAssignRefAVLocation1; + +#if !defined(HOST_ARM64) +EXTERN_C void * RhpByRefAssignRefAVLocation2; +#endif + +#if defined(HOST_ARM64) && !defined(LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT) +EXTERN_C void* RhpCheckedLockCmpXchgAVLocation2; +EXTERN_C void* RhpCheckedXchgAVLocation2; +#endif static bool InWriteBarrierHelper(uintptr_t faultingIP) { @@ -298,6 +307,14 @@ static bool InWriteBarrierHelper(uintptr_t faultingIP) (uintptr_t)&RhpCheckedXchgAVLocation, (uintptr_t)&RhpLockCmpXchg32AVLocation, (uintptr_t)&RhpLockCmpXchg64AVLocation, + (uintptr_t)&RhpByRefAssignRefAVLocation1, +#if !defined(HOST_ARM64) + (uintptr_t)&RhpByRefAssignRefAVLocation2, +#endif +#if defined(HOST_ARM64) && !defined(LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT) + (uintptr_t)&RhpCheckedLockCmpXchgAVLocation2, + (uintptr_t)&RhpCheckedXchgAVLocation2, +#endif }; // compare the IP against the list of known possible AV locations in the write barrier helpers diff --git a/src/coreclr/nativeaot/Runtime/IntrinsicConstants.h b/src/coreclr/nativeaot/Runtime/IntrinsicConstants.h index e80b42ccb0ed34..67ba547488e960 100644 --- a/src/coreclr/nativeaot/Runtime/IntrinsicConstants.h +++ b/src/coreclr/nativeaot/Runtime/IntrinsicConstants.h @@ -32,6 +32,8 @@ enum XArchIntrinsicConstants XArchIntrinsicConstants_Avx512cd_vl = 0x100000, XArchIntrinsicConstants_Avx512dq = 0x200000, XArchIntrinsicConstants_Avx512dq_vl = 0x400000, + XArchIntrinsicConstants_Avx512Vbmi = 0x800000, + XArchIntrinsicConstants_Avx512Vbmi_vl = 0x1000000, }; #endif //HOST_X86 || HOST_AMD64 @@ -48,6 +50,11 @@ enum ARM64IntrinsicConstants ARM64IntrinsicConstants_Atomics = 0x0080, ARM64IntrinsicConstants_Rcpc = 0x0100, }; + +// Bit position for the ARM64IntrinsicConstants_Atomics flags, to be used with tbz / tbnz instructions +static const int ARM64_ATOMICS_FEATURE_FLAG_BIT = 7; +static_assert((1 << ARM64_ATOMICS_FEATURE_FLAG_BIT) == ARM64IntrinsicConstants_Atomics, "ARM64_ATOMICS_FEATURE_FLAG_BIT must match with ARM64IntrinsicConstants_Atomics"); + #endif //HOST_ARM64 #endif //!INTRINSICCONSTANTS_INCLUDED diff --git a/src/coreclr/nativeaot/Runtime/MethodTable.cpp b/src/coreclr/nativeaot/Runtime/MethodTable.cpp index a5bfaddd826f28..26130e715467aa 100644 --- a/src/coreclr/nativeaot/Runtime/MethodTable.cpp +++ b/src/coreclr/nativeaot/Runtime/MethodTable.cpp @@ -42,8 +42,7 @@ bool MethodTable::Validate(bool assertOnFail /* default: true */) // If the parent type is NULL this had better look like Object. if (!IsInterface() && (m_RelatedType.m_pBaseType == NULL)) { - if (IsRelatedTypeViaIAT() || - get_IsValueType() || + if (get_IsValueType() || HasFinalizer() || HasReferenceFields() || HasGenericVariance()) @@ -104,8 +103,5 @@ MethodTable * MethodTable::get_RelatedParameterType() { ASSERT(IsParameterizedType()); - if (IsRelatedTypeViaIAT()) - return *PTR_PTR_EEType(reinterpret_cast(m_RelatedType.m_ppRelatedParameterTypeViaIAT)); - else - return PTR_EEType(reinterpret_cast(m_RelatedType.m_pRelatedParameterType)); + return PTR_EEType(reinterpret_cast(m_RelatedType.m_pRelatedParameterType)); } diff --git a/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp b/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp index e7af0aa45499f7..3dc6e98dfeb76d 100644 --- a/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp +++ b/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp @@ -774,7 +774,8 @@ void StackFrameIterator::UnwindFuncletInvokeThunk() #if defined(USE_PORTABLE_HELPERS) // @TODO: Currently no funclet invoke defined in a portable way return; #else // defined(USE_PORTABLE_HELPERS) - ASSERT(CategorizeUnadjustedReturnAddress(m_ControlPC) == InFuncletInvokeThunk); + ASSERT((CategorizeUnadjustedReturnAddress(m_ControlPC) == InFuncletInvokeThunk) || + (CategorizeUnadjustedReturnAddress(m_ControlPC) == InFilterFuncletInvokeThunk)); PTR_UIntNative SP; @@ -1512,6 +1513,12 @@ void StackFrameIterator::NextInternal() exCollide = true; } } + else if (category == InFilterFuncletInvokeThunk) + { + // Unwind through the funclet invoke assembly thunk to reach the topmost managed frame in + // the exception dispatch code. + UnwindFuncletInvokeThunk(); + } else if (category == InManagedCode) { // Non-exceptionally invoked funclet case. The caller is processed as a normal managed @@ -1932,19 +1939,33 @@ StackFrameIterator::ReturnAddressCategory StackFrameIterator::CategorizeUnadjust return InThrowSiteThunk; } - if ( #ifdef TARGET_X86 - EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFunclet2) -#else - EQUALS_RETURN_ADDRESS(returnAddress, RhpCallCatchFunclet2) || - EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFinallyFunclet2) || - EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFilterFunclet2) -#endif - ) + if (EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFunclet2)) + { + // See if it is a filter funclet based on the caller of RhpCallFunclet + PTR_UIntNative SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x4); // skip the saved assembly-routine-EBP + PTR_UIntNative ControlPC = *SP++; + if (EQUALS_RETURN_ADDRESS(ControlPC, RhpCallFilterFunclet2)) + { + return InFilterFuncletInvokeThunk; + } + else + { + return InFuncletInvokeThunk; + } + } +#else // TARGET_X86 + if (EQUALS_RETURN_ADDRESS(returnAddress, RhpCallCatchFunclet2) || + EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFinallyFunclet2)) { return InFuncletInvokeThunk; } + if (EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFilterFunclet2)) + { + return InFilterFuncletInvokeThunk; + } +#endif // TARGET_X86 return InManagedCode; #endif // defined(USE_PORTABLE_HELPERS) } diff --git a/src/coreclr/nativeaot/Runtime/StackFrameIterator.h b/src/coreclr/nativeaot/Runtime/StackFrameIterator.h index f01ca6656fbf2a..9551e4caeed497 100644 --- a/src/coreclr/nativeaot/Runtime/StackFrameIterator.h +++ b/src/coreclr/nativeaot/Runtime/StackFrameIterator.h @@ -114,6 +114,7 @@ class StackFrameIterator InManagedCode, InThrowSiteThunk, InFuncletInvokeThunk, + InFilterFuncletInvokeThunk, InCallDescrThunk, InUniversalTransitionThunk, }; diff --git a/src/coreclr/nativeaot/Runtime/TypeManager.cpp b/src/coreclr/nativeaot/Runtime/TypeManager.cpp index a8e372956aedd9..8458f883be2b59 100644 --- a/src/coreclr/nativeaot/Runtime/TypeManager.cpp +++ b/src/coreclr/nativeaot/Runtime/TypeManager.cpp @@ -45,7 +45,6 @@ TypeManager::TypeManager(HANDLE osModule, ReadyToRunHeader * pHeader, void** pCl int length; m_pStaticsGCDataSection = (uint8_t*)GetModuleSection(ReadyToRunSectionType::GCStaticRegion, &length); m_pThreadStaticsDataSection = (uint8_t*)GetModuleSection(ReadyToRunSectionType::ThreadStaticRegion, &length); - m_pDispatchMapTable = (DispatchMap **)GetModuleSection(ReadyToRunSectionType::InterfaceDispatchTable, &length); } void * TypeManager::GetModuleSection(ReadyToRunSectionType sectionId, int * length) diff --git a/src/coreclr/nativeaot/Runtime/TypeManager.h b/src/coreclr/nativeaot/Runtime/TypeManager.h index 84d1ead3de344f..91a38ffbbacf98 100644 --- a/src/coreclr/nativeaot/Runtime/TypeManager.h +++ b/src/coreclr/nativeaot/Runtime/TypeManager.h @@ -4,14 +4,11 @@ #include "ModuleHeaders.h" #include "ICodeManager.h" -class DispatchMap; - class TypeManager { // NOTE: Part of this layout is a contract with the managed side in TypeManagerHandle.cs HANDLE m_osModule; ReadyToRunHeader * m_pHeader; - DispatchMap** m_pDispatchMapTable; uint8_t* m_pStaticsGCDataSection; uint8_t* m_pThreadStaticsDataSection; void** m_pClasslibFunctions; diff --git a/src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc b/src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc index 5db25fd935138c..55ca399b4e405c 100644 --- a/src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc +++ b/src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc @@ -420,4 +420,3 @@ endif ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP EXTERN g_write_watch_table : QWORD endif - diff --git a/src/coreclr/nativeaot/Runtime/amd64/GetThread.asm b/src/coreclr/nativeaot/Runtime/amd64/GetThread.asm deleted file mode 100644 index 806f8db2c72298..00000000000000 --- a/src/coreclr/nativeaot/Runtime/amd64/GetThread.asm +++ /dev/null @@ -1,27 +0,0 @@ -;; Licensed to the .NET Foundation under one or more agreements. -;; The .NET Foundation licenses this file to you under the MIT license. - -include asmmacros.inc - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; RhpGetThread -;; -;; -;; INPUT: -;; -;; OUTPUT: RAX: Thread pointer -;; -;; TRASHES: R10 -;; -;; MUST PRESERVE ARGUMENT REGISTERS -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -LEAF_ENTRY RhpGetThread, _TEXT - ;; rax = GetThread(), TRASHES r10 - INLINE_GETTHREAD rax, r10 - ret -LEAF_END RhpGetThread, _TEXT - - - end diff --git a/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.S b/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.S index 3888d0a8adfeab..cc740a9c0601f7 100644 --- a/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.S +++ b/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.S @@ -260,8 +260,13 @@ LEAF_END RhpCheckedXchg, _TEXT // rdi, rsi are incremented by 8, // rcx, r10, r11: trashed // +// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular: +// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpByRefAssignRefAVLocation1/2 +// - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address LEAF_ENTRY RhpByRefAssignRef, _TEXT +ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 mov rcx, [rsi] +ALTERNATE_ENTRY RhpByRefAssignRefAVLocation2 mov [rdi], rcx // Check whether the writes were even into the heap. If not there's no card update required. diff --git a/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm b/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm index 753ca45609797f..148aa7d1301b1c 100644 --- a/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm +++ b/src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm @@ -276,8 +276,13 @@ LEAF_END RhpCheckedXchg, _TEXT ;; rdi, rsi are incremented by 8, ;; rcx, r10, r11: trashed ;; +;; WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular: +;; - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpByRefAssignRefAVLocation1/2 +;; - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address LEAF_ENTRY RhpByRefAssignRef, _TEXT +ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 mov rcx, [rsi] +ALTERNATE_ENTRY RhpByRefAssignRefAVLocation2 mov [rdi], rcx ;; Check whether the writes were even into the heap. If not there's no card update required. diff --git a/src/coreclr/nativeaot/Runtime/arm/GetThread.asm b/src/coreclr/nativeaot/Runtime/arm/GetThread.asm deleted file mode 100644 index b78319f8f15c24..00000000000000 --- a/src/coreclr/nativeaot/Runtime/arm/GetThread.asm +++ /dev/null @@ -1,32 +0,0 @@ -;; Licensed to the .NET Foundation under one or more agreements. -;; The .NET Foundation licenses this file to you under the MIT license. - -#include "AsmMacros.h" - - TEXTAREA - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; RhpGetThread -;; -;; -;; INPUT: none -;; -;; OUTPUT: r0: Thread pointer -;; -;; MUST PRESERVE ARGUMENT REGISTERS -;; @todo check the actual requirements here, r0 is both return and argument register -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - LEAF_ENTRY RhpGetThread - - ;; r0 = GetThread(), TRASHES r12 - INLINE_GETTHREAD r0, r12 - bx lr - - LEAF_END -FASTCALL_ENDFUNC - - INLINE_GETTHREAD_CONSTANT_POOL - - end diff --git a/src/coreclr/nativeaot/Runtime/arm/WriteBarriers.S b/src/coreclr/nativeaot/Runtime/arm/WriteBarriers.S index 863e17cc9fdf9f..30e20c4bea401f 100644 --- a/src/coreclr/nativeaot/Runtime/arm/WriteBarriers.S +++ b/src/coreclr/nativeaot/Runtime/arm/WriteBarriers.S @@ -322,11 +322,16 @@ LEAF_END RhpCheckedXchg, _TEXT // r0, r1 are incremented by 4, // r2, r3: trashed // +// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular: +// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpByRefAssignRefAVLocation1/2 +// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address LEAF_ENTRY RhpByRefAssignRef, _TEXT // See comment in RhpAssignRef dmb +ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 ldr r2, [r1] +ALTERNATE_ENTRY RhpByRefAssignRefAVLocation2 str r2, [r0] // Check whether the writes were even into the heap. If not there's no card update required. diff --git a/src/coreclr/nativeaot/Runtime/arm64/AllocFast.asm b/src/coreclr/nativeaot/Runtime/arm64/AllocFast.asm index 560c6dcbad52d8..e6849b87312669 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/AllocFast.asm +++ b/src/coreclr/nativeaot/Runtime/arm64/AllocFast.asm @@ -48,8 +48,6 @@ RhpNewFast_RarePath b RhpNewObject LEAF_END RhpNewFast - INLINE_GETTHREAD_CONSTANT_POOL - ;; Allocate non-array object with finalizer. ;; x0 == MethodTable LEAF_ENTRY RhpNewFinalizable @@ -149,9 +147,6 @@ StringSizeOverflow b RhExceptionHandling_FailedAllocation LEAF_END RhNewString - INLINE_GETTHREAD_CONSTANT_POOL - - ;; Allocate one dimensional, zero based array (SZARRAY). ;; x0 == MethodTable ;; x1 == element count @@ -213,8 +208,6 @@ ArraySizeOverflow b RhExceptionHandling_FailedAllocation LEAF_END RhpNewArray - INLINE_GETTHREAD_CONSTANT_POOL - ;; Allocate one dimensional, zero based array (SZARRAY) using the slow path that calls a runtime helper. ;; x0 == MethodTable ;; x1 == element count diff --git a/src/coreclr/nativeaot/Runtime/arm64/AsmMacros.h b/src/coreclr/nativeaot/Runtime/arm64/AsmMacros.h index de4aef3d267773..6fc40e8d1d665a 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/AsmMacros.h +++ b/src/coreclr/nativeaot/Runtime/arm64/AsmMacros.h @@ -116,6 +116,7 @@ OFFSETOF__Thread__m_alloc_context__alloc_limit equ OFFSETOF__Thread__m_rgbA EXTERN g_write_watch_table #endif + EXTERN g_cpuFeatures ;; ----------------------------------------------------------------------------- ;; Macro used to assign an alternate name to a symbol containing characters normally disallowed in a symbol @@ -163,6 +164,16 @@ MovInstr SETS "movk" ldr $Reg, [$Reg, $Name] MEND +;; ---------------------------------------------------------------------------- - +;; Macro for loading a 32bit value of a global variable into a register + MACRO + PREPARE_EXTERNAL_VAR_INDIRECT_W $Name, $RegNum + + adrp x$RegNum, $Name + ldr w$RegNum, [x$RegNum, $Name] + MEND + + ;; ----------------------------------------------------------------------------- ;; ;; Macro to export a pointer to an address inside a stub as a 64-bit variable @@ -200,18 +211,16 @@ CodeLbl SETS "$Name":CC:"Lbl" ;; ----------------------------------------------------------------------------- ;; -;; Macro to get a pointer to the Thread* object for the currently executing thread +;; Macro to get a pointer to a threadlocal symbol for the currently executing thread ;; __tls_array equ 0x58 ;; offsetof(TEB, ThreadLocalStoragePointer) - EXTERN _tls_index - - GBLS __SECTIONREL_tls_CurrentThread -__SECTIONREL_tls_CurrentThread SETS "SECTIONREL_tls_CurrentThread" - MACRO - INLINE_GETTHREAD $destReg, $trashReg + INLINE_GET_TLS_VAR $destReg, $trashReg, $variable + + EXTERN _tls_index + EXTERN $variable ;; The following macro variables are just some assembler magic to get the name of the 32-bit version ;; of $trashReg. It does it by string manipulation. Replaces something like x3 with w3. @@ -219,32 +228,27 @@ __SECTIONREL_tls_CurrentThread SETS "SECTIONREL_tls_CurrentThread" TrashRegister32Bit SETS "$trashReg" TrashRegister32Bit SETS "w":CC:("$TrashRegister32Bit":RIGHT:((:LEN:TrashRegister32Bit) - 1)) - ldr $trashReg, =_tls_index - ldr $TrashRegister32Bit, [$trashReg] + adrp $destReg, _tls_index + ldr $TrashRegister32Bit, [$destReg, _tls_index] ldr $destReg, [xpr, #__tls_array] - ldr $destReg, [$destReg, $trashReg lsl #3] - ldr $trashReg, =$__SECTIONREL_tls_CurrentThread - ldr $trashReg, [$trashReg] - add $destReg, $destReg, $trashReg + ldr $destReg, [$destReg, $TrashRegister32Bit uxtw #3] + add $destReg, $destReg, #0, lsl #0xC + RELOC 0xA, $variable ;; IMAGE_REL_ARM64_SECREL_HIGH12A + add $destReg, $destReg, #0, lsl #0 + RELOC 0x9, $variable ;; IMAGE_REL_ARM64_SECREL_LOW12A MEND - ;; INLINE_GETTHREAD_CONSTANT_POOL macro has to be used after the last function in the .asm file that used - ;; INLINE_GETTHREAD. Optionally, it can be also used after any function that used INLINE_GETTHREAD - ;; to improve density, or to reduce distance between the constant pool and its use. +;; ----------------------------------------------------------------------------- +;; +;; Macro to get a pointer to the Thread* object for the currently executing thread +;; MACRO - INLINE_GETTHREAD_CONSTANT_POOL - EXTERN tls_CurrentThread - - ;; Section relocs are 32 bits. Using an extra DCD initialized to zero for 8-byte alignment. -$__SECTIONREL_tls_CurrentThread - DCD tls_CurrentThread - RELOC 8, tls_CurrentThread ;; SECREL - DCD 0 - -__SECTIONREL_tls_CurrentThread SETS "$__SECTIONREL_tls_CurrentThread":CC:"_" + INLINE_GETTHREAD $destReg, $trashReg + INLINE_GET_TLS_VAR $destReg, $trashReg, tls_CurrentThread MEND + MACRO INLINE_THREAD_UNHIJACK $threadReg, $trashReg1, $trashReg2 ;; diff --git a/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.asm b/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.asm index 3db1d648c4deec..1af4fd19f0c664 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.asm +++ b/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.asm @@ -624,6 +624,4 @@ SetSuccess NESTED_END RhpCallFilterFunclet - INLINE_GETTHREAD_CONSTANT_POOL - end diff --git a/src/coreclr/nativeaot/Runtime/arm64/GcProbe.asm b/src/coreclr/nativeaot/Runtime/arm64/GcProbe.asm index ef01e43b5e1ff4..d95ab7a0320708 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/GcProbe.asm +++ b/src/coreclr/nativeaot/Runtime/arm64/GcProbe.asm @@ -366,7 +366,5 @@ Success LEAF_END RhpSuppressGcStress #endif ;; FEATURE_GC_STRESS - INLINE_GETTHREAD_CONSTANT_POOL - end diff --git a/src/coreclr/nativeaot/Runtime/arm64/GetThread.asm b/src/coreclr/nativeaot/Runtime/arm64/GetThread.asm deleted file mode 100644 index 7c01e66453385c..00000000000000 --- a/src/coreclr/nativeaot/Runtime/arm64/GetThread.asm +++ /dev/null @@ -1,29 +0,0 @@ -;; Licensed to the .NET Foundation under one or more agreements. -;; The .NET Foundation licenses this file to you under the MIT license. - -#include "AsmMacros.h" - - TEXTAREA - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; RhpGetThread -;; -;; -;; INPUT: none -;; -;; OUTPUT: x9: Thread pointer -;; -;; MUST PRESERVE ARGUMENT REGISTERS -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - LEAF_ENTRY RhpGetThread - ;; x9 = GetThread(), TRASHES xip0 (which can be used as an intra-procedure-call scratch register) - INLINE_GETTHREAD x9, xip0 - ret - LEAF_END -FASTCALL_ENDFUNC - - INLINE_GETTHREAD_CONSTANT_POOL - - end diff --git a/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm b/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm index 475737fea71a0e..52d55ad2846c77 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm +++ b/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm @@ -34,8 +34,6 @@ ret NESTED_END RhpPInvoke - INLINE_GETTHREAD_CONSTANT_POOL - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff --git a/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S b/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S index 8fbbce7fd8186a..d00ffb3a4a9978 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S +++ b/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S @@ -192,8 +192,12 @@ // x15 : trashed // x12, x17 : trashed // +// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular: +// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpByRefAssignRefAVLocation1 +// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address LEAF_ENTRY RhpByRefAssignRefArm64, _TEXT + ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 ldr x15, [x13], 8 b C_FUNC(RhpCheckedAssignRefArm64) @@ -268,6 +272,10 @@ LEAF_END RhpAssignRef, _TEXT // - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedLockCmpXchgAVLocation // - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT +.arch_extension lse +#endif + // RhpCheckedLockCmpXchg(Object** dest, Object* value, Object* comparand) // // Interlocked compare exchange on objectref. @@ -279,13 +287,26 @@ LEAF_END RhpAssignRef, _TEXT // // On exit: // x0: original value of objectref -// x10, x12, x17: trashed +// x10, x12, x16, x17: trashed // LEAF_ENTRY RhpCheckedLockCmpXchg +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + PREPARE_EXTERNAL_VAR_INDIRECT_W g_cpuFeatures, 16 + tbz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, CmpXchgRetry +#endif + + mov x10, x2 + ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation + casal x10, x1, [x0] // exchange + cmp x2, x10 + bne CmpXchgNoUpdate + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + b DoCardsCmpXchg CmpXchgRetry: // Check location value is what we expect. - ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation + ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation2 ldaxr x10, [x0] cmp x10, x2 bne CmpXchgNoUpdate @@ -293,7 +314,9 @@ CmpXchgRetry: // Current value matches comparand, attempt to update with the new value. stlxr w12, x1, [x0] cbnz w12, CmpXchgRetry +#endif +DoCardsCmpXchg: // We have successfully updated the value of the objectref so now we need a GC write barrier. // The following barrier code takes the destination in x0 and the value in x1 so the arguments are // already correctly set up. @@ -303,7 +326,12 @@ CmpXchgRetry: CmpXchgNoUpdate: // x10 still contains the original value. mov x0, x10 + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + tbnz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, NoBarrierCmpXchg InterlockedOperationBarrier +NoBarrierCmpXchg: +#endif ret lr LEAF_END RhpCheckedLockCmpXchg, _TEXT @@ -323,19 +351,31 @@ CmpXchgNoUpdate: // On exit: // x0: original value of objectref // x10: trashed -// x12, x17: trashed +// x12, x16, x17: trashed // LEAF_ENTRY RhpCheckedXchg, _TEXT +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + PREPARE_EXTERNAL_VAR_INDIRECT_W g_cpuFeatures, 16 + tbz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, ExchangeRetry +#endif + + ALTERNATE_ENTRY RhpCheckedXchgAVLocation + swpal x1, x10, [x0] // exchange + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + b DoCardsXchg ExchangeRetry: // Read the existing memory location. - ALTERNATE_ENTRY RhpCheckedXchgAVLocation + ALTERNATE_ENTRY RhpCheckedXchgAVLocation2 ldaxr x10, [x0] // Attempt to update with the new value. stlxr w12, x1, [x0] cbnz w12, ExchangeRetry +#endif +DoCardsXchg: // We have successfully updated the value of the objectref so now we need a GC write barrier. // The following barrier code takes the destination in x0 and the value in x1 so the arguments are // already correctly set up. @@ -344,7 +384,16 @@ ExchangeRetry: // x10 still contains the original value. mov x0, x10 + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + tbnz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, NoBarrierXchg InterlockedOperationBarrier +NoBarrierXchg: +#endif ret LEAF_END RhpCheckedXchg, _TEXT + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT +.arch_extension nolse +#endif diff --git a/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.asm b/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.asm index 62639a7a6de42c..26a8ef30387c5e 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.asm +++ b/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.asm @@ -206,8 +206,12 @@ INVALIDGCVALUE EQU 0xCCCCCCCD ;; x15 : trashed ;; x12, x17 : trashed ;; +;; WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular: +;; - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpByRefAssignRefAVLocation1 +;; - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address LEAF_ENTRY RhpByRefAssignRefArm64, _TEXT + ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 ldr x15, [x13], 8 b RhpCheckedAssignRefArm64 @@ -294,13 +298,26 @@ NotInHeap ;; ;; On exit: ;; x0: original value of objectref -;; x10, x12, x17: trashed +;; x10, x12, x16, x17: trashed ;; LEAF_ENTRY RhpCheckedLockCmpXchg +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + PREPARE_EXTERNAL_VAR_INDIRECT_W g_cpuFeatures, 16 + tbz x16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, CmpXchgRetry +#endif + + mov x10, x2 + ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation + casal x10, x1, [x0] ;; exchange + cmp x2, x10 + bne CmpXchgNoUpdate + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + b DoCardsCmpXchg CmpXchgRetry ;; Check location value is what we expect. - ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation + ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation2 ldaxr x10, [x0] cmp x10, x2 bne CmpXchgNoUpdate @@ -308,8 +325,10 @@ CmpXchgRetry ;; Current value matches comparand, attempt to update with the new value. stlxr w12, x1, [x0] cbnz w12, CmpXchgRetry +#endif - ;; We've successfully updated the value of the objectref so now we need a GC write barrier. +DoCardsCmpXchg + ;; We have successfully updated the value of the objectref so now we need a GC write barrier. ;; The following barrier code takes the destination in x0 and the value in x1 so the arguments are ;; already correctly set up. @@ -318,7 +337,12 @@ CmpXchgRetry CmpXchgNoUpdate ;; x10 still contains the original value. mov x0, x10 + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + tbnz x16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, NoBarrierCmpXchg InterlockedOperationBarrier +NoBarrierCmpXchg +#endif ret lr LEAF_END RhpCheckedLockCmpXchg @@ -338,20 +362,32 @@ CmpXchgNoUpdate ;; On exit: ;; x0: original value of objectref ;; x10: trashed -;; x12, x17: trashed +;; x12, x16, x17: trashed ;; LEAF_ENTRY RhpCheckedXchg +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + PREPARE_EXTERNAL_VAR_INDIRECT_W g_cpuFeatures, 16 + tbz x16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, ExchangeRetry +#endif + + ALTERNATE_ENTRY RhpCheckedXchgAVLocation + swpal x1, x10, [x0] ;; exchange + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + b DoCardsXchg ExchangeRetry ;; Read the existing memory location. - ALTERNATE_ENTRY RhpCheckedXchgAVLocation + ALTERNATE_ENTRY RhpCheckedXchgAVLocation2 ldaxr x10, [x0] ;; Attempt to update with the new value. stlxr w12, x1, [x0] cbnz w12, ExchangeRetry +#endif - ;; We've successfully updated the value of the objectref so now we need a GC write barrier. +DoCardsXchg + ;; We have successfully updated the value of the objectref so now we need a GC write barrier. ;; The following barrier code takes the destination in x0 and the value in x1 so the arguments are ;; already correctly set up. @@ -359,7 +395,12 @@ ExchangeRetry ;; x10 still contains the original value. mov x0, x10 + +#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT + tbnz x16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, NoBarrierXchg InterlockedOperationBarrier +NoBarrierXchg +#endif ret LEAF_END RhpCheckedXchg diff --git a/src/coreclr/nativeaot/Runtime/forward_declarations.h b/src/coreclr/nativeaot/Runtime/forward_declarations.h index 55e8b376eb454f..5e4ffd3b2e9bdc 100644 --- a/src/coreclr/nativeaot/Runtime/forward_declarations.h +++ b/src/coreclr/nativeaot/Runtime/forward_declarations.h @@ -47,6 +47,5 @@ namespace rh { #endif // FEATURE_RWX_MEMORY // inc -FWD_DECL(EEInterfaceInfo) FWD_DECL(MethodTable) diff --git a/src/coreclr/nativeaot/Runtime/i386/GetThread.asm b/src/coreclr/nativeaot/Runtime/i386/GetThread.asm deleted file mode 100644 index b330406b9a098a..00000000000000 --- a/src/coreclr/nativeaot/Runtime/i386/GetThread.asm +++ /dev/null @@ -1,31 +0,0 @@ -;; Licensed to the .NET Foundation under one or more agreements. -;; The .NET Foundation licenses this file to you under the MIT license. - - .586 - .model flat - option casemap:none - .code - - -include AsmMacros.inc - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; RhpGetThread -;; -;; -;; INPUT: none -;; -;; OUTPUT: EAX: Thread pointer -;; -;; MUST PRESERVE ARGUMENT REGISTERS -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -FASTCALL_FUNC RhpGetThread, 0 - push ecx - INLINE_GETTHREAD eax, ecx ; eax dest, ecx trash - pop ecx - ret -FASTCALL_ENDFUNC - - end diff --git a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h index e194bbdc700181..311fdefdcaa66c 100644 --- a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h +++ b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h @@ -17,27 +17,6 @@ struct EETypeRef; #define SUPPORTS_WRITABLE_DATA 1 #endif -//------------------------------------------------------------------------------------------------- -// Array of these represents the interfaces implemented by a type - -class EEInterfaceInfo -{ - public: - MethodTable * GetInterfaceEEType() - { - return ((UIntTarget)m_pInterfaceEEType & ((UIntTarget)1)) ? - *(MethodTable**)((UIntTarget)m_ppInterfaceEETypeViaIAT & ~((UIntTarget)1)) : - m_pInterfaceEEType; - } - - private: - union - { - MethodTable * m_pInterfaceEEType; // m_uFlags == InterfaceFlagNormal - MethodTable ** m_ppInterfaceEETypeViaIAT; // m_uFlags == InterfaceViaIATFlag - }; -}; - //------------------------------------------------------------------------------------------------- // The subset of TypeFlags that Redhawk knows about at runtime // This should match the TypeFlags enum in the managed type system. @@ -75,6 +54,7 @@ enum EETypeElementType : uint8_t ElementType_SzArray = 0x18, ElementType_ByRef = 0x19, ElementType_Pointer = 0x1A, + ElementType_FunctionPointer = 0x1B, }; //------------------------------------------------------------------------------------------------- @@ -118,15 +98,9 @@ class MethodTable { // Kinds.CanonicalEEType MethodTable* m_pBaseType; - MethodTable** m_ppBaseTypeViaIAT; - - // Kinds.ClonedEEType - MethodTable** m_pCanonicalType; - MethodTable** m_ppCanonicalTypeViaIAT; // Kinds.ParameterizedEEType MethodTable* m_pRelatedParameterType; - MethodTable** m_ppRelatedParameterTypeViaIAT; }; }; @@ -147,7 +121,7 @@ class MethodTable TgtPTR_Void m_VTable[]; // make this explicit so the binder gets the right alignment // after the m_usNumVtableSlots vtable slots, we have m_usNumInterfaces slots of - // EEInterfaceInfo, and after that a couple of additional pointers based on whether the type is + // MethodTable*, and after that a couple of additional pointers based on whether the type is // finalizable (the address of the finalizer code) or has optional fields (pointer to the compacted // fields). @@ -158,11 +132,7 @@ class MethodTable // simplified version of MethodTable. See LimitedEEType definition below. EETypeKindMask = 0x00030000, - // This flag is set when m_pRelatedType is in a different module. In that case, m_pRelatedType - // actually points to a 'fake' MethodTable whose m_pRelatedType field lines up with an IAT slot in this - // module, which then points to the desired MethodTable. In other words, there is an extra indirection - // through m_pRelatedType to get to the related type in the other module. - RelatedTypeViaIATFlag = 0x00040000, + // Unused = 0x00040000, IsDynamicTypeFlag = 0x00080000, @@ -216,9 +186,6 @@ class MethodTable Kinds get_Kind(); - bool IsRelatedTypeViaIAT() - { return (m_uFlags & RelatedTypeViaIATFlag) != 0; } - bool IsArray() { EETypeElementType elementType = GetElementType(); diff --git a/src/coreclr/nativeaot/Runtime/inc/MethodTable.inl b/src/coreclr/nativeaot/Runtime/inc/MethodTable.inl index f8f7215989ed03..56f922fa6b4019 100644 --- a/src/coreclr/nativeaot/Runtime/inc/MethodTable.inl +++ b/src/coreclr/nativeaot/Runtime/inc/MethodTable.inl @@ -60,10 +60,7 @@ inline bool MethodTable::DacVerifyWorker(MethodTable* pThis) // Now on to the next type in the hierarchy. // - if (pCurrentType->IsRelatedTypeViaIAT()) - pCurrentType = *dac_cast(reinterpret_cast(pCurrentType->m_RelatedType.m_ppBaseTypeViaIAT)); - else - pCurrentType = dac_cast(reinterpret_cast(pCurrentType->m_RelatedType.m_pBaseType)); + pCurrentType = dac_cast(reinterpret_cast(pCurrentType->m_RelatedType.m_pBaseType)); if (pCurrentType == NULL) break; @@ -115,7 +112,7 @@ __forceinline uint32_t MethodTable::GetFieldOffset(EETypeField eField) ASSERT(GetNumInterfaces() > 0); return cbOffset; } - cbOffset += sizeof(EEInterfaceInfo) * GetNumInterfaces(); + cbOffset += sizeof(MethodTable*) * GetNumInterfaces(); const uint32_t relativeOrFullPointerOffset = #if USE_PORTABLE_HELPERS diff --git a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h index 7d0c985486c9d1..750faccc828383 100644 --- a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h +++ b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h @@ -12,7 +12,7 @@ struct ReadyToRunHeaderConstants static const uint32_t Signature = 0x00525452; // 'RTR' static const uint32_t CurrentMajorVersion = 9; - static const uint32_t CurrentMinorVersion = 0; + static const uint32_t CurrentMinorVersion = 1; }; struct ReadyToRunHeader @@ -43,7 +43,7 @@ enum class ReadyToRunSectionType StringTable = 200, GCStaticRegion = 201, ThreadStaticRegion = 202, - InterfaceDispatchTable = 203, + // unused = 203, TypeManagerIndirection = 204, EagerCctor = 205, FrozenObjectRegion = 206, diff --git a/src/coreclr/nativeaot/Runtime/startup.cpp b/src/coreclr/nativeaot/Runtime/startup.cpp index 1ce5f40d3b6d89..177e6c792cd0b6 100644 --- a/src/coreclr/nativeaot/Runtime/startup.cpp +++ b/src/coreclr/nativeaot/Runtime/startup.cpp @@ -299,6 +299,15 @@ bool DetectCPUFeatures() g_cpuFeatures |= XArchIntrinsicConstants_Avx512dq_vl; } } + + if ((cpuidInfo[CPUID_ECX] & (1 << 1)) != 0) // AVX512VBMI + { + g_cpuFeatures |= XArchIntrinsicConstants_Avx512Vbmi; + if (isAVX512_VLSupported) + { + g_cpuFeatures |= XArchIntrinsicConstants_Avx512Vbmi_vl; + } + } } } } @@ -373,7 +382,7 @@ bool InitGSCookie() volatile GSCookie * pGSCookiePtr = GetProcessGSCookiePtr(); #ifdef FEATURE_READONLY_GS_COOKIE - // The GS cookie is stored in a read only data segment + // The GS cookie is stored in a read only data segment if (!PalVirtualProtect((void*)pGSCookiePtr, sizeof(GSCookie), PAGE_READWRITE)) { return false; @@ -460,7 +469,7 @@ static void UninitDLL() #ifdef _WIN32 // This is set to the thread that initiates and performs the shutdown and may run // after other threads are rudely terminated. So far this is a Windows-specific concern. -// +// // On POSIX OSes a process typically lives as long as any of its threads are alive or until // the process is terminated via `exit()` or a signal. Thus there is no such distinction // between threads. diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp index cd470e479e3882..6f599b97c9eb25 100644 --- a/src/coreclr/nativeaot/Runtime/thread.cpp +++ b/src/coreclr/nativeaot/Runtime/thread.cpp @@ -1125,34 +1125,33 @@ EXTERN_C NATIVEAOT_API uint32_t __cdecl RhCompatibleReentrantWaitAny(UInt32_BOOL FORCEINLINE bool Thread::InlineTryFastReversePInvoke(ReversePInvokeFrame * pFrame) { - // Do we need to attach the thread? - if (!IsStateSet(TSF_Attached)) - return false; // thread is not attached + // remember the current transition frame, so it will be restored when we return from reverse pinvoke + pFrame->m_savedPInvokeTransitionFrame = m_pTransitionFrame; // If the thread is already in cooperative mode, this is a bad transition that will be a fail fast unless we are in // a do not trigger mode. The exception to the rule allows us to have [UnmanagedCallersOnly] methods that are called via // the "restricted GC callouts" as well as from native, which is necessary because the methods are CCW vtable // methods on interfaces passed to native. - if (IsCurrentThreadInCooperativeMode()) + // We will allow threads in DoNotTriggerGc mode to do reverse PInvoke regardless of their coop state. + if (IsDoNotTriggerGcSet()) { - if (IsDoNotTriggerGcSet()) - { - // RhpTrapThreads will always be set in this case, so we must skip that check. We must be sure to - // zero-out our 'previous transition frame' state first, however. - pFrame->m_savedPInvokeTransitionFrame = NULL; - return true; - } + // We expect this scenario only when EE is stopped. + ASSERT(ThreadStore::IsTrapThreadsRequested()); + // no need to do anything + return true; + } + // Do we need to attach the thread? + if (!IsStateSet(TSF_Attached)) + return false; // thread is not attached + + if (IsCurrentThreadInCooperativeMode()) return false; // bad transition - } // this is an ordinary transition to managed code // GC threads should not do that ASSERT(!IsGCSpecial()); - // save the previous transition frame - pFrame->m_savedPInvokeTransitionFrame = m_pTransitionFrame; - // must be in cooperative mode when checking the trap flag VolatileStoreWithoutBarrier(&m_pTransitionFrame, NULL); @@ -1233,6 +1232,7 @@ FORCEINLINE void Thread::InlineReversePInvokeReturn(ReversePInvokeFrame * pFrame FORCEINLINE void Thread::InlinePInvoke(PInvokeTransitionFrame * pFrame) { + ASSERT(!IsDoNotTriggerGcSet() || ThreadStore::IsTrapThreadsRequested()); pFrame->m_pThread = this; // set our mode to preemptive VolatileStoreWithoutBarrier(&m_pTransitionFrame, pFrame); diff --git a/src/coreclr/nativeaot/Runtime/threadstore.cpp b/src/coreclr/nativeaot/Runtime/threadstore.cpp index 9beb0448377abd..12cdea592ce498 100644 --- a/src/coreclr/nativeaot/Runtime/threadstore.cpp +++ b/src/coreclr/nativeaot/Runtime/threadstore.cpp @@ -505,60 +505,4 @@ void ThreadStore::SaveCurrentThreadOffsetForDAC() { } -#endif // _WIN32 - - -#ifndef DACCESS_COMPILE - -// internal static extern unsafe bool RhGetExceptionsForCurrentThread(Exception[] outputArray, out int writtenCountOut); -COOP_PINVOKE_HELPER(FC_BOOL_RET, RhGetExceptionsForCurrentThread, (Array* pOutputArray, int32_t* pWrittenCountOut)) -{ - FC_RETURN_BOOL(GetThreadStore()->GetExceptionsForCurrentThread(pOutputArray, pWrittenCountOut)); -} - -bool ThreadStore::GetExceptionsForCurrentThread(Array* pOutputArray, int32_t* pWrittenCountOut) -{ - int32_t countWritten = 0; - Object** pArrayElements; - Thread * pThread = GetCurrentThread(); - - for (PTR_ExInfo pInfo = pThread->m_pExInfoStackHead; pInfo != NULL; pInfo = pInfo->m_pPrevExInfo) - { - if (pInfo->m_exception == NULL) - continue; - - countWritten++; - } - - // No input array provided, or it was of the wrong kind. We'll fill out the count and return false. - if ((pOutputArray == NULL) || (pOutputArray->get_EEType()->RawGetComponentSize() != POINTER_SIZE)) - goto Error; - - // Input array was not big enough. We don't even partially fill it. - if (pOutputArray->GetArrayLength() < (uint32_t)countWritten) - goto Error; - - *pWrittenCountOut = countWritten; - - // Success, but nothing to report. - if (countWritten == 0) - return true; - - pArrayElements = (Object**)pOutputArray->GetArrayData(); - for (PTR_ExInfo pInfo = pThread->m_pExInfoStackHead; pInfo != NULL; pInfo = pInfo->m_pPrevExInfo) - { - if (pInfo->m_exception == NULL) - continue; - - *pArrayElements = pInfo->m_exception; - pArrayElements++; - } - - RhpBulkWriteBarrier(pArrayElements, countWritten * POINTER_SIZE); - return true; - -Error: - *pWrittenCountOut = countWritten; - return false; -} -#endif // DACCESS_COMPILE +#endif // _WIN32 \ No newline at end of file diff --git a/src/coreclr/nativeaot/Runtime/threadstore.h b/src/coreclr/nativeaot/Runtime/threadstore.h index 2e2aba2d86bc88..c9208cecf3b8d7 100644 --- a/src/coreclr/nativeaot/Runtime/threadstore.h +++ b/src/coreclr/nativeaot/Runtime/threadstore.h @@ -59,7 +59,6 @@ class ThreadStore #else static PTR_Thread GetThreadFromTEB(TADDR pvTEB); #endif - bool GetExceptionsForCurrentThread(Array* pOutputArray, int32_t* pWrittenCountOut); void Destroy(); void SuspendAllThreads(bool waitForGCEvent); diff --git a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp index 45cdbc15d52f95..9172d7709fa96c 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp @@ -818,10 +818,10 @@ bool DoTheStep(uintptr_t pc, UnwindInfoSections uwInfoSections, REGDISPLAY *regs #if defined(TARGET_ARM) DwarfInstructions dwarfInst; - int stepRet = dwarfInst.stepWithDwarf(_addressSpace, pc, procInfo.unwind_info, *(Registers_arm_rt*)regs, isSignalFrame); + int stepRet = dwarfInst.stepWithDwarf(_addressSpace, pc, procInfo.unwind_info, *(Registers_arm_rt*)regs, isSignalFrame, /* stage2 */ false); #else DwarfInstructions dwarfInst; - int stepRet = dwarfInst.stepWithDwarf(_addressSpace, pc, procInfo.unwind_info, *(Registers_REGDISPLAY*)regs, isSignalFrame); + int stepRet = dwarfInst.stepWithDwarf(_addressSpace, pc, procInfo.unwind_info, *(Registers_REGDISPLAY*)regs, isSignalFrame, /* stage2 */ false); #endif if (stepRet != UNW_STEP_SUCCESS) 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 62a222fb4d8168..74c75705619d7c 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 @@ -401,6 +401,12 @@ public static RuntimeTypeHandle GetRelatedParameterTypeHandle(RuntimeTypeHandle return new RuntimeTypeHandle(elementType); } + public static unsafe int GetArrayRankOrMinusOneForSzArray(RuntimeTypeHandle arrayHandle) + { + Debug.Assert(IsArrayType(arrayHandle)); + return arrayHandle.ToMethodTable()->IsSzArray ? -1 : arrayHandle.ToMethodTable()->ArrayRank; + } + public static bool IsValueType(RuntimeTypeHandle type) { return type.ToEETypePtr().IsValueType; @@ -642,6 +648,43 @@ public static bool IsFunctionPointerType(RuntimeTypeHandle typeHandle) return typeHandle.ToEETypePtr().IsFunctionPointer; } + public static unsafe RuntimeTypeHandle GetFunctionPointerReturnType(RuntimeTypeHandle typeHandle) + { + return new RuntimeTypeHandle(new EETypePtr(typeHandle.ToMethodTable()->FunctionPointerReturnType)); + } + + public static unsafe int GetFunctionPointerParameterCount(RuntimeTypeHandle typeHandle) + { + return (int)typeHandle.ToMethodTable()->NumFunctionPointerParameters; + } + + public static unsafe RuntimeTypeHandle GetFunctionPointerParameterType(RuntimeTypeHandle typeHandle, int argumentIndex) + { + Debug.Assert(argumentIndex < GetFunctionPointerParameterCount(typeHandle)); + return new RuntimeTypeHandle(new EETypePtr(typeHandle.ToMethodTable()->FunctionPointerParameters[argumentIndex])); + } + + public static unsafe RuntimeTypeHandle[] GetFunctionPointerParameterTypes(RuntimeTypeHandle typeHandle) + { + int paramCount = GetFunctionPointerParameterCount(typeHandle); + if (paramCount == 0) + return Array.Empty(); + + RuntimeTypeHandle[] result = new RuntimeTypeHandle[paramCount]; + MethodTableList parameters = typeHandle.ToMethodTable()->FunctionPointerParameters; + for (int i = 0; i < result.Length; i++) + { + result[i] = new RuntimeTypeHandle(new EETypePtr(parameters[i])); + } + + return result; + } + + public static unsafe bool IsUnmanagedFunctionPointerType(RuntimeTypeHandle typeHandle) + { + return typeHandle.ToMethodTable()->IsUnmanagedFunctionPointer; + } + public static bool IsByRefType(RuntimeTypeHandle typeHandle) { return typeHandle.ToEETypePtr().IsByRef; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs index 92894018a0b3b7..482a9a7b357a7e 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs @@ -13,7 +13,7 @@ internal static class SharedCodeHelpers public static unsafe MethodTable* GetOrdinalInterface(MethodTable* pType, ushort interfaceIndex) { Debug.Assert(interfaceIndex <= pType->NumInterfaces); - return pType->InterfaceMap[interfaceIndex].InterfaceType; + return pType->InterfaceMap[interfaceIndex]; } public static unsafe MethodTable* GetCurrentSharedThunkContext() 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 dd0e469c284301..e400551f9a50ba 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 @@ -145,7 +145,6 @@ - diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs index e9f52b9b278681..f2d1aac03130bf 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs @@ -192,7 +192,7 @@ private static unsafe void CopyImpl(Array sourceArray, int sourceIndex, Array de } else { - if (RuntimeImports.AreTypesEquivalent(sourceElementEEType, destinationElementEEType)) + if (sourceElementEEType == destinationElementEEType) { if (sourceElementEEType.ContainsGCPointers) { @@ -387,7 +387,7 @@ private static unsafe void CopyImplReferenceArrayToValueTypeArray(Array sourceAr // private static unsafe void CopyImplValueTypeArrayWithInnerGcRefs(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable) { - Debug.Assert(RuntimeImports.AreTypesEquivalent(sourceArray.GetEETypePtr(), destinationArray.GetEETypePtr())); + Debug.Assert(sourceArray.GetEETypePtr() == destinationArray.GetEETypePtr()); Debug.Assert(sourceArray.ElementEEType.IsValueType); EETypePtr sourceElementEEType = sourceArray.GetEETypePtr().ArrayElementType; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/EETypePtr.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/EETypePtr.cs index bd5dd0995ce0ac..19b1b12bc8357b 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/EETypePtr.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/EETypePtr.cs @@ -18,8 +18,8 @@ using Internal.Runtime.CompilerServices; using MethodTable = Internal.Runtime.MethodTable; +using MethodTableList = Internal.Runtime.MethodTableList; using EETypeElementType = Internal.Runtime.EETypeElementType; -using EETypeRef = Internal.Runtime.EETypeRef; using CorElementType = System.Reflection.CorElementType; namespace System @@ -60,12 +60,7 @@ public bool Equals(EETypePtr p) public static bool operator ==(EETypePtr value1, EETypePtr value2) { - if (value1.IsNull) - return value2.IsNull; - else if (value2.IsNull) - return false; - else - return RuntimeImports.AreTypesEquivalent(value1, value2); + return value1._value == value2._value; } public static bool operator !=(EETypePtr value1, EETypePtr value2) @@ -444,17 +439,17 @@ public EETypePtr this[int index] { Debug.Assert((uint)index < _value->NumInterfaces); - return new EETypePtr(_value->InterfaceMap[index].InterfaceType); + return new EETypePtr(_value->InterfaceMap[index]); } } } public struct GenericArgumentCollection { - private EETypeRef* _arguments; + private MethodTableList _arguments; private uint _argumentCount; - internal GenericArgumentCollection(uint argumentCount, EETypeRef* arguments) + internal GenericArgumentCollection(uint argumentCount, MethodTableList arguments) { _argumentCount = argumentCount; _arguments = arguments; @@ -473,7 +468,7 @@ public EETypePtr this[int index] get { Debug.Assert((uint)index < _argumentCount); - return new EETypePtr(_arguments[index].Value); + return new EETypePtr(_arguments[index]); } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs index 5a80b4318eddb1..818dccc95dceb3 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs @@ -24,5 +24,10 @@ public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, Pro { ReflectionEmitThrower.ThrowPlatformNotSupportedException(); } + +#pragma warning disable CA1822 // Member 'Ctor' does not access instance data and can be marked as static + internal ConstructorInfo Ctor => default; + internal byte[] Data => default; +#pragma warning restore CA1822 } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs deleted file mode 100644 index 2c02ff1f1ea7b6..00000000000000 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs +++ /dev/null @@ -1,73 +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 System.Reflection.Emit -{ - public partial class ParameterBuilder - { - internal ParameterBuilder() - { - // Prevent generating a default constructor - } - - public virtual int Attributes - { - get - { - return default; - } - } - - public bool IsIn - { - get - { - return default; - } - } - - public bool IsOptional - { - get - { - return default; - } - } - - public bool IsOut - { - get - { - return default; - } - } - - public virtual string Name - { - get - { - return default; - } - } - - public virtual int Position - { - get - { - return default; - } - } - - public virtual void SetConstant(object defaultValue) - { - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - } - } -} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs index 7cf1313aed901e..32f171f1b5d839 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs @@ -1,20 +1,123 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; +using System.Reflection.Runtime.General; + +using Internal.Metadata.NativeFormat; + +using Debug = System.Diagnostics.Debug; + namespace System.Reflection { internal partial class ModifiedType { - internal struct TypeSignature + internal readonly struct TypeSignature + { + internal readonly MetadataReader Reader; + internal readonly Handle Handle; + public TypeSignature(MetadataReader reader, Handle handle) + => (Reader, Handle) = (reader, handle); + } + + internal Type GetTypeParameter(Type unmodifiedType, int index) + { + MetadataReader reader = _typeSignature.Reader; + Handle handle = _typeSignature.Handle; + + while (handle.HandleType == HandleType.ModifiedType) + handle = reader.GetModifiedType(handle.ToModifiedTypeHandle(reader)).Type; + + if (handle.HandleType == HandleType.TypeSpecification) + handle = reader.GetTypeSpecification(handle.ToTypeSpecificationHandle(reader)).Signature; + + switch (handle.HandleType) + { + case HandleType.SZArraySignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetSZArraySignature(handle.ToSZArraySignatureHandle(reader)).ElementType)); + case HandleType.ArraySignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetArraySignature(handle.ToArraySignatureHandle(reader)).ElementType)); + case HandleType.PointerSignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetPointerSignature(handle.ToPointerSignatureHandle(reader)).Type)); + case HandleType.ByReferenceSignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetByReferenceSignature(handle.ToByReferenceSignatureHandle(reader)).Type)); + case HandleType.FunctionPointerSignature: + { + MethodSignature functionSig = reader.GetMethodSignature( + reader.GetFunctionPointerSignature(handle.ToFunctionPointerSignatureHandle(reader)).Signature); + if (index-- == 0) + return Create(unmodifiedType, new TypeSignature(reader, functionSig.ReturnType)); + + Debug.Assert(index <= functionSig.Parameters.Count); + foreach (Handle paramHandle in functionSig.Parameters) + if (index-- == 0) + return Create(unmodifiedType, new TypeSignature(reader, paramHandle)); + } + break; + case HandleType.TypeInstantiationSignature: + { + TypeInstantiationSignature typeInst = + reader.GetTypeInstantiationSignature(handle.ToTypeInstantiationSignatureHandle(reader)); + Debug.Assert(index < typeInst.GenericTypeArguments.Count); + foreach (Handle paramHandle in typeInst.GenericTypeArguments) + if (index-- == 0) + return Create(unmodifiedType, new TypeSignature(reader, paramHandle)); + } + break; + } + + Debug.Fail(handle.HandleType.ToString()); + return null; + } + + internal SignatureCallingConvention GetCallingConventionFromFunctionPointer() { + MetadataReader reader = _typeSignature.Reader; + Handle fnPtrTypeSigHandle = reader.GetTypeSpecification( + _typeSignature.Handle.ToTypeSpecificationHandle(reader)).Signature; + MethodSignatureHandle methodSigHandle = reader.GetFunctionPointerSignature( + fnPtrTypeSigHandle.ToFunctionPointerSignatureHandle(reader)).Signature; + + Debug.Assert((int)Internal.Metadata.NativeFormat.SignatureCallingConvention.StdCall == (int)SignatureCallingConvention.StdCall); + Debug.Assert((int)Internal.Metadata.NativeFormat.SignatureCallingConvention.Unmanaged == (int)SignatureCallingConvention.Unmanaged); + return (SignatureCallingConvention)(reader.GetMethodSignature(methodSigHandle).CallingConvention + & Internal.Metadata.NativeFormat.SignatureCallingConvention.UnmanagedCallingConventionMask); } -#pragma warning disable IDE0060 - internal Type GetTypeParameter(Type unmodifiedType, int index) => throw new NotSupportedException(); + private Type[] GetCustomModifiers(bool required) + { + ArrayBuilder builder = default; + + MetadataReader reader = _typeSignature.Reader; + Handle handle = _typeSignature.Handle; + + while (handle.HandleType == HandleType.ModifiedType) + { + var modifiedType = reader.GetModifiedType(handle.ToModifiedTypeHandle(reader)); - internal SignatureCallingConvention GetCallingConventionFromFunctionPointer() => throw new NotSupportedException(); + handle = modifiedType.Type; + + if (modifiedType.IsOptional == required) + continue; + + builder.Add(modifiedType.ModifierType.Resolve(reader, new TypeContext(null, null))); + } + + Type[] result = builder.ToArray(); + + // We call Reverse for compat with CoreCLR that also reverses these. + // ILDasm also reverses these but don't be fooled: you can go to + // View -> MetaInfo -> Show to see the file format order in ILDasm. + Array.Reverse(result); + + return result; + } - private Type[] GetCustomModifiers(bool required) => throw new NotSupportedException(); -#pragma warning restore IDE0060 + public static Type Create(Type unmodifiedType, MetadataReader reader, Handle typeSignature) + => ModifiedType.Create(unmodifiedType, new TypeSignature(reader, typeSignature)); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs index be8721f006b25b..e4272119e698cd 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs @@ -162,6 +162,8 @@ protected sealed override RuntimeTypeInfo FieldRuntimeType protected sealed override int ExplicitLayoutFieldOffsetData => (int)(_field.Offset); + public sealed override Type GetModifiedFieldType() => ModifiedType.Create(FieldRuntimeType, _reader, FieldTypeHandle); + private Handle FieldTypeHandle => _field.Signature.GetFieldSignature(_reader).Type; private readonly NativeFormatRuntimeNamedTypeInfo _definingTypeInfo; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs index 116249d661f409..c7892602a14877 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs @@ -61,5 +61,10 @@ internal Type[] GetCustomModifiers(TypeContext typeContext, bool optional) return _handle.GetCustomModifiers((global::Internal.Metadata.NativeFormat.MetadataReader)Reader, typeContext, optional); #endif } + + internal Type GetModifiedType(TypeContext typeContext) + { + return ModifiedType.Create(Resolve(typeContext), (global::Internal.Metadata.NativeFormat.MetadataReader)Reader, _handle); + } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs index b146eadb260b99..6f8ba75970dcc9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs @@ -36,6 +36,8 @@ public sealed override Type ParameterType } } + public sealed override Type GetModifiedParameterType() => QualifiedParameterTypeHandle.GetModifiedType(_typeContext); + protected readonly QSignatureTypeHandle QualifiedParameterTypeHandle; private readonly TypeContext _typeContext; private volatile Type _lazyParameterType; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs index 7966647740c76d..813a40073a2c98 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs @@ -75,6 +75,12 @@ public sealed override IEnumerable CustomAttributes } } + public override Type GetModifiedPropertyType() + { + return ModifiedType.Create(PropertyType, _reader, _reader.GetPropertySignature(_property.Signature).Type); + + } + public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other) { ArgumentNullException.ThrowIfNull(other); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs index 1048c76d583a06..bcbc4008351d0a 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs @@ -304,7 +304,7 @@ public static unsafe object GetUninitializedObject( throw new SerializationException(SR.Format(SR.Serialization_InvalidType, type)); } - if (type.HasElementType || type.IsGenericParameter) + if (type.HasElementType || type.IsGenericParameter || type.IsFunctionPointer) { throw new ArgumentException(SR.Argument_InvalidValue); } @@ -319,6 +319,11 @@ public static unsafe object GetUninitializedObject( throw new NotSupportedException(SR.NotSupported_ManagedActivation); } + if (type.IsAbstract) + { + throw new MemberAccessException(SR.Acc_CreateAbst); + } + MethodTable* mt = type.TypeHandle.ToMethodTable(); if (mt->ElementType == Internal.Runtime.EETypeElementType.Void) @@ -337,11 +342,6 @@ public static unsafe object GetUninitializedObject( throw new MemberAccessException(); } - if (mt->IsAbstract) - { - throw new MemberAccessException(SR.Acc_CreateAbst); - } - if (mt->IsByRefLike) { throw new NotSupportedException(SR.NotSupported_ByRefLike); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs index 235b87db181017..c348418d510c4d 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs @@ -81,7 +81,7 @@ public unsafe partial struct ComInterfaceDispatch public static unsafe T GetInstance(ComInterfaceDispatch* dispatchPtr) where T : class { ManagedObjectWrapper* comInstance = ToManagedObjectWrapper(dispatchPtr); - return Unsafe.As(RuntimeImports.RhHandleGet(comInstance->Target)); + return Unsafe.As(comInstance->Holder.WrappedObject); } internal static unsafe ManagedObjectWrapper* ToManagedObjectWrapper(ComInterfaceDispatch* dispatchPtr) @@ -127,7 +127,7 @@ internal enum CreateComInterfaceFlagsEx internal unsafe struct ManagedObjectWrapper { - public IntPtr Target; // This is GC Handle + public volatile IntPtr HolderHandle; // This is GC Handle public ulong RefCount; public int UserDefinedCount; @@ -136,6 +136,34 @@ internal unsafe struct ManagedObjectWrapper internal CreateComInterfaceFlagsEx Flags; + public bool IsRooted + { + get + { + ulong refCount = Interlocked.Read(ref RefCount); + bool rooted = GetComCount(refCount) > 0; + if (!rooted) + { + // TODO: global pegging state + // https://github.com/dotnet/runtime/issues/85137 + rooted = GetTrackerCount(refCount) > 0 && (Flags & CreateComInterfaceFlagsEx.IsPegged) != 0; + } + return rooted; + } + } + + public ManagedObjectWrapperHolder? Holder + { + get + { + IntPtr handle = HolderHandle; + if (handle == IntPtr.Zero) + return null; + else + return Unsafe.As(GCHandle.FromIntPtr(handle).Target); + } + } + public uint AddRef() { return GetComCount(Interlocked.Increment(ref RefCount)); @@ -174,10 +202,10 @@ public uint ReleaseFromReferenceTracker() // If we observe the destroy sentinel, then this release // must destroy the wrapper. - if (RefCount == DestroySentinel) + if (curr == DestroySentinel) Destroy(); - return GetTrackerCount(RefCount); + return GetTrackerCount(curr); } public uint Peg() @@ -192,20 +220,26 @@ public uint Unpeg() return HResults.S_OK; } - public unsafe int QueryInterface(in Guid riid, out IntPtr ppvObject) + + public unsafe int QueryInterfaceForTracker(in Guid riid, out IntPtr ppvObject) { - if (GetComCount(RefCount) == 0) + if (IsMarkedToDestroy(RefCount) || Holder is null) { ppvObject = IntPtr.Zero; return COR_E_ACCESSING_CCW; } + return QueryInterface(in riid, out ppvObject); + } + + public unsafe int QueryInterface(in Guid riid, out IntPtr ppvObject) + { ppvObject = AsRuntimeDefined(in riid); if (ppvObject == IntPtr.Zero) { if ((Flags & CreateComInterfaceFlagsEx.LacksICustomQueryInterface) == 0) { - var customQueryInterface = GCHandle.FromIntPtr(Target).Target as ICustomQueryInterface; + var customQueryInterface = Holder.WrappedObject as ICustomQueryInterface; if (customQueryInterface is null) { SetFlag(CreateComInterfaceFlagsEx.LacksICustomQueryInterface); @@ -244,15 +278,38 @@ public IntPtr As(in Guid riid) return typeMaybe; } - public unsafe void Destroy() + /// true if actually destroyed + public unsafe bool Destroy() { - if (Target == IntPtr.Zero) + Debug.Assert(GetComCount(RefCount) == 0 || HolderHandle == IntPtr.Zero); + + if (HolderHandle == IntPtr.Zero) { - return; + // We either were previously destroyed or multiple ManagedObjectWrapperHolder + // were created by the ConditionalWeakTable for the same object and we lost the race. + return true; } - RuntimeImports.RhHandleFree(Target); - Target = IntPtr.Zero; + ulong prev, refCount; + do + { + prev = RefCount; + refCount = prev | DestroySentinel; + } while (Interlocked.CompareExchange(ref RefCount, refCount, prev) != prev); + + if (refCount == DestroySentinel) + { + IntPtr handle = Interlocked.Exchange(ref HolderHandle, IntPtr.Zero); + if (handle != IntPtr.Zero) + { + RuntimeImports.RhHandleFree(handle); + } + return true; + } + else + { + return false; + } } private unsafe IntPtr AsRuntimeDefined(in Guid riid) @@ -333,22 +390,67 @@ private static bool IsMarkedToDestroy(ulong c) internal unsafe class ManagedObjectWrapperHolder { + static ManagedObjectWrapperHolder() + { + delegate* unmanaged callback = &IsRootedCallback; + if (!RuntimeImports.RhRegisterRefCountedHandleCallback((nint)callback, typeof(ManagedObjectWrapperHolder).GetEEType())) + { + throw new OutOfMemoryException(); + } + } + + [UnmanagedCallersOnly] + static bool IsRootedCallback(IntPtr pObj) + { + // We are paused in the GC, so this is safe. +#pragma warning disable CS8500 // Takes a pointer to a managed type + ManagedObjectWrapperHolder* holder = (ManagedObjectWrapperHolder*)&pObj; + return holder->_wrapper->IsRooted; +#pragma warning restore CS8500 + } + private ManagedObjectWrapper* _wrapper; + private object _wrappedObject; - public ManagedObjectWrapperHolder(ManagedObjectWrapper* wrapper) + public ManagedObjectWrapperHolder(ManagedObjectWrapper* wrapper, object wrappedObject) { _wrapper = wrapper; + _wrappedObject = wrappedObject; + } + + public void InitializeHandle() + { + IntPtr handle = RuntimeImports.RhHandleAllocRefCounted(this); + IntPtr prev = Interlocked.CompareExchange(ref _wrapper->HolderHandle, handle, IntPtr.Zero); + if (prev != IntPtr.Zero) + { + RuntimeImports.RhHandleFree(handle); + } } public unsafe IntPtr ComIp => _wrapper->As(in ComWrappers.IID_IUnknown); + public object WrappedObject => _wrappedObject; + public uint AddRef() => _wrapper->AddRef(); ~ManagedObjectWrapperHolder() { // Release GC handle created when MOW was built. - _wrapper->Destroy(); - NativeMemory.Free(_wrapper); + if (_wrapper->Destroy()) + { + NativeMemory.Free(_wrapper); + } + else + { + // There are still outstanding references on the COM side. + // This case should only be hit when an outstanding + // tracker refcount exists from AddRefFromReferenceTracker. + // When implementing IReferenceTrackerHost, this should be + // reconsidered. + // https://github.com/dotnet/runtime/issues/85137 + GC.ReRegisterForFinalize(this); + } } } @@ -370,7 +472,7 @@ public void Release() { if (_comWrappers != null) { - _comWrappers.RemoveRCWFromCache(_externalComObject); + _comWrappers.RemoveRCWFromCache(_externalComObject, _proxyHandle); _comWrappers = null; } @@ -427,8 +529,9 @@ public unsafe IntPtr GetOrCreateComInterfaceForObject(object instance, CreateCom ccwValue = _ccwTable.GetValue(instance, (c) => { ManagedObjectWrapper* value = CreateCCW(c, flags); - return new ManagedObjectWrapperHolder(value); + return new ManagedObjectWrapperHolder(value, c); }); + ccwValue.InitializeHandle(); return ccwValue.ComIp; } @@ -477,7 +580,7 @@ public unsafe IntPtr GetOrCreateComInterfaceForObject(object instance, CreateCom pDispatches[i]._thisPtr = mow; } - mow->Target = RuntimeImports.RhHandleAlloc(instance, GCHandleType.Normal); + mow->HolderHandle = IntPtr.Zero; mow->RefCount = 1; mow->UserDefinedCount = userDefinedCount; mow->UserDefined = userDefined; @@ -617,8 +720,18 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( { if (_rcwCache.TryGetValue(externalComObject, out GCHandle handle)) { - retValue = handle.Target; - return true; + object? cachedWrapper = handle.Target; + if (cachedWrapper is not null) + { + retValue = cachedWrapper; + return true; + } + else + { + // The GCHandle has been clear out but the NativeObjectWrapper + // finalizer has not yet run to remove the entry from _rcwCache + _rcwCache.Remove(externalComObject); + } } if (wrapperMaybe is not null) @@ -662,9 +775,21 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( using (LockHolder.Hold(_lock)) { + object? cachedWrapper = null; if (_rcwCache.TryGetValue(externalComObject, out var existingHandle)) { - retValue = existingHandle.Target; + cachedWrapper = existingHandle.Target; + if (cachedWrapper is null) + { + // The GCHandle has been clear out but the NativeObjectWrapper + // finalizer has not yet run to remove the entry from _rcwCache + _rcwCache.Remove(externalComObject); + } + } + + if (cachedWrapper is not null) + { + retValue = cachedWrapper; } else { @@ -685,11 +810,17 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( } #pragma warning restore IDE0060 - private void RemoveRCWFromCache(IntPtr comPointer) + private void RemoveRCWFromCache(IntPtr comPointer, GCHandle expectedValue) { using (LockHolder.Hold(_lock)) { - _rcwCache.Remove(comPointer); + // TryGetOrCreateObjectForComInstanceInternal may have put a new entry into the cache + // in the time between the GC cleared the contents of the GC handle but before the + // NativeObjectWrapper finializer ran. + if (_rcwCache.TryGetValue(comPointer, out GCHandle cachedValue) && expectedValue.Equals(cachedValue)) + { + _rcwCache.Remove(comPointer); + } } } @@ -806,11 +937,6 @@ internal static unsafe uint IUnknown_Release(IntPtr pThis) { ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis); uint refcount = wrapper->Release(); - if (wrapper->RefCount == 0) - { - wrapper->Destroy(); - } - return refcount; } @@ -818,7 +944,7 @@ internal static unsafe uint IUnknown_Release(IntPtr pThis) internal static unsafe int IReferenceTrackerTarget_QueryInterface(IntPtr pThis, Guid* guid, IntPtr* ppObject) { ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis); - return wrapper->QueryInterface(in *guid, out *ppObject); + return wrapper->QueryInterfaceForTracker(in *guid, out *ppObject); } [UnmanagedCallersOnly] 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 a0b70c8f45a4a3..f3b4cca51b052f 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 @@ -296,13 +296,6 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) // calls to runtime for type equality checks // - [MethodImpl(MethodImplOptions.InternalCall)] - [RuntimeImport(RuntimeLibrary, "RhTypeCast_AreTypesEquivalent")] - private static extern unsafe bool AreTypesEquivalent(MethodTable* pType1, MethodTable* pType2); - - internal static unsafe bool AreTypesEquivalent(EETypePtr pType1, EETypePtr pType2) - => AreTypesEquivalent(pType1.ToPointer(), pType2.ToPointer()); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhTypeCast_AreTypesAssignable")] internal static extern unsafe bool AreTypesAssignable(MethodTable* pSourceType, MethodTable* pTargetType); @@ -599,10 +592,6 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe internal static extern unsafe int RhGetModuleFileName(IntPtr moduleHandle, out char* moduleName); #endif - [MethodImplAttribute(MethodImplOptions.InternalCall)] - [RuntimeImport(RuntimeLibrary, "RhGetExceptionsForCurrentThread")] - internal static extern unsafe bool RhGetExceptionsForCurrentThread(Exception[] outputArray, out int writtenCountOut); - // returns the previous value. [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhSetErrorInfoBuffer")] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs index 465dbe83356a0e..97ced6c5e361cf 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime; using System.Runtime.CompilerServices; - +using System.Text; +using System.Text.Unicode; using Internal.DeveloperExperience; using Internal.Runtime.Augments; @@ -167,21 +169,7 @@ public static unsafe void FailFast(string message, Exception? exception) // exception that escapes from a ThreadPool workitem, or from a void-returning async method. public static void ReportUnhandledException(Exception exception) { -#if FEATURE_DUMP_DEBUGGING - // ReportUnhandledError will also call this in APPX scenarios, - // but WinRT can failfast before we get another chance - // (in APPX scenarios, this one will get overwritten by the one with the CCW pointer) - GenerateExceptionInformationForDump(exception, IntPtr.Zero); -#endif - -#if ENABLE_WINRT - // If possible report the exception to GEH, if not fail fast. - WinRTInteropCallbacks callbacks = WinRTInterop.UnsafeCallbacks; - if (callbacks == null || !callbacks.ReportUnhandledError(exception)) - FailFast(GetStringForFailFastReason(RhFailFastReason.UnhandledException), exception); -#else FailFast(GetStringForFailFastReason(RhFailFastReason.UnhandledException), exception); -#endif } // This is the classlib-provided fail-fast function that will be invoked whenever the runtime @@ -248,14 +236,37 @@ internal static void FailFast(string message, Exception? exception, RhFailFastRe outputMessage = message; } + Internal.Console.Error.Write(prefix); if (outputMessage != null) Internal.Console.Error.Write(outputMessage); Internal.Console.Error.Write(Environment.NewLine); -#if FEATURE_DUMP_DEBUGGING - GenerateExceptionInformationForDump(exception, IntPtr.Zero); -#endif + if (outputMessage != null) + { + // Try to save the exception stack trace in a buffer on the stack. If the exception is too large, we'll truncate it. + const int MaxStack = 2048; + Span exceptionStack = stackalloc byte[MaxStack]; + + // Ignore output, as this is best-effort + _ = Utf8.FromUtf16(outputMessage, exceptionStack, out _, out int length); + // Fill the rest of the buffer with nulls + if (length < MaxStack) + exceptionStack.Slice(length).Clear(); + + unsafe + { + byte* stackExceptionRecord = stackalloc byte[sizeof(CrashDumpRecord)]; + CrashDumpRecord* pExceptionRecord = (CrashDumpRecord*)stackExceptionRecord; + var cookieSpan = new Span(pExceptionRecord->Cookie, CrashDumpRecord.CookieSize); + // Random 10 bytes to identify the record + ((ReadOnlySpan)new byte[] { 0x1c, 0x73, 0xd0, 0x2d, 0xda, 0x6b, 0x4c, 0xef, 0xbf, 0xa1 }).CopyTo(cookieSpan); + "NETRUNTIME"u8.CopyTo(cookieSpan.Slice(10)); + pExceptionRecord->Type = 1; + pExceptionRecord->Data = (void*)exceptionStack.GetPinnableReference(); + pExceptionRecord->Length = length; + } + } } #if TARGET_WINDOWS @@ -282,6 +293,15 @@ internal static void FailFast(string message, Exception? exception, RhFailFastRe #endif } + private unsafe struct CrashDumpRecord + { + public const int CookieSize = 20; + public fixed byte Cookie[CookieSize]; + public int Type; + public void* Data; + public int Length; + } + // Use a nested class to avoid running the class constructor of the outer class when // accessing this flag. private static class InFailFast @@ -304,374 +324,5 @@ public static bool SafeToPerformRichExceptionSupport return true; } } - -#if FEATURE_DUMP_DEBUGGING - -#pragma warning disable 414 // field is assigned, but never used -- This is because C# doesn't realize that we - // copy the field into a buffer. - /// - /// This is the header that describes our 'error report' buffer to the minidump auxiliary provider. - /// Its format is know to that system-wide DLL, so do not change it. The remainder of the buffer is - /// opaque to the minidump auxiliary provider, so it'll have its own format that is more easily - /// changed. - /// - [StructLayout(LayoutKind.Sequential)] - private struct ERROR_REPORT_BUFFER_HEADER - { - private int _headerSignature; - private int _bufferByteCount; - - public void WriteHeader(int cbBuffer) - { - _headerSignature = 0x31304244; // 'DB01' - _bufferByteCount = cbBuffer; - } - } - - /// - /// This header describes the contents of the serialized error report to DAC, which can deserialize it - /// from a dump file or live debugging session. This format is easier to change than the - /// ERROR_REPORT_BUFFER_HEADER, but it is still well-known to DAC, so any changes must update the - /// version number and also have corresponding changes made to DAC. - /// - [StructLayout(LayoutKind.Sequential)] - private struct SERIALIZED_ERROR_REPORT_HEADER - { - private int _errorReportSignature; // This is the version of the 'container format'. - private int _exceptionSerializationVersion; // This is the version of the Exception format. It is - // separate from the 'container format' version since the - // implementation of the Exception serialization is owned by - // the Exception class. - private int _exceptionCount; // We just contain a logical array of exceptions. - private int _loadedModuleCount; // Number of loaded modules. present when signature >= ER02. - // {ExceptionCount} serialized Exceptions follow. - // {LoadedModuleCount} module handles follow. present when signature >= ER02. - - public void WriteHeader(int nExceptions, int nLoadedModules) - { - _errorReportSignature = 0x32305245; // 'ER02' - _exceptionSerializationVersion = Exception.CurrentSerializationSignature; - _exceptionCount = nExceptions; - _loadedModuleCount = nLoadedModules; - } - } - - /// - /// Holds metadata about an exception in flight. Class because ConditionalWeakTable only accepts reference types - /// - private class ExceptionData - { - public ExceptionData() - { - // Set this to a non-zero value so that logic mapping entries to threads - // doesn't think an uninitialized ExceptionData is on thread 0 - ExceptionMetadata.ThreadId = 0xFFFFFFFF; - } - - public struct ExceptionMetadataStruct - { - public uint ExceptionId { get; set; } // Id assigned to the exception. May not be contiguous or start at 0. - public uint InnerExceptionId { get; set; } // ID of the inner exception or 0xFFFFFFFF for 'no inner exception' - public uint ThreadId { get; set; } // Managed thread ID the eception was thrown on - public int NestingLevel { get; set; } // If multiple exceptions are currently active on a thread, this gives the ordering for them. - // The highest number is the most recent exception. -1 means the exception is not currently in flight - // (but it may still be an InnerException). - public IntPtr ExceptionCCWPtr { get; set; } // If the exception was thrown in an interop scenario, this contains the CCW pointer, otherwise, IntPtr.Zero - } - - public ExceptionMetadataStruct ExceptionMetadata; - - /// - /// Data created by Exception.SerializeForDump() - /// - public byte[] SerializedExceptionData { get; set; } - - /// - /// Serializes the exception metadata and SerializedExceptionData - /// - public unsafe byte[] Serialize() - { - checked - { - byte[] serializedData = new byte[sizeof(ExceptionMetadataStruct) + SerializedExceptionData.Length]; - fixed (byte* pSerializedData = &serializedData[0]) - { - ExceptionMetadataStruct* pMetadata = (ExceptionMetadataStruct*)pSerializedData; - pMetadata->ExceptionId = ExceptionMetadata.ExceptionId; - pMetadata->InnerExceptionId = ExceptionMetadata.InnerExceptionId; - pMetadata->ThreadId = ExceptionMetadata.ThreadId; - pMetadata->NestingLevel = ExceptionMetadata.NestingLevel; - pMetadata->ExceptionCCWPtr = ExceptionMetadata.ExceptionCCWPtr; - - SerializedExceptionData.AsSpan().CopyTo(new Span(pSerializedData + sizeof(ExceptionMetadataStruct), SerializedExceptionData.Length)); - } - return serializedData; - } - } - } - - /// - /// Table of exceptions that were on stacks triggering GenerateExceptionInformationForDump - /// - private static readonly ConditionalWeakTable s_exceptionDataTable = new ConditionalWeakTable(); - - /// - /// Counter for exception ID assignment - /// - private static int s_currentExceptionId; - - /// - /// This method will call the runtime to gather the Exception objects from every exception dispatch in - /// progress on the current thread. It will then serialize them into a new buffer and pass that - /// buffer back to the runtime, which will publish it to a place where a global "minidump auxiliary - /// provider" will be able to save the buffer's contents into triage dumps. - /// - /// Thread safety information: The guarantee of this method is that the buffer it produces will have - /// complete and correct information for all live exceptions on the current thread (as long as the same exception object - /// is not thrown simultaneously on multiple threads). It will do a best-effort attempt to serialize information about exceptions - /// already recorded on other threads, but that data can be lost or corrupted. The restrictions are: - /// 1. Only exceptions active or recorded on the current thread have their table data modified. - /// 2. After updating data in the table, we serialize a snapshot of the table (provided by ConditionalWeakTable.Values), - /// regardless of what other threads might do to the table before or after. However, because of #1, this thread's - /// exception data should stay stable - /// 3. There is a dependency on the fact that ConditionalWeakTable's members are all threadsafe and that .Values returns a snapshot - /// - public static void GenerateExceptionInformationForDump(Exception currentException, IntPtr exceptionCCWPtr) - { - LowLevelList serializedExceptions = new LowLevelList(); - - // If currentException is null, there's a state corrupting exception in flight and we can't serialize it - if (currentException != null) - { - SerializeExceptionsForDump(currentException, exceptionCCWPtr, serializedExceptions); - } - - GenerateErrorReportForDump(serializedExceptions); - } - - private static void SerializeExceptionsForDump(Exception currentException, IntPtr exceptionCCWPtr, LowLevelList serializedExceptions) - { - const uint NoInnerExceptionValue = 0xFFFFFFFF; - - // Approximate upper size limit for the serialized exceptions (but we'll always serialize currentException) - // If we hit the limit, because we serialize in arbitrary order, there may be missing InnerExceptions or nested exceptions. - const int MaxBufferSize = 20000; - - int nExceptions; - RuntimeImports.RhGetExceptionsForCurrentThread(null, out nExceptions); - Exception[] curThreadExceptions = new Exception[nExceptions]; - RuntimeImports.RhGetExceptionsForCurrentThread(curThreadExceptions, out nExceptions); - LowLevelList exceptions = new LowLevelList(curThreadExceptions); - LowLevelList nonThrownInnerExceptions = new LowLevelList(); - - uint currentThreadId = (uint)Environment.CurrentManagedThreadId; - - // Reset nesting levels for exceptions on this thread that might not be currently in flight - foreach (KeyValuePair item in s_exceptionDataTable) - { - ExceptionData exceptionData = item.Value; - if (exceptionData.ExceptionMetadata.ThreadId == currentThreadId) - { - exceptionData.ExceptionMetadata.NestingLevel = -1; - } - } - - // Find all inner exceptions, even if they're not currently being handled - for (int i = 0; i < exceptions.Count; i++) - { - if (exceptions[i].InnerException != null && !exceptions.Contains(exceptions[i].InnerException)) - { - exceptions.Add(exceptions[i].InnerException); - nonThrownInnerExceptions.Add(exceptions[i].InnerException); - } - } - - int currentNestingLevel = curThreadExceptions.Length - 1; - - // Make sure we serialize currentException - if (!exceptions.Contains(currentException)) - { - // When this happens, currentException is probably passed to this function through System.Environment.FailFast(), we - // would want to treat as if this exception is last thrown in the current thread. - exceptions.Insert(0, currentException); - currentNestingLevel++; - } - - // Populate exception data for all exceptions interesting to this thread. - // Whether or not there was previously data for that object, it might have changed. - for (int i = 0; i < exceptions.Count; i++) - { - ExceptionData exceptionData = s_exceptionDataTable.GetOrCreateValue(exceptions[i]); - - exceptionData.ExceptionMetadata.ExceptionId = (uint)System.Threading.Interlocked.Increment(ref s_currentExceptionId); - if (exceptionData.ExceptionMetadata.ExceptionId == NoInnerExceptionValue) - { - exceptionData.ExceptionMetadata.ExceptionId = (uint)System.Threading.Interlocked.Increment(ref s_currentExceptionId); - } - - exceptionData.ExceptionMetadata.ThreadId = currentThreadId; - - // Only include nesting information for exceptions that were thrown on this thread - if (!nonThrownInnerExceptions.Contains(exceptions[i])) - { - exceptionData.ExceptionMetadata.NestingLevel = currentNestingLevel; - currentNestingLevel--; - } - else - { - exceptionData.ExceptionMetadata.NestingLevel = -1; - } - - // Only match the CCW pointer up to the current exception - if (object.ReferenceEquals(exceptions[i], currentException)) - { - exceptionData.ExceptionMetadata.ExceptionCCWPtr = exceptionCCWPtr; - } - - byte[] serializedEx = exceptions[i].SerializeForDump(); - exceptionData.SerializedExceptionData = serializedEx; - } - - // Populate inner exception ids now that we have all of them in the table - for (int i = 0; i < exceptions.Count; i++) - { - ExceptionData exceptionData; - if (!s_exceptionDataTable.TryGetValue(exceptions[i], out exceptionData)) - { - // This shouldn't happen, but we can't meaningfully throw here - continue; - } - - if (exceptions[i].InnerException != null) - { - ExceptionData innerExceptionData; - if (s_exceptionDataTable.TryGetValue(exceptions[i].InnerException, out innerExceptionData)) - { - exceptionData.ExceptionMetadata.InnerExceptionId = innerExceptionData.ExceptionMetadata.ExceptionId; - } - } - else - { - exceptionData.ExceptionMetadata.InnerExceptionId = NoInnerExceptionValue; - } - } - - int totalSerializedExceptionSize = 0; - // Make sure we include the current exception, regardless of buffer size - ExceptionData currentExceptionData = null; - if (s_exceptionDataTable.TryGetValue(currentException, out currentExceptionData)) - { - byte[] serializedExceptionData = currentExceptionData.Serialize(); - serializedExceptions.Add(serializedExceptionData); - totalSerializedExceptionSize = serializedExceptionData.Length; - } - - checked - { - foreach (KeyValuePair item in s_exceptionDataTable) - { - ExceptionData exceptionData = item.Value; - - // Already serialized currentException - if (currentExceptionData != null && exceptionData.ExceptionMetadata.ExceptionId == currentExceptionData.ExceptionMetadata.ExceptionId) - { - continue; - } - - byte[] serializedExceptionData = exceptionData.Serialize(); - if (totalSerializedExceptionSize + serializedExceptionData.Length >= MaxBufferSize) - { - break; - } - - serializedExceptions.Add(serializedExceptionData); - totalSerializedExceptionSize += serializedExceptionData.Length; - } - } - } - - private static unsafe void GenerateErrorReportForDump(LowLevelList serializedExceptions) - { - checked - { - int loadedModuleCount = (int)RuntimeImports.RhGetLoadedOSModules(null); - int cbModuleHandles = sizeof(System.IntPtr) * loadedModuleCount; - int cbFinalBuffer = sizeof(ERROR_REPORT_BUFFER_HEADER) + sizeof(SERIALIZED_ERROR_REPORT_HEADER) + cbModuleHandles; - for (int i = 0; i < serializedExceptions.Count; i++) - { - cbFinalBuffer += serializedExceptions[i].Length; - } - - byte[] finalBuffer = new byte[cbFinalBuffer]; - fixed (byte* pBuffer = &finalBuffer[0]) - { - byte* pCursor = pBuffer; - int cbRemaining = cbFinalBuffer; - - ERROR_REPORT_BUFFER_HEADER* pDacHeader = (ERROR_REPORT_BUFFER_HEADER*)pCursor; - pDacHeader->WriteHeader(cbFinalBuffer); - pCursor += sizeof(ERROR_REPORT_BUFFER_HEADER); - cbRemaining -= sizeof(ERROR_REPORT_BUFFER_HEADER); - - SERIALIZED_ERROR_REPORT_HEADER* pPayloadHeader = (SERIALIZED_ERROR_REPORT_HEADER*)pCursor; - pPayloadHeader->WriteHeader(serializedExceptions.Count, loadedModuleCount); - pCursor += sizeof(SERIALIZED_ERROR_REPORT_HEADER); - cbRemaining -= sizeof(SERIALIZED_ERROR_REPORT_HEADER); - - // copy the serialized exceptions to report buffer - for (int i = 0; i < serializedExceptions.Count; i++) - { - int cbChunk = serializedExceptions[i].Length; - serializedExceptions[i].AsSpan().CopyTo(new Span(pCursor, cbChunk)); - cbRemaining -= cbChunk; - pCursor += cbChunk; - } - - // copy the module-handle array to report buffer - IntPtr[] loadedModuleHandles = new IntPtr[loadedModuleCount]; - RuntimeImports.RhGetLoadedOSModules(loadedModuleHandles); - loadedModuleHandles.AsSpan().CopyTo(new Span(pCursor, loadedModuleHandles.Length)); - cbRemaining -= cbModuleHandles; - pCursor += cbModuleHandles; - - Debug.Assert(cbRemaining == 0); - } - UpdateErrorReportBuffer(finalBuffer); - } - } - - private static GCHandle s_ExceptionInfoBufferPinningHandle; - private static Lock s_ExceptionInfoBufferLock = new Lock(); - - private static unsafe void UpdateErrorReportBuffer(byte[] finalBuffer) - { - Debug.Assert(finalBuffer?.Length > 0); - - using (LockHolder.Hold(s_ExceptionInfoBufferLock)) - { - fixed (byte* pBuffer = &finalBuffer[0]) - { - byte* pPrevBuffer = (byte*)RuntimeImports.RhSetErrorInfoBuffer(pBuffer); - Debug.Assert(s_ExceptionInfoBufferPinningHandle.IsAllocated == (pPrevBuffer != null)); - if (pPrevBuffer != null) - { - byte[] currentExceptionInfoBuffer = (byte[])s_ExceptionInfoBufferPinningHandle.Target; - Debug.Assert(currentExceptionInfoBuffer?.Length > 0); - fixed (byte* pPrev = ¤tExceptionInfoBuffer[0]) - Debug.Assert(pPrev == pPrevBuffer); - } - if (!s_ExceptionInfoBufferPinningHandle.IsAllocated) - { - // We allocate a pinning GC handle because we are logically giving the runtime 'unmanaged memory'. - s_ExceptionInfoBufferPinningHandle = GCHandle.Alloc(finalBuffer, GCHandleType.Pinned); - } - else - { - s_ExceptionInfoBufferPinningHandle.Target = finalBuffer; - } - } - } - } -#endif // FEATURE_DUMP_DEBUGGING } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs index cdf98172819758..526362d6527ea1 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs @@ -51,18 +51,7 @@ public override int GetHashCode() [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(RuntimeTypeHandle handle) { - if (_value == handle._value) - { - return true; - } - else if (this.IsNull || handle.IsNull) - { - return false; - } - else - { - return RuntimeImports.AreTypesEquivalent(this.ToEETypePtr(), handle.ToEETypePtr()); - } + return _value == handle._value; } public static RuntimeTypeHandle FromIntPtr(IntPtr value) => new RuntimeTypeHandle(value); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs index a0873fc273ff32..5046b6230104fc 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs @@ -9,7 +9,7 @@ namespace System.Threading /// A LIFO semaphore. /// Waits on this semaphore are uninterruptible. /// - internal sealed partial class LowLevelLifoSemaphore : IDisposable + internal sealed partial class LowLevelLifoSemaphore : LowLevelLifoSemaphoreBase, IDisposable { private WaitSubsystem.WaitableObject _semaphore; @@ -27,7 +27,7 @@ private bool WaitCore(int timeoutMs) return WaitSubsystem.Wait(_semaphore, timeoutMs, false, true) == WaitHandle.WaitSuccess; } - private void ReleaseCore(int count) + protected override void ReleaseCore(int count) { WaitSubsystem.ReleaseSemaphore(_semaphore, count); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs index 17187d41b716b4..47b08a12daabd1 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs @@ -306,7 +306,9 @@ public override bool TryGetFunctionPointerTypeForComponents(RuntimeTypeHandle re // public override void GetFunctionPointerTypeComponents(RuntimeTypeHandle functionPointerHandle, out RuntimeTypeHandle returnTypeHandle, out RuntimeTypeHandle[] parameterHandles, out bool isUnmanaged) { - TypeLoaderEnvironment.Instance.GetFunctionPointerTypeComponents(functionPointerHandle, out returnTypeHandle, out parameterHandles, out isUnmanaged); + returnTypeHandle = RuntimeAugments.GetFunctionPointerReturnType(functionPointerHandle); + parameterHandles = RuntimeAugments.GetFunctionPointerParameterTypes(functionPointerHandle); + isUnmanaged = RuntimeAugments.IsUnmanagedFunctionPointerType(functionPointerHandle); } // diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs index 0f7ec210484755..fe136fabc5427d 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs @@ -53,7 +53,7 @@ public static unsafe void SetDictionary(this RuntimeTypeHandle rtth, int diction public static unsafe void SetInterface(this RuntimeTypeHandle rtth, int interfaceIndex, RuntimeTypeHandle interfaceType) { - rtth.ToEETypePtr()->InterfaceMap[interfaceIndex].InterfaceType = interfaceType.ToEETypePtr(); + rtth.ToEETypePtr()->InterfaceMap[interfaceIndex] = interfaceType.ToEETypePtr(); } public static unsafe void SetGenericDefinition(this RuntimeTypeHandle rtth, RuntimeTypeHandle genericDefinitionHandle) @@ -61,19 +61,10 @@ public static unsafe void SetGenericDefinition(this RuntimeTypeHandle rtth, Runt rtth.ToEETypePtr()->GenericDefinition = genericDefinitionHandle.ToEETypePtr(); } - public static unsafe void SetGenericVariance(this RuntimeTypeHandle rtth, int argumentIndex, GenericVariance variance) - { - rtth.ToEETypePtr()->GenericVariance[argumentIndex] = variance; - } - - public static unsafe void SetGenericArity(this RuntimeTypeHandle rtth, uint arity) - { - rtth.ToEETypePtr()->GenericArity = arity; - } - public static unsafe void SetGenericArgument(this RuntimeTypeHandle rtth, int argumentIndex, RuntimeTypeHandle argumentType) { - rtth.ToEETypePtr()->GenericArguments[argumentIndex].Value = argumentType.ToEETypePtr(); + MethodTableList argumentList = rtth.ToEETypePtr()->GenericArguments; + argumentList[argumentIndex] = argumentType.ToEETypePtr(); } public static unsafe void SetRelatedParameterType(this RuntimeTypeHandle rtth, RuntimeTypeHandle relatedTypeHandle) @@ -164,10 +155,12 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo int baseSize = 0; bool isValueType; + bool hasDispatchMap; bool hasFinalizer; bool isNullable; bool isArray; bool isGeneric; + bool hasSealedVTable; uint flags; ushort runtimeInterfacesLength = 0; IntPtr typeManager = IntPtr.Zero; @@ -180,15 +173,18 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo baseSize = (int)pTemplateEEType->RawBaseSize; isValueType = pTemplateEEType->IsValueType; hasFinalizer = pTemplateEEType->IsFinalizable; + hasDispatchMap = pTemplateEEType->HasDispatchMap; isNullable = pTemplateEEType->IsNullable; flags = pTemplateEEType->Flags; isArray = pTemplateEEType->IsArray; isGeneric = pTemplateEEType->IsGeneric; + hasSealedVTable = pTemplateEEType->HasSealedVTableEntries; typeManager = pTemplateEEType->PointerToTypeManager; Debug.Assert(pTemplateEEType->NumInterfaces == runtimeInterfacesLength); flags |= (uint)EETypeFlags.IsDynamicTypeFlag; + int numFunctionPointerTypeParameters = 0; if (state.TypeBeingBuilt.IsMdArray) { // If we're building an MDArray, the template is object[,] and we @@ -197,6 +193,17 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo 2 * IntPtr.Size + // EETypePtr + Length state.ArrayRank.Value * sizeof(int) * 2; // 2 ints per rank for bounds } + else if (state.TypeBeingBuilt.IsFunctionPointer) + { + // Base size encodes number of parameters and calling convention + MethodSignature sig = ((FunctionPointerType)state.TypeBeingBuilt).Signature; + baseSize = (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) switch + { + 0 => sig.Length, + _ => sig.Length | unchecked((int)FunctionPointerFlags.IsUnmanaged), + }; + numFunctionPointerTypeParameters = sig.Length; + } // Optional fields encoding int cbOptionalFieldsSize; @@ -220,9 +227,6 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo if (rareFlags != 0) optionalFields.SetFieldValue(EETypeOptionalFieldTag.RareFlags, rareFlags); - // Dispatch map is fetched from template type - optionalFields.ClearField(EETypeOptionalFieldTag.DispatchMap); - // Compute size of optional fields encoding cbOptionalFieldsSize = optionalFields.Encode(); @@ -246,10 +250,12 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo int cbEEType = (int)MethodTable.GetSizeofEEType( numVtableSlots, runtimeInterfacesLength, + hasDispatchMap, hasFinalizer, cbOptionalFieldsSize > 0, - (rareFlags & (int)EETypeRareFlags.HasSealedVTableEntriesFlag) != 0, + hasSealedVTable, isGeneric, + numFunctionPointerTypeParameters, allocatedNonGCDataSize != 0, state.GcDataSize != 0, state.ThreadDataSize != 0); @@ -294,6 +300,12 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo for (int i = 0; i < numVtableSlots; i++) pVtable[i] = pTemplateVtable[i]; + // Copy dispatch map from the template type + if (hasDispatchMap) + { + pEEType->DispatchMap = pTemplateEEType->DispatchMap; + } + // Copy Pointer to finalizer method from the template type if (hasFinalizer) { @@ -302,7 +314,7 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo } // Copy the sealed vtable entries if they exist on the template type - if ((rareFlags & (int)EETypeRareFlags.HasSealedVTableEntriesFlag) != 0) + if (hasSealedVTable) { uint cbSealedVirtualSlotsTypeOffset = pEEType->GetFieldOffset(EETypeField.ETF_SealedVirtualSlots); *((void**)((byte*)pEEType + cbSealedVirtualSlotsTypeOffset)) = pTemplateEEType->GetSealedVirtualTable(); @@ -329,8 +341,11 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo if (isGeneric) { - genericComposition = MemoryHelpers.AllocateMemory(MethodTable.GetGenericCompositionSize(arity, pEEType->HasGenericVariance)); - pEEType->SetGenericComposition(genericComposition); + if (arity > 1) + { + genericComposition = MemoryHelpers.AllocateMemory(MethodTable.GetGenericCompositionSize(arity)); + pEEType->SetGenericComposition(genericComposition); + } if (allocatedNonGCDataSize > 0) { @@ -624,6 +639,24 @@ private static unsafe int CreateGCDesc(LowLevelList bitfield, int size, bo return numSeries; } + public static RuntimeTypeHandle CreateFunctionPointerEEType(uint hashCodeOfNewType, RuntimeTypeHandle returnTypeHandle, RuntimeTypeHandle[] parameterHandles, FunctionPointerType functionPointerType) + { + TypeBuilderState state = new TypeBuilderState(functionPointerType); + + CreateEETypeWorker(typeof(delegate*).TypeHandle.ToEETypePtr(), hashCodeOfNewType, 0, state); + Debug.Assert(!state.HalfBakedRuntimeTypeHandle.IsNull()); + + TypeLoaderLogger.WriteLine("Allocated new FUNCTION POINTER type " + functionPointerType.ToString() + " with hashcode value = 0x" + hashCodeOfNewType.LowLevelToString() + " with MethodTable = " + state.HalfBakedRuntimeTypeHandle.ToIntPtr().LowLevelToString()); + + state.HalfBakedRuntimeTypeHandle.ToEETypePtr()->FunctionPointerReturnType = returnTypeHandle.ToEETypePtr(); + Debug.Assert(state.HalfBakedRuntimeTypeHandle.ToEETypePtr()->NumFunctionPointerParameters == parameterHandles.Length); + MethodTableList paramList = state.HalfBakedRuntimeTypeHandle.ToEETypePtr()->FunctionPointerParameters; + for (int i = 0; i < parameterHandles.Length; i++) + paramList[i] = parameterHandles[i].ToEETypePtr(); + + return state.HalfBakedRuntimeTypeHandle; + } + public static RuntimeTypeHandle CreatePointerEEType(uint hashCodeOfNewType, RuntimeTypeHandle pointeeTypeHandle, TypeDesc pointerType) { TypeBuilderState state = new TypeBuilderState(pointerType); @@ -666,7 +699,7 @@ public static RuntimeTypeHandle CreateEEType(TypeDesc type, TypeBuilderState sta MethodTable* pTemplateEEType; - if (type is PointerType || type is ByRefType) + if (type is PointerType || type is ByRefType || type is FunctionPointerType) { Debug.Assert(0 == state.NonGcDataSize); Debug.Assert(false == state.HasStaticConstructor); @@ -675,8 +708,17 @@ public static RuntimeTypeHandle CreateEEType(TypeDesc type, TypeBuilderState sta Debug.Assert(IntPtr.Zero == state.GcStaticDesc); Debug.Assert(IntPtr.Zero == state.ThreadStaticDesc); - // Pointers and ByRefs only differ by the ParameterizedTypeShape and ElementType value. - RuntimeTypeHandle templateTypeHandle = typeof(void*).TypeHandle; + RuntimeTypeHandle templateTypeHandle; + if (type is FunctionPointerType) + { + // There's still differences to paper over, but `delegate*` is close enough. + templateTypeHandle = typeof(delegate*).TypeHandle; + } + else + { + // Pointers and ByRefs only differ by the ParameterizedTypeShape and ElementType value. + templateTypeHandle = typeof(void*).TypeHandle; + } pTemplateEEType = templateTypeHandle.ToEETypePtr(); } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs index bf8795ad50f1ea..f3c356f5ce628f 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs @@ -125,7 +125,7 @@ internal TypeDesc GetType(ref NativeParser parser) case TypeSignatureKind.MultiDimArray: { - DefType elementType = (DefType)GetType(ref parser); + TypeDesc elementType = GetType(ref parser); int rank = (int)data; // Skip encoded bounds and lobounds @@ -150,9 +150,25 @@ internal TypeDesc GetType(ref NativeParser parser) return _typeSystemContext.GetWellKnownType((WellKnownType)data); case TypeSignatureKind.FunctionPointer: - Debug.Fail("NYI!"); - NativeParser.ThrowBadImageFormatException(); - return null; + { + var callConv = (MethodCallingConvention)parser.GetUnsigned(); + Debug.Assert((callConv & MethodCallingConvention.Generic) == 0); + + uint numParams = parser.GetUnsigned(); + + TypeDesc returnType = GetType(ref parser); + TypeDesc[] parameters = new TypeDesc[numParams]; + for (uint i = 0; i < parameters.Length; i++) + parameters[i] = GetType(ref parser); + + return _typeSystemContext.GetFunctionPointerType( + new MethodSignature( + (callConv & MethodCallingConvention.Unmanaged) != 0 ? MethodSignatureFlags.UnmanagedCallingConvention : 0, + 0, + returnType, + parameters + )); + } default: NativeParser.ThrowBadImageFormatException(); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 299d25df24a323..1cf54b25ab4505 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -159,7 +159,7 @@ public void PrepareMethod(MethodDesc method) private void InsertIntoNeedsTypeHandleList(TypeDesc type) { - if ((type is DefType) || (type is ArrayType) || (type is PointerType) || (type is ByRefType)) + if ((type is DefType) || (type is ArrayType) || (type is PointerType) || (type is ByRefType) || (type is FunctionPointerType)) { _typesThatNeedTypeHandles.Add(type); } @@ -233,7 +233,7 @@ internal void PrepareType(TypeDesc type) if (type is ArrayType typeAsArrayType) { - if (typeAsArrayType.IsSzArray && !typeAsArrayType.ElementType.IsPointer) + if (typeAsArrayType.IsSzArray && !typeAsArrayType.ElementType.IsPointer && !typeAsArrayType.ElementType.IsFunctionPointer) { TypeDesc.ComputeTemplate(state); Debug.Assert(state.TemplateType != null && state.TemplateType is ArrayType && !state.TemplateType.RuntimeTypeHandle.IsNull()); @@ -242,10 +242,16 @@ internal void PrepareType(TypeDesc type) } else { - Debug.Assert(typeAsArrayType.IsMdArray || typeAsArrayType.ElementType.IsPointer); + Debug.Assert(typeAsArrayType.IsMdArray || typeAsArrayType.ElementType.IsPointer || typeAsArrayType.ElementType.IsFunctionPointer); } } } + else if (type is FunctionPointerType functionPointerType) + { + RegisterForPreparation(functionPointerType.Signature.ReturnType); + foreach (TypeDesc paramType in functionPointerType.Signature) + RegisterForPreparation(paramType); + } else { Debug.Assert(false); @@ -432,14 +438,6 @@ internal void ParseNativeLayoutInfo(TypeBuilderState state, TypeDesc type) state.ThreadStaticDesc = context.GetGCStaticInfo(typeInfoParser.GetUnsigned()); break; - case BagElementKind.GenericVarianceInfo: - TypeLoaderLogger.WriteLine("Found BagElementKind.GenericVarianceInfo"); - NativeParser varianceInfoParser = typeInfoParser.GetParserFromRelativeOffset(); - state.GenericVarianceFlags = new GenericVariance[varianceInfoParser.GetSequenceCount()]; - for (int i = 0; i < state.GenericVarianceFlags.Length; i++) - state.GenericVarianceFlags[i] = checked((GenericVariance)varianceInfoParser.GetUnsigned()); - break; - case BagElementKind.FieldLayout: TypeLoaderLogger.WriteLine("Found BagElementKind.FieldLayout"); typeInfoParser.SkipInteger(); // Handled in type layout algorithm @@ -590,7 +588,7 @@ private unsafe void AllocateRuntimeType(TypeDesc type) { TypeBuilderState state = type.GetTypeBuilderState(); - Debug.Assert(type is DefType || type is ArrayType || type is PointerType || type is ByRefType); + Debug.Assert(type is DefType || type is ArrayType || type is PointerType || type is ByRefType || type is FunctionPointerType); RuntimeTypeHandle rtt = EETypeCreator.CreateEEType(type, state); @@ -788,15 +786,9 @@ private void FinishRuntimeType(TypeDesc type) state.HalfBakedRuntimeTypeHandle.SetGenericDefinition(GetRuntimeTypeHandle(typeAsDefType.GetTypeDefinition())); Instantiation instantiation = typeAsDefType.Instantiation; - state.HalfBakedRuntimeTypeHandle.SetGenericArity((uint)instantiation.Length); for (int argIndex = 0; argIndex < instantiation.Length; argIndex++) { state.HalfBakedRuntimeTypeHandle.SetGenericArgument(argIndex, GetRuntimeTypeHandle(instantiation[argIndex])); - if (state.GenericVarianceFlags != null) - { - Debug.Assert(state.GenericVarianceFlags.Length == instantiation.Length); - state.HalfBakedRuntimeTypeHandle.SetGenericVariance(argIndex, state.GenericVarianceFlags[argIndex]); - } } } @@ -843,6 +835,19 @@ private void FinishRuntimeType(TypeDesc type) } } } + else if (type is FunctionPointerType) + { + MethodSignature sig = ((FunctionPointerType)type).Signature; + unsafe + { + MethodTable* halfBakedMethodTable = state.HalfBakedRuntimeTypeHandle.ToEETypePtr(); + halfBakedMethodTable->FunctionPointerReturnType = GetRuntimeTypeHandle(sig.ReturnType).ToEETypePtr(); + Debug.Assert(halfBakedMethodTable->NumFunctionPointerParameters == sig.Length); + MethodTableList paramList = halfBakedMethodTable->FunctionPointerParameters; + for (int i = 0; i < sig.Length; i++) + paramList[i] = GetRuntimeTypeHandle(sig[i]).ToEETypePtr(); + } + } else { Debug.Assert(false); @@ -942,24 +947,25 @@ private void FinishTypeAndMethodBuilding() int newArrayTypesCount = 0; int newPointerTypesCount = 0; int newByRefTypesCount = 0; + int newFunctionPointerTypesCount = 0; int[] mdArrayNewTypesCount = null; for (int i = 0; i < _typesThatNeedTypeHandles.Count; i++) { - ParameterizedType typeAsParameterizedType = _typesThatNeedTypeHandles[i] as ParameterizedType; - if (typeAsParameterizedType == null) - continue; + TypeDesc type = _typesThatNeedTypeHandles[i]; - if (typeAsParameterizedType.IsSzArray) + if (type.IsSzArray) newArrayTypesCount++; - else if (typeAsParameterizedType.IsPointer) + else if (type.IsPointer) newPointerTypesCount++; - else if (typeAsParameterizedType.IsByRef) + else if (type.IsFunctionPointer) + newFunctionPointerTypesCount++; + else if (type.IsByRef) newByRefTypesCount++; - else if (typeAsParameterizedType.IsMdArray) + else if (type.IsMdArray) { mdArrayNewTypesCount ??= new int[MDArray.MaxRank + 1]; - mdArrayNewTypesCount[((ArrayType)typeAsParameterizedType).Rank]++; + mdArrayNewTypesCount[((ArrayType)type).Rank]++; } } // Reserve space in array/pointer cache's so that the actual adding can be fault-free. @@ -981,6 +987,7 @@ private void FinishTypeAndMethodBuilding() TypeSystemContext.PointerTypesCache.Reserve(TypeSystemContext.PointerTypesCache.Count + newPointerTypesCount); TypeSystemContext.ByRefTypesCache.Reserve(TypeSystemContext.ByRefTypesCache.Count + newByRefTypesCount); + TypeSystemContext.FunctionPointerTypesCache.Reserve(TypeSystemContext.FunctionPointerTypesCache.Count + newFunctionPointerTypesCount); // Finally, register all generic types and methods atomically with the runtime RegisterGenericTypesAndMethods(); @@ -1001,7 +1008,8 @@ private void FinishTypeAndMethodBuilding() { if (_typesThatNeedTypeHandles[i] is FunctionPointerType typeAsFunctionPointerType) { - throw new NotImplementedException(); + Debug.Assert(!typeAsFunctionPointerType.RuntimeTypeHandle.IsNull()); + TypeSystemContext.FunctionPointerTypesCache.AddOrGetExisting(typeAsFunctionPointerType.RuntimeTypeHandle); } continue; } @@ -1282,6 +1290,30 @@ public static bool TryBuildByRefType(RuntimeTypeHandle pointeeTypeHandle, out Ru return true; } + public static bool TryBuildFunctionPointerType(RuntimeTypeHandle returnTypeHandle, RuntimeTypeHandle[] parameterHandles, bool isUnmanaged, out RuntimeTypeHandle runtimeTypeHandle) + { + var key = new TypeSystemContext.FunctionPointerTypeKey(returnTypeHandle, parameterHandles, isUnmanaged); + if (!TypeSystemContext.FunctionPointerTypesCache.TryGetValue(key, out runtimeTypeHandle)) + { + TypeSystemContext context = TypeSystemContextFactory.Create(); + FunctionPointerType functionPointerType = context.GetFunctionPointerType(new MethodSignature( + isUnmanaged ? MethodSignatureFlags.UnmanagedCallingConvention : 0, + genericParameterCount: 0, + context.ResolveRuntimeTypeHandle(returnTypeHandle), + context.ResolveRuntimeTypeHandlesInternal(parameterHandles))); + runtimeTypeHandle = EETypeCreator.CreateFunctionPointerEEType((uint)functionPointerType.GetHashCode(), returnTypeHandle, parameterHandles, functionPointerType); + unsafe + { + Debug.Assert(runtimeTypeHandle.ToEETypePtr()->IsFunctionPointerType); + } + TypeSystemContext.FunctionPointerTypesCache.AddOrGetExisting(runtimeTypeHandle); + + // Recycle the context only if we successfully built the type. The state may be partially initialized otherwise. + TypeSystemContextFactory.Recycle(context); + } + return true; + } + internal static bool TryBuildGenericMethod(InstantiatedMethod methodBeingLoaded, out IntPtr methodDictionary) { try diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs index b4348c1ed51b0f..a95514e7bf0b37 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs @@ -69,7 +69,8 @@ public TypeDesc TemplateType // Arrays of pointers don't implement generic interfaces and are special cases. They use // typeof(char*[]) as their template. - if (TypeBeingBuilt.IsSzArray && ((ArrayType)TypeBeingBuilt).ElementType.IsPointer) + if (TypeBeingBuilt.IsSzArray && ((ArrayType)TypeBeingBuilt).ElementType is TypeDesc elementType && + (elementType.IsPointer || elementType.IsFunctionPointer)) { _templateType = TypeBeingBuilt.Context.ResolveRuntimeTypeHandle(typeof(char*[]).TypeHandle); _templateTypeLoaderNativeLayout = false; @@ -252,12 +253,13 @@ private ushort ComputeNumVTableSlots() // Template type loader case unsafe { - if (TypeBeingBuilt.IsPointer || TypeBeingBuilt.IsByRef) + if (TypeBeingBuilt.IsPointer || TypeBeingBuilt.IsByRef || TypeBeingBuilt.IsFunctionPointer) { // Pointers and byrefs don't have vtable slots return 0; } - if (TypeBeingBuilt.IsMdArray || (TypeBeingBuilt.IsSzArray && ((ArrayType)TypeBeingBuilt).ElementType.IsPointer)) + if (TypeBeingBuilt.IsMdArray || (TypeBeingBuilt.IsSzArray && ((ArrayType)TypeBeingBuilt).ElementType is TypeDesc elementType + && (elementType.IsPointer || elementType.IsFunctionPointer))) { // MDArray types and pointer arrays have the same vtable as the System.Array type they "derive" from. // They do not implement the generic interfaces that make this interesting for normal arrays. @@ -355,7 +357,8 @@ public LowLevelList InstanceGCLayout Debug.Assert(TypeBeingBuilt.RetrieveRuntimeTypeHandleIfPossible() || TypeBeingBuilt.IsTemplateCanonical() || (TypeBeingBuilt is PointerType) || - (TypeBeingBuilt is ByRefType)); + (TypeBeingBuilt is ByRefType) || + (TypeBeingBuilt is FunctionPointerType)); _instanceGCLayout = s_emptyLayout; } } @@ -458,7 +461,7 @@ public bool IsArrayOfReferenceTypes { ArrayType typeAsArrayType = TypeBeingBuilt as ArrayType; if (typeAsArrayType != null) - return !typeAsArrayType.ParameterType.IsValueType && !typeAsArrayType.ParameterType.IsPointer; + return !typeAsArrayType.ParameterType.IsValueType && !typeAsArrayType.ParameterType.IsPointer && !typeAsArrayType.ParameterType.IsFunctionPointer; else return false; } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericTypesLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericTypesLookup.cs index 5c918fc26cc327..2db0a24b5586d9 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericTypesLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericTypesLookup.cs @@ -91,76 +91,34 @@ protected override GenericTypeEntry CreateValueFromKey(GenericTypeLookupData key } } - internal abstract class GenericTypeLookupData - { - internal abstract int LookupHashCode(); - internal abstract bool MatchParsedEntry(RuntimeTypeHandle tentativeType); - internal abstract bool MatchGenericTypeEntry(GenericTypeEntry entry); - } - internal class DefTypeBasedGenericTypeLookup : GenericTypeLookupData - { - protected DefType _typeToLookup; - - internal DefTypeBasedGenericTypeLookup(DefType typeToLookup) { _typeToLookup = typeToLookup; } - - internal override int LookupHashCode() { return _typeToLookup.GetHashCode(); } - - internal override bool MatchParsedEntry(RuntimeTypeHandle tentativeType) - { - // - // Entries read from the hashtable are loaded as DefTypes, and compared to the input. - // This lookup is slower than the lookups using RuntimeTypeHandles, but can handle cases where we don't have - // RuntimeTypeHandle values for all of the components of the input DefType, but still need to look it up in case the type - // statically exists and has an existing RuntimeTypeHandle value. - // - TypeSystemContext context = _typeToLookup.Context; - - RuntimeTypeHandle[] parsedArgsHandles; - RuntimeTypeHandle parsedTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(tentativeType, out parsedArgsHandles); - - DefType parsedTypeDefinition = (DefType)context.ResolveRuntimeTypeHandle(parsedTypeDefinitionHandle); - Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(parsedArgsHandles); - DefType parsedGenericType = context.ResolveGenericInstantiation(parsedTypeDefinition, parsedArgs); - - return parsedGenericType == _typeToLookup; - } - - internal override bool MatchGenericTypeEntry(GenericTypeEntry entry) - { - TypeSystemContext context = _typeToLookup.Context; - - DefType parsedTypeDefinition = (DefType)context.ResolveRuntimeTypeHandle(entry._genericTypeDefinitionHandle); - Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(entry._genericTypeArgumentHandles); - DefType parsedGenericType = context.ResolveGenericInstantiation(parsedTypeDefinition, parsedArgs); - - return parsedGenericType == _typeToLookup; - } - } - internal class HandleBasedGenericTypeLookup : DefTypeBasedGenericTypeLookup + internal struct GenericTypeLookupData { + private DefType _typeToLookup; private RuntimeTypeHandle _genericTypeDefinitionHandle; private RuntimeTypeHandle[] _genericTypeArgumentHandles; - internal HandleBasedGenericTypeLookup(DefType typeToLookup) : base(typeToLookup) + internal GenericTypeLookupData(DefType typeToLookup) { Debug.Assert(typeToLookup != null); + _typeToLookup = typeToLookup; _genericTypeDefinitionHandle = _typeToLookup.GetTypeDefinition().RuntimeTypeHandle; // _genericTypeArgumentHandles not initialized here to avoid allocation of new array (and it's not used if we initialize _typeToLookup). } - internal HandleBasedGenericTypeLookup(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles) : base(null) + internal GenericTypeLookupData(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles) { Debug.Assert(genericTypeArgumentHandles != null); + _typeToLookup = null; _genericTypeDefinitionHandle = genericTypeDefinitionHandle; _genericTypeArgumentHandles = genericTypeArgumentHandles; } - internal override int LookupHashCode() + internal int LookupHashCode() { return _typeToLookup != null ? _typeToLookup.GetHashCode() : TypeHashingAlgorithms.ComputeGenericInstanceHashCode(_genericTypeDefinitionHandle.GetHashCode(), _genericTypeArgumentHandles); } - internal override bool MatchParsedEntry(RuntimeTypeHandle tentativeType) + internal bool MatchParsedEntry(RuntimeTypeHandle tentativeType) { RuntimeTypeHandle parsedTypeDefinitionHandle = RuntimeAugments.GetGenericDefinition(tentativeType); if (!parsedTypeDefinitionHandle.Equals(_genericTypeDefinitionHandle)) @@ -179,7 +137,7 @@ internal override bool MatchParsedEntry(RuntimeTypeHandle tentativeType) return true; } - internal override bool MatchGenericTypeEntry(GenericTypeEntry entry) + internal bool MatchGenericTypeEntry(GenericTypeEntry entry) { if (!entry._genericTypeDefinitionHandle.Equals(_genericTypeDefinitionHandle)) return false; @@ -254,7 +212,7 @@ internal bool TryLookupConstructedGenericTypeForComponents(GenericTypeLookupData public bool TryLookupConstructedGenericTypeForComponents(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles, out RuntimeTypeHandle runtimeTypeHandle) { - return TryLookupConstructedGenericTypeForComponents(new HandleBasedGenericTypeLookup(genericTypeDefinitionHandle, genericTypeArgumentHandles), out runtimeTypeHandle); + return TryLookupConstructedGenericTypeForComponents(new GenericTypeLookupData(genericTypeDefinitionHandle, genericTypeArgumentHandles), out runtimeTypeHandle); } public bool TryLookupConstructedLazyDictionaryForContext(IntPtr context, IntPtr signature, out IntPtr dictionary) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs index fff856fc124050..fba781424ea971 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs @@ -370,13 +370,12 @@ private static unsafe bool TryGetNamedTypeForTypeReference_Inner(MetadataReader /// Preconditions: /// elementTypeHandle is a valid RuntimeTypeHandle. /// - /// MethodTable of the array element type - /// Resolved MethodTable of the array type - public static unsafe bool TryGetArrayTypeForNonDynamicElementType(RuntimeTypeHandle elementTypeHandle, out RuntimeTypeHandle arrayTypeHandle) + public static unsafe bool TryGetArrayTypeForNonDynamicElementType(RuntimeTypeHandle elementTypeHandle, bool isMdArray, int rank, out RuntimeTypeHandle arrayTypeHandle) { arrayTypeHandle = new RuntimeTypeHandle(); - int arrayHashcode = TypeHashingAlgorithms.ComputeArrayTypeHashCode(elementTypeHandle.GetHashCode(), -1); + Debug.Assert(isMdArray || rank == -1); + int arrayHashcode = TypeHashingAlgorithms.ComputeArrayTypeHashCode(elementTypeHandle.GetHashCode(), rank); // Note: ReflectionMapBlob.ArrayMap may not exist in the module that contains the element type. // So we must enumerate all loaded modules in order to find ArrayMap and the array type for @@ -398,7 +397,8 @@ public static unsafe bool TryGetArrayTypeForNonDynamicElementType(RuntimeTypeHan { RuntimeTypeHandle foundArrayType = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); RuntimeTypeHandle foundArrayElementType = RuntimeAugments.GetRelatedParameterTypeHandle(foundArrayType); - if (foundArrayElementType.Equals(elementTypeHandle)) + if (foundArrayElementType.Equals(elementTypeHandle) + && rank == RuntimeAugments.GetArrayRankOrMinusOneForSzArray(foundArrayType)) { arrayTypeHandle = foundArrayType; return true; @@ -410,50 +410,48 @@ public static unsafe bool TryGetArrayTypeForNonDynamicElementType(RuntimeTypeHan return false; } - public void GetStaticFunctionPointerTypeComponents(RuntimeTypeHandle functionPointerHandle, out RuntimeTypeHandle returnTypeHandle, out RuntimeTypeHandle[] parameterHandles, out bool isUnmanaged) + public static unsafe bool TryGetByRefTypeForNonDynamicElementType(RuntimeTypeHandle elementTypeHandle, out RuntimeTypeHandle pointerTypeHandle) { - Debug.Assert(!RuntimeAugments.IsDynamicType(functionPointerHandle)); - Debug.Assert(RuntimeAugments.IsFunctionPointerType(functionPointerHandle)); + int byRefHashcode = TypeHashingAlgorithms.ComputeByrefTypeHashCode(elementTypeHandle.GetHashCode()); + return TryGetParameterizedTypeForNonDynamicElementType(elementTypeHandle, byRefHashcode, ReflectionMapBlob.ByRefTypeMap, out pointerTypeHandle); + } - int hashCode = functionPointerHandle.GetHashCode(); + public static unsafe bool TryGetPointerTypeForNonDynamicElementType(RuntimeTypeHandle elementTypeHandle, out RuntimeTypeHandle pointerTypeHandle) + { + int pointerHashcode = TypeHashingAlgorithms.ComputePointerTypeHashCode(elementTypeHandle.GetHashCode()); + return TryGetParameterizedTypeForNonDynamicElementType(elementTypeHandle, pointerHashcode, ReflectionMapBlob.PointerTypeMap, out pointerTypeHandle); + } + private static unsafe bool TryGetParameterizedTypeForNonDynamicElementType(RuntimeTypeHandle elementTypeHandle, int hashCode, ReflectionMapBlob blob, out RuntimeTypeHandle parameterizedTypeHandle) + { foreach (NativeFormatModuleInfo module in ModuleList.EnumerateModules()) { - if (TryGetNativeReaderForBlob(module, ReflectionMapBlob.FunctionPointerTypeMap, out NativeReader fnPtrMapReader)) + NativeReader mapReader; + if (TryGetNativeReaderForBlob(module, blob, out mapReader)) { - NativeParser fnPtrMapParser = new NativeParser(fnPtrMapReader, 0); - NativeHashtable fnPtrHashtable = new NativeHashtable(fnPtrMapParser); + NativeParser mapParser = new NativeParser(mapReader, 0); + NativeHashtable hashtable = new NativeHashtable(mapParser); ExternalReferencesTable externalReferences = default(ExternalReferencesTable); externalReferences.InitializeCommonFixupsTable(module); - var lookup = fnPtrHashtable.Lookup(hashCode); + var lookup = hashtable.Lookup(hashCode); NativeParser entryParser; while (!(entryParser = lookup.GetNext()).IsNull) { - RuntimeTypeHandle foundFnPtrType = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); - if (!foundFnPtrType.Equals(functionPointerHandle)) - continue; - - uint countAndUnmanagedBit = entryParser.GetUnsigned(); - isUnmanaged = (countAndUnmanagedBit & FunctionPointerMapEntry.IsUnmanagedFlag) != 0; - - returnTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); - - uint count = countAndUnmanagedBit >> FunctionPointerMapEntry.ParameterCountShift; - - parameterHandles = new RuntimeTypeHandle[count]; - for (int i = 0; i < parameterHandles.Length; i++) - parameterHandles[i] = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); - - return; + RuntimeTypeHandle foundParameterizedType = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); + RuntimeTypeHandle foundElementType = RuntimeAugments.GetRelatedParameterTypeHandle(foundParameterizedType); + if (foundElementType.Equals(elementTypeHandle)) + { + parameterizedTypeHandle = foundParameterizedType; + return true; + } } } } - // Unreachable unless there's a compiler bug - Debug.Fail("Should have found a static function pointer in the hashtable"); - throw new NotSupportedException(); + parameterizedTypeHandle = default; + return false; } public bool TryGetStaticFunctionPointerTypeForComponents(RuntimeTypeHandle returnTypeHandle, RuntimeTypeHandle[] parameterHandles, bool isUnmanaged, out RuntimeTypeHandle runtimeTypeHandle) @@ -475,33 +473,23 @@ public bool TryGetStaticFunctionPointerTypeForComponents(RuntimeTypeHandle retur while (!(entryParser = lookup.GetNext()).IsNull) { uint foundFnPtrTypeIndex = entryParser.GetUnsigned(); + RuntimeTypeHandle foundTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(foundFnPtrTypeIndex); - uint countAndUnmanagedBit = entryParser.GetUnsigned(); - bool foundIsUnmanaged = (countAndUnmanagedBit & FunctionPointerMapEntry.IsUnmanagedFlag) != 0; - uint foundParamCount = countAndUnmanagedBit >> FunctionPointerMapEntry.ParameterCountShift; + if (RuntimeAugments.GetFunctionPointerParameterCount(foundTypeHandle) != parameterHandles.Length) + continue; - if (foundIsUnmanaged != isUnmanaged || foundParamCount != parameterHandles.Length) + if (!RuntimeAugments.GetFunctionPointerReturnType(foundTypeHandle).Equals(returnTypeHandle)) continue; - RuntimeTypeHandle foundReturnTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); - if (!foundReturnTypeHandle.Equals(returnTypeHandle)) + if (RuntimeAugments.IsUnmanagedFunctionPointerType(foundTypeHandle) != isUnmanaged) continue; - bool matches = true; - for (int i = 0; i < foundParamCount; i++) - { - if (!externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()).Equals(parameterHandles[i])) - { - matches = false; - break; - } - } + for (int i = 0; i < parameterHandles.Length; i++) + if (!parameterHandles[i].Equals(RuntimeAugments.GetFunctionPointerParameterType(foundTypeHandle, i))) + continue; - if (matches) - { - runtimeTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(foundFnPtrTypeIndex); - return true; - } + runtimeTypeHandle = foundTypeHandle; + return true; } } } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs index 3fbec317f3058d..f9dfb5b8a37f06 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs @@ -349,23 +349,33 @@ public bool TryGetFunctionPointerTypeForComponents(RuntimeTypeHandle returnTypeH using (LockHolder.Hold(_typeLoaderLock)) { - throw new NotImplementedException(); + return TypeBuilder.TryBuildFunctionPointerType(returnTypeHandle, parameterHandles, isUnmanaged, out runtimeTypeHandle); } } public bool TryLookupFunctionPointerTypeForComponents(RuntimeTypeHandle returnTypeHandle, RuntimeTypeHandle[] parameterHandles, bool isUnmanaged, out RuntimeTypeHandle runtimeTypeHandle) { - // TODO: cache same as for arrays - // TODO: lookup dynamically built ones - return TryGetStaticFunctionPointerTypeForComponents(returnTypeHandle, parameterHandles, isUnmanaged, out runtimeTypeHandle); - } + var key = new TypeSystemContext.FunctionPointerTypeKey(returnTypeHandle, parameterHandles, isUnmanaged); + if (TypeSystemContext.FunctionPointerTypesCache.TryGetValue(key, out runtimeTypeHandle)) + return true; - public void GetFunctionPointerTypeComponents(RuntimeTypeHandle functionPointerHandle, out RuntimeTypeHandle returnTypeHandle, out RuntimeTypeHandle[] parameterHandles, out bool isUnmanaged) - { - if (RuntimeAugments.IsDynamicType(functionPointerHandle)) - throw new NotImplementedException(); + if (!RuntimeAugments.IsDynamicType(returnTypeHandle) + && AllNonDynamicTypes(parameterHandles) + && TryGetStaticFunctionPointerTypeForComponents(returnTypeHandle, parameterHandles, isUnmanaged, out runtimeTypeHandle)) + { + TypeSystemContext.FunctionPointerTypesCache.AddOrGetExisting(runtimeTypeHandle); + return true; + } + + return false; - GetStaticFunctionPointerTypeComponents(functionPointerHandle, out returnTypeHandle, out parameterHandles, out isUnmanaged); + static bool AllNonDynamicTypes(RuntimeTypeHandle[] handles) + { + foreach (RuntimeTypeHandle h in handles) + if (RuntimeAugments.IsDynamicType(h)) + return false; + return true; + } } // Get an array RuntimeTypeHandle given an element's RuntimeTypeHandle and rank. Pass false for isMdArray, and rank == -1 for SzArrays @@ -403,9 +413,8 @@ internal static bool TryGetArrayTypeForElementType_LookupOnly(RuntimeTypeHandle if (TypeSystemContext.GetArrayTypesCache(isMdArray, rank).TryGetValue(elementTypeHandle, out arrayTypeHandle)) return true; - if (!isMdArray && - !RuntimeAugments.IsDynamicType(elementTypeHandle) && - TryGetArrayTypeForNonDynamicElementType(elementTypeHandle, out arrayTypeHandle)) + if (!RuntimeAugments.IsDynamicType(elementTypeHandle) && + TryGetArrayTypeForNonDynamicElementType(elementTypeHandle, isMdArray, rank, out arrayTypeHandle)) { TypeSystemContext.GetArrayTypesCache(isMdArray, rank).AddOrGetExisting(arrayTypeHandle); return true; @@ -416,36 +425,62 @@ internal static bool TryGetArrayTypeForElementType_LookupOnly(RuntimeTypeHandle public bool TryGetPointerTypeForTargetType(RuntimeTypeHandle pointeeTypeHandle, out RuntimeTypeHandle pointerTypeHandle) { - // There are no lookups for pointers in static modules. All pointer EETypes will be created at this level. - // It's possible to have multiple pointer EETypes representing the same pointer type with the same element type - // The caching of pointer types is done at the reflection layer (in the RuntimeTypeUnifier) and - // here in the TypeSystemContext layer - - if (TypeSystemContext.PointerTypesCache.TryGetValue(pointeeTypeHandle, out pointerTypeHandle)) + if (TryGetPointerTypeForTargetType_LookupOnly(pointeeTypeHandle, out pointerTypeHandle)) return true; using (LockHolder.Hold(_typeLoaderLock)) { + if (TypeSystemContext.PointerTypesCache.TryGetValue(pointeeTypeHandle, out pointerTypeHandle)) + return true; + return TypeBuilder.TryBuildPointerType(pointeeTypeHandle, out pointerTypeHandle); } } - public bool TryGetByRefTypeForTargetType(RuntimeTypeHandle pointeeTypeHandle, out RuntimeTypeHandle byRefTypeHandle) + public static bool TryGetPointerTypeForTargetType_LookupOnly(RuntimeTypeHandle pointeeTypeHandle, out RuntimeTypeHandle pointerTypeHandle) { - // There are no lookups for ByRefs in static modules. All ByRef EETypes will be created at this level. - // It's possible to have multiple ByRef EETypes representing the same ByRef type with the same element type - // The caching of ByRef types is done at the reflection layer (in the RuntimeTypeUnifier) and - // here in the TypeSystemContext layer + if (TypeSystemContext.PointerTypesCache.TryGetValue(pointeeTypeHandle, out pointerTypeHandle)) + return true; + + if (!RuntimeAugments.IsDynamicType(pointeeTypeHandle) && + TryGetPointerTypeForNonDynamicElementType(pointeeTypeHandle, out pointerTypeHandle)) + { + TypeSystemContext.PointerTypesCache.AddOrGetExisting(pointerTypeHandle); + return true; + } + + return false; + } - if (TypeSystemContext.ByRefTypesCache.TryGetValue(pointeeTypeHandle, out byRefTypeHandle)) + public bool TryGetByRefTypeForTargetType(RuntimeTypeHandle pointeeTypeHandle, out RuntimeTypeHandle byRefTypeHandle) + { + if (TryGetByRefTypeForTargetType_LookupOnly(pointeeTypeHandle, out byRefTypeHandle)) return true; using (LockHolder.Hold(_typeLoaderLock)) { + if (TypeSystemContext.ByRefTypesCache.TryGetValue(pointeeTypeHandle, out byRefTypeHandle)) + return true; + return TypeBuilder.TryBuildByRefType(pointeeTypeHandle, out byRefTypeHandle); } } + public static bool TryGetByRefTypeForTargetType_LookupOnly(RuntimeTypeHandle pointeeTypeHandle, out RuntimeTypeHandle pointerTypeHandle) + { + if (TypeSystemContext.ByRefTypesCache.TryGetValue(pointeeTypeHandle, out pointerTypeHandle)) + return true; + + if (!RuntimeAugments.IsDynamicType(pointeeTypeHandle) && + TryGetByRefTypeForNonDynamicElementType(pointeeTypeHandle, out pointerTypeHandle)) + { + TypeSystemContext.ByRefTypesCache.AddOrGetExisting(pointerTypeHandle); + return true; + } + + return false; + } + public int GetCanonicalHashCode(RuntimeTypeHandle typeHandle, CanonicalFormKind kind) { TypeSystemContext context = TypeSystemContextFactory.Create(); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs index 1a245457049134..2a43df3eb85027 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs @@ -77,23 +77,16 @@ internal bool RetrieveRuntimeTypeHandleIfPossible() // Generic type. First make sure we have type handles for the arguments, then check // the instantiation. bool argumentsRegistered = true; - bool arrayArgumentsFound = false; for (int i = 0; i < instantiation.Length; i++) { if (!instantiation[i].RetrieveRuntimeTypeHandleIfPossible()) { argumentsRegistered = false; - arrayArgumentsFound = arrayArgumentsFound || (instantiation[i] is ArrayType); } } RuntimeTypeHandle rtth; - - // If at least one of the arguments is not known to the runtime, we take a slower - // path to compare the current type we need a handle for to the list of generic - // types statically available, by loading them as DefTypes and doing a DefType comparaison - if ((argumentsRegistered && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.HandleBasedGenericTypeLookup(typeAsDefType), out rtth)) || - (arrayArgumentsFound && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.DefTypeBasedGenericTypeLookup(typeAsDefType), out rtth))) + if (argumentsRegistered && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.GenericTypeLookupData(typeAsDefType), out rtth)) { typeAsDefType.SetRuntimeTypeHandleUnsafe(rtth); return true; @@ -115,9 +108,9 @@ internal bool RetrieveRuntimeTypeHandleIfPossible() if ((type is ArrayType && TypeLoaderEnvironment.TryGetArrayTypeForElementType_LookupOnly(typeAsParameterType.ParameterType.RuntimeTypeHandle, type.IsMdArray, type.IsMdArray ? ((ArrayType)type).Rank : -1, out rtth)) || - (type is PointerType && TypeSystemContext.PointerTypesCache.TryGetValue(typeAsParameterType.ParameterType.RuntimeTypeHandle, out rtth)) + (type is PointerType && TypeLoaderEnvironment.TryGetPointerTypeForTargetType_LookupOnly(typeAsParameterType.ParameterType.RuntimeTypeHandle, out rtth)) || - (type is ByRefType && TypeSystemContext.ByRefTypesCache.TryGetValue(typeAsParameterType.ParameterType.RuntimeTypeHandle, out rtth))) + (type is ByRefType && TypeLoaderEnvironment.TryGetByRefTypeForTargetType_LookupOnly(typeAsParameterType.ParameterType.RuntimeTypeHandle, out rtth))) { typeAsParameterType.SetRuntimeTypeHandleUnsafe(rtth); return true; @@ -128,6 +121,37 @@ internal bool RetrieveRuntimeTypeHandleIfPossible() { // SignatureVariables do not have RuntimeTypeHandles } + else if (type is FunctionPointerType functionPointerType) + { + MethodSignature sig = functionPointerType.Signature; + if (sig.ReturnType.RetrieveRuntimeTypeHandleIfPossible()) + { + RuntimeTypeHandle[] parameterHandles = new RuntimeTypeHandle[sig.Length]; + bool handlesAvailable = true; + for (int i = 0; i < parameterHandles.Length; i++) + { + if (sig[i].RetrieveRuntimeTypeHandleIfPossible()) + { + parameterHandles[i] = sig[i].RuntimeTypeHandle; + } + else + { + handlesAvailable = false; + break; + } + } + + if (handlesAvailable + && TypeLoaderEnvironment.Instance.TryLookupFunctionPointerTypeForComponents( + sig.ReturnType.RuntimeTypeHandle, parameterHandles, + isUnmanaged: (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) != 0, + out RuntimeTypeHandle rtth)) + { + functionPointerType.SetRuntimeTypeHandleUnsafe(rtth); + return true; + } + } + } else { Debug.Assert(false); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs index 5861acff48ca2e..d37e5a684a4d6c 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs @@ -71,6 +71,65 @@ protected override int GetValueHashCode(RuntimeTypeHandle value) } } + internal readonly struct FunctionPointerTypeKey + { + public readonly RuntimeTypeHandle ReturnType; + public readonly RuntimeTypeHandle[] ParameterTypes; + public readonly bool IsUnmanaged; + public FunctionPointerTypeKey(RuntimeTypeHandle returnType, RuntimeTypeHandle[] parameterTypes, bool isUnmanaged) + => (ReturnType, ParameterTypes, IsUnmanaged) = (returnType, parameterTypes, isUnmanaged); + } + + internal class FunctionPointerRuntimeTypeHandleHashtable : LockFreeReaderHashtableOfPointers + { + protected override bool CompareKeyToValue(FunctionPointerTypeKey key, RuntimeTypeHandle value) + { + if (key.IsUnmanaged != RuntimeAugments.IsUnmanagedFunctionPointerType(value) + || key.ParameterTypes.Length != RuntimeAugments.GetFunctionPointerParameterCount(value) + || !key.ReturnType.Equals(RuntimeAugments.GetFunctionPointerReturnType(value))) + return false; + + for (int i = 0; i < key.ParameterTypes.Length; i++) + if (!key.ParameterTypes[i].Equals(RuntimeAugments.GetFunctionPointerParameterType(value, i))) + return false; + + return true; + } + + protected override bool CompareValueToValue(RuntimeTypeHandle value1, RuntimeTypeHandle value2) + { + return value1.Equals(value2); + } + + protected override RuntimeTypeHandle ConvertIntPtrToValue(IntPtr pointer) + { + unsafe + { + return ((MethodTable*)pointer.ToPointer())->ToRuntimeTypeHandle(); + } + } + + protected override IntPtr ConvertValueToIntPtr(RuntimeTypeHandle value) + { + return value.ToIntPtr(); + } + + protected override RuntimeTypeHandle CreateValueFromKey(FunctionPointerTypeKey key) + { + throw new NotSupportedException(); + } + + protected override int GetKeyHashCode(FunctionPointerTypeKey key) + { + return TypeHashingAlgorithms.ComputeMethodSignatureHashCode(key.ReturnType.GetHashCode(), key.ParameterTypes); + } + + protected override int GetValueHashCode(RuntimeTypeHandle value) + { + return value.GetHashCode(); + } + } + internal static RuntimeTypeHandleToParameterTypeRuntimeTypeHandleHashtable[] s_ArrayTypesCaches = new RuntimeTypeHandleToParameterTypeRuntimeTypeHandleHashtable[MDArray.MaxRank + 1]; /// /// Cache of array types created by the builder to prevent duplication @@ -100,7 +159,10 @@ internal static RuntimeTypeHandleToParameterTypeRuntimeTypeHandleHashtable GetAr internal static RuntimeTypeHandleToParameterTypeRuntimeTypeHandleHashtable ByRefTypesCache { get; } = new RuntimeTypeHandleToParameterTypeRuntimeTypeHandleHashtable(); - private TypeDesc[] ResolveRuntimeTypeHandlesInternal(RuntimeTypeHandle[] runtimeTypeHandles) + internal static FunctionPointerRuntimeTypeHandleHashtable FunctionPointerTypesCache { get; } + = new FunctionPointerRuntimeTypeHandleHashtable(); + + public TypeDesc[] ResolveRuntimeTypeHandlesInternal(RuntimeTypeHandle[] runtimeTypeHandles) { TypeDesc[] TypeDescs = new TypeDesc[runtimeTypeHandles.Length]; for (int i = 0; i < runtimeTypeHandles.Length; i++) @@ -135,7 +197,7 @@ public TypeDesc ResolveRuntimeTypeHandle(RuntimeTypeHandle rtth) { unsafe { - TypeDesc[] genericParameters = new TypeDesc[rtth.ToEETypePtr()->GenericArgumentCount]; + TypeDesc[] genericParameters = new TypeDesc[rtth.ToEETypePtr()->GenericParameterCount]; Runtime.GenericVariance* runtimeVariance = rtth.ToEETypePtr()->HasGenericVariance ? rtth.ToEETypePtr()->GenericVariance : null; for (int i = 0; i < genericParameters.Length; i++) @@ -183,9 +245,9 @@ public TypeDesc ResolveRuntimeTypeHandle(RuntimeTypeHandle rtth) } else if (RuntimeAugments.IsFunctionPointerType(rtth)) { - TypeLoaderEnvironment.Instance.GetFunctionPointerTypeComponents(rtth, out RuntimeTypeHandle returnTypeHandle, - out RuntimeTypeHandle[] parameterHandles, - out bool isUnmanaged); + RuntimeTypeHandle returnTypeHandle = RuntimeAugments.GetFunctionPointerReturnType(rtth); + RuntimeTypeHandle[] parameterHandles = RuntimeAugments.GetFunctionPointerParameterTypes(rtth); + bool isUnmanaged = RuntimeAugments.IsUnmanagedFunctionPointerType(rtth); var sig = new MethodSignature( isUnmanaged ? MethodSignatureFlags.UnmanagedCallingConvention : 0, diff --git a/src/coreclr/nativeaot/docs/compiling.md b/src/coreclr/nativeaot/docs/compiling.md index 5ba64ee6d95881..6949d603c47fbc 100644 --- a/src/coreclr/nativeaot/docs/compiling.md +++ b/src/coreclr/nativeaot/docs/compiling.md @@ -127,3 +127,6 @@ Alpine ```sh apk add cmake openssl-dev openssl-libs-static ``` + +## NixOS +NativeAOT uses native executable `ilc` pulled from nuget, which has special requirements. Docs can be found at https://nixos.wiki/wiki/DotNET#NativeAOT diff --git a/src/coreclr/nativeaot/docs/optimizing.md b/src/coreclr/nativeaot/docs/optimizing.md index c64f49bda44268..9f2c9ae70d12a8 100644 --- a/src/coreclr/nativeaot/docs/optimizing.md +++ b/src/coreclr/nativeaot/docs/optimizing.md @@ -37,12 +37,7 @@ Since `PublishTrimmed` is implied to be true with Native AOT, some framework fea * `false`: this disables generation of stack trace metadata that provides textual names in stack traces. This is for example the text string one gets by calling `Exception.ToString()` on a caught exception. With this option disabled, stack traces will still be generated, but will be based on reflection metadata alone (they might be less complete). ## Options related to code generation -* `Speed`: when generating optimized code, favor code execution speed. -* `Size`: when generating optimized code, favor smaller code size. +* `Speed`: when generating optimized code, favor code execution speed. +* `Size`: when generating optimized code, favor smaller code size. * ``: By default, the compiler targets the minimum instruction set supported by the target OS and architecture. This option allows targeting newer instruction sets for better performance. The native binary will require the instruction sets to be supported by the hardware in order to run. For example, `avx2,bmi2,fma,pclmul,popcnt,aes` will produce binary that takes advantage of instruction sets that are typically present on current Intel and AMD processors. Run `ilc --help` for the full list of available instruction sets. `ilc` can be executed from the NativeAOT package in your local nuget cache e.g. `%USERPROFILE%\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\8.0.0-...\tools\ilc.exe` on Windows or `~/.nuget/packages/runtime.linux-arm64.microsoft.dotnet.ilcompiler/8.0.0-.../tools/ilc` on Linux. -## Special considerations for Linux/macOS - -Debugging symbols (data about your program required for debugging) is by default part of native executable files on Unix-like operating systems. To strip symbols into a separate file (`*.dbg` on Linux and `*.dwarf` on macOS), set `true`. - -No action is needed on Windows since the platform convention is to generate debug information into a separate file (`*.pdb`). diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 92ffa6aad9d7a1..8e085e3cc15ab1 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2284,7 +2284,6 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT { // /* +0x000 */ DWORD ContextFlags; - /* +0x004 */ DWORD Fcsr; // // Integer registers. @@ -2328,6 +2327,7 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT { // // TODO-RISCV64: support the SIMD. ULONGLONG F[32]; + DWORD Fcsr; } CONTEXT, *PCONTEXT, *LPCONTEXT; // diff --git a/src/coreclr/pal/prebuilt/corerror/mscorurt.rc b/src/coreclr/pal/prebuilt/corerror/mscorurt.rc index 6f808d6f8f84d5..a30a45ef680196 100644 --- a/src/coreclr/pal/prebuilt/corerror/mscorurt.rc +++ b/src/coreclr/pal/prebuilt/corerror/mscorurt.rc @@ -147,6 +147,7 @@ BEGIN MSG_FOR_URT_HR(CORPROF_E_NOT_YET_AVAILABLE) "Requested information is not yet available." MSG_FOR_URT_HR(CORPROF_E_TYPE_IS_PARAMETERIZED) "The given type is a generic and cannot be used with this method." MSG_FOR_URT_HR(CORPROF_E_FUNCTION_IS_PARAMETERIZED) "The given function is a generic and cannot be used with this method." + MSG_FOR_URT_HR(CORPROF_E_NOT_GC_OBJECT) "This object belongs to a non-gc heap." MSG_FOR_URT_HR(CORSEC_E_POLICY_EXCEPTION) "PolicyException thrown." MSG_FOR_URT_HR(CORSEC_E_MIN_GRANT_FAIL) "Failed to grant minimum permission requests." MSG_FOR_URT_HR(CORSEC_E_NO_EXEC_PERM) "Failed to grant permission to execute." @@ -288,6 +289,7 @@ BEGIN MSG_FOR_URT_HR(CORDBG_E_MISSING_DEBUGGER_EXPORTS) "The debuggee memory space does not have the expected debugging export table." MSG_FOR_URT_HR(CORDBG_E_DATA_TARGET_ERROR) "Failure when calling a data target method." MSG_FOR_URT_HR(CORDBG_E_UNSUPPORTED_DELEGATE) "The delegate contains a delegate currently not supported by the API." + MSG_FOR_URT_HR(CORDBG_E_ASSEMBLY_UPDATES_APPLIED) "The operation is not supported because assembly updates have been applied." MSG_FOR_URT_HR(PEFMT_E_64BIT) "File is PE32+." MSG_FOR_URT_HR(PEFMT_E_32BIT) "File is PE32" MSG_FOR_URT_HR(CLR_E_BIND_ASSEMBLY_VERSION_TOO_LOW) "The bound assembly has a version that is lower than that of the request." diff --git a/src/coreclr/pal/prebuilt/idl/corprof_i.cpp b/src/coreclr/pal/prebuilt/idl/corprof_i.cpp index dbe77ca5d683ed..61546a47bd2afc 100644 --- a/src/coreclr/pal/prebuilt/idl/corprof_i.cpp +++ b/src/coreclr/pal/prebuilt/idl/corprof_i.cpp @@ -147,6 +147,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo12,0x27b24ccd,0x1cb1,0x47c5,0x96,0xee, MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo13,0x6E6C7EE2,0x0701,0x4EC2,0x9D,0x29,0x2E,0x87,0x33,0xB6,0x69,0x34); +MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo14,0xF460E352,0xD76D,0x4FE9,0x83,0x5F,0xF6,0xAF,0x9D,0x6E,0x86,0x2D); + + MIDL_DEFINE_GUID(IID, IID_ICorProfilerMethodEnum,0xFCCEE788,0x0088,0x454B,0xA8,0x11,0xC9,0x9F,0x29,0x8D,0x19,0x42); diff --git a/src/coreclr/pal/prebuilt/inc/corerror.h b/src/coreclr/pal/prebuilt/inc/corerror.h index 6f0be602583ee1..8b64c945ac9bc8 100644 --- a/src/coreclr/pal/prebuilt/inc/corerror.h +++ b/src/coreclr/pal/prebuilt/inc/corerror.h @@ -214,6 +214,7 @@ #define CORDIAGIPC_E_UNKNOWN_MAGIC EMAKEHR(0x1386) #define CORDIAGIPC_E_UNKNOWN_ERROR EMAKEHR(0x1387) #define CORPROF_E_SUSPENSION_IN_PROGRESS EMAKEHR(0x1388) +#define CORPROF_E_NOT_GC_OBJECT EMAKEHR(0x1389) #define CORSEC_E_POLICY_EXCEPTION EMAKEHR(0x1416) #define CORSEC_E_MIN_GRANT_FAIL EMAKEHR(0x1417) #define CORSEC_E_NO_EXEC_PERM EMAKEHR(0x1418) diff --git a/src/coreclr/pal/prebuilt/inc/corprof.h b/src/coreclr/pal/prebuilt/inc/corprof.h index 05e935661aad74..8023d897de13e3 100644 --- a/src/coreclr/pal/prebuilt/inc/corprof.h +++ b/src/coreclr/pal/prebuilt/inc/corprof.h @@ -3,12 +3,12 @@ /* this ALWAYS GENERATED file contains the definitions for the interfaces */ - /* File created by MIDL compiler version 8.01.0622 */ + /* File created by MIDL compiler version 8.01.0626 */ /* Compiler settings for corprof.idl: - Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0622 + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0626 protocol : dce , ms_ext, c_ext, robust - error checks: allocation ref bounds_check enum stub_data - VC __declspec() decoration level: + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: __declspec(uuid()), __declspec(selectany), __declspec(novtable) DECLSPEC_UUID(), MIDL_INTERFACE() */ @@ -41,230 +41,245 @@ #pragma once #endif -/* Forward Declarations */ +#ifndef DECLSPEC_XFGVIRT +#if _CONTROL_FLOW_GUARD_XFG +#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func)) +#else +#define DECLSPEC_XFGVIRT(base, func) +#endif +#endif + +/* Forward Declarations */ #ifndef __ICorProfilerCallback_FWD_DEFINED__ #define __ICorProfilerCallback_FWD_DEFINED__ typedef interface ICorProfilerCallback ICorProfilerCallback; -#endif /* __ICorProfilerCallback_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback2_FWD_DEFINED__ #define __ICorProfilerCallback2_FWD_DEFINED__ typedef interface ICorProfilerCallback2 ICorProfilerCallback2; -#endif /* __ICorProfilerCallback2_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback2_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback3_FWD_DEFINED__ #define __ICorProfilerCallback3_FWD_DEFINED__ typedef interface ICorProfilerCallback3 ICorProfilerCallback3; -#endif /* __ICorProfilerCallback3_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback3_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback4_FWD_DEFINED__ #define __ICorProfilerCallback4_FWD_DEFINED__ typedef interface ICorProfilerCallback4 ICorProfilerCallback4; -#endif /* __ICorProfilerCallback4_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback4_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback5_FWD_DEFINED__ #define __ICorProfilerCallback5_FWD_DEFINED__ typedef interface ICorProfilerCallback5 ICorProfilerCallback5; -#endif /* __ICorProfilerCallback5_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback5_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback6_FWD_DEFINED__ #define __ICorProfilerCallback6_FWD_DEFINED__ typedef interface ICorProfilerCallback6 ICorProfilerCallback6; -#endif /* __ICorProfilerCallback6_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback6_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback7_FWD_DEFINED__ #define __ICorProfilerCallback7_FWD_DEFINED__ typedef interface ICorProfilerCallback7 ICorProfilerCallback7; -#endif /* __ICorProfilerCallback7_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback7_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback8_FWD_DEFINED__ #define __ICorProfilerCallback8_FWD_DEFINED__ typedef interface ICorProfilerCallback8 ICorProfilerCallback8; -#endif /* __ICorProfilerCallback8_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback8_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback9_FWD_DEFINED__ #define __ICorProfilerCallback9_FWD_DEFINED__ typedef interface ICorProfilerCallback9 ICorProfilerCallback9; -#endif /* __ICorProfilerCallback9_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback9_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback10_FWD_DEFINED__ #define __ICorProfilerCallback10_FWD_DEFINED__ typedef interface ICorProfilerCallback10 ICorProfilerCallback10; -#endif /* __ICorProfilerCallback10_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback10_FWD_DEFINED__ */ #ifndef __ICorProfilerCallback11_FWD_DEFINED__ #define __ICorProfilerCallback11_FWD_DEFINED__ typedef interface ICorProfilerCallback11 ICorProfilerCallback11; -#endif /* __ICorProfilerCallback11_FWD_DEFINED__ */ +#endif /* __ICorProfilerCallback11_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo_FWD_DEFINED__ #define __ICorProfilerInfo_FWD_DEFINED__ typedef interface ICorProfilerInfo ICorProfilerInfo; -#endif /* __ICorProfilerInfo_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo2_FWD_DEFINED__ #define __ICorProfilerInfo2_FWD_DEFINED__ typedef interface ICorProfilerInfo2 ICorProfilerInfo2; -#endif /* __ICorProfilerInfo2_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo2_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo3_FWD_DEFINED__ #define __ICorProfilerInfo3_FWD_DEFINED__ typedef interface ICorProfilerInfo3 ICorProfilerInfo3; -#endif /* __ICorProfilerInfo3_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo3_FWD_DEFINED__ */ #ifndef __ICorProfilerObjectEnum_FWD_DEFINED__ #define __ICorProfilerObjectEnum_FWD_DEFINED__ typedef interface ICorProfilerObjectEnum ICorProfilerObjectEnum; -#endif /* __ICorProfilerObjectEnum_FWD_DEFINED__ */ +#endif /* __ICorProfilerObjectEnum_FWD_DEFINED__ */ #ifndef __ICorProfilerFunctionEnum_FWD_DEFINED__ #define __ICorProfilerFunctionEnum_FWD_DEFINED__ typedef interface ICorProfilerFunctionEnum ICorProfilerFunctionEnum; -#endif /* __ICorProfilerFunctionEnum_FWD_DEFINED__ */ +#endif /* __ICorProfilerFunctionEnum_FWD_DEFINED__ */ #ifndef __ICorProfilerModuleEnum_FWD_DEFINED__ #define __ICorProfilerModuleEnum_FWD_DEFINED__ typedef interface ICorProfilerModuleEnum ICorProfilerModuleEnum; -#endif /* __ICorProfilerModuleEnum_FWD_DEFINED__ */ +#endif /* __ICorProfilerModuleEnum_FWD_DEFINED__ */ #ifndef __IMethodMalloc_FWD_DEFINED__ #define __IMethodMalloc_FWD_DEFINED__ typedef interface IMethodMalloc IMethodMalloc; -#endif /* __IMethodMalloc_FWD_DEFINED__ */ +#endif /* __IMethodMalloc_FWD_DEFINED__ */ #ifndef __ICorProfilerFunctionControl_FWD_DEFINED__ #define __ICorProfilerFunctionControl_FWD_DEFINED__ typedef interface ICorProfilerFunctionControl ICorProfilerFunctionControl; -#endif /* __ICorProfilerFunctionControl_FWD_DEFINED__ */ +#endif /* __ICorProfilerFunctionControl_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo4_FWD_DEFINED__ #define __ICorProfilerInfo4_FWD_DEFINED__ typedef interface ICorProfilerInfo4 ICorProfilerInfo4; -#endif /* __ICorProfilerInfo4_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo4_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo5_FWD_DEFINED__ #define __ICorProfilerInfo5_FWD_DEFINED__ typedef interface ICorProfilerInfo5 ICorProfilerInfo5; -#endif /* __ICorProfilerInfo5_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo5_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo6_FWD_DEFINED__ #define __ICorProfilerInfo6_FWD_DEFINED__ typedef interface ICorProfilerInfo6 ICorProfilerInfo6; -#endif /* __ICorProfilerInfo6_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo6_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo7_FWD_DEFINED__ #define __ICorProfilerInfo7_FWD_DEFINED__ typedef interface ICorProfilerInfo7 ICorProfilerInfo7; -#endif /* __ICorProfilerInfo7_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo7_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo8_FWD_DEFINED__ #define __ICorProfilerInfo8_FWD_DEFINED__ typedef interface ICorProfilerInfo8 ICorProfilerInfo8; -#endif /* __ICorProfilerInfo8_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo8_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo9_FWD_DEFINED__ #define __ICorProfilerInfo9_FWD_DEFINED__ typedef interface ICorProfilerInfo9 ICorProfilerInfo9; -#endif /* __ICorProfilerInfo9_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo9_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo10_FWD_DEFINED__ #define __ICorProfilerInfo10_FWD_DEFINED__ typedef interface ICorProfilerInfo10 ICorProfilerInfo10; -#endif /* __ICorProfilerInfo10_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo10_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo11_FWD_DEFINED__ #define __ICorProfilerInfo11_FWD_DEFINED__ typedef interface ICorProfilerInfo11 ICorProfilerInfo11; -#endif /* __ICorProfilerInfo11_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo11_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo12_FWD_DEFINED__ #define __ICorProfilerInfo12_FWD_DEFINED__ typedef interface ICorProfilerInfo12 ICorProfilerInfo12; -#endif /* __ICorProfilerInfo12_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo12_FWD_DEFINED__ */ #ifndef __ICorProfilerInfo13_FWD_DEFINED__ #define __ICorProfilerInfo13_FWD_DEFINED__ typedef interface ICorProfilerInfo13 ICorProfilerInfo13; -#endif /* __ICorProfilerInfo13_FWD_DEFINED__ */ +#endif /* __ICorProfilerInfo13_FWD_DEFINED__ */ + + +#ifndef __ICorProfilerInfo14_FWD_DEFINED__ +#define __ICorProfilerInfo14_FWD_DEFINED__ +typedef interface ICorProfilerInfo14 ICorProfilerInfo14; + +#endif /* __ICorProfilerInfo14_FWD_DEFINED__ */ #ifndef __ICorProfilerMethodEnum_FWD_DEFINED__ #define __ICorProfilerMethodEnum_FWD_DEFINED__ typedef interface ICorProfilerMethodEnum ICorProfilerMethodEnum; -#endif /* __ICorProfilerMethodEnum_FWD_DEFINED__ */ +#endif /* __ICorProfilerMethodEnum_FWD_DEFINED__ */ #ifndef __ICorProfilerThreadEnum_FWD_DEFINED__ #define __ICorProfilerThreadEnum_FWD_DEFINED__ typedef interface ICorProfilerThreadEnum ICorProfilerThreadEnum; -#endif /* __ICorProfilerThreadEnum_FWD_DEFINED__ */ +#endif /* __ICorProfilerThreadEnum_FWD_DEFINED__ */ #ifndef __ICorProfilerAssemblyReferenceProvider_FWD_DEFINED__ #define __ICorProfilerAssemblyReferenceProvider_FWD_DEFINED__ typedef interface ICorProfilerAssemblyReferenceProvider ICorProfilerAssemblyReferenceProvider; -#endif /* __ICorProfilerAssemblyReferenceProvider_FWD_DEFINED__ */ +#endif /* __ICorProfilerAssemblyReferenceProvider_FWD_DEFINED__ */ /* header files for imported files */ @@ -272,11 +287,11 @@ typedef interface ICorProfilerAssemblyReferenceProvider ICorProfilerAssemblyRefe #ifdef __cplusplus extern "C"{ -#endif +#endif /* interface __MIDL_itf_corprof_0000_0000 */ -/* [local] */ +/* [local] */ #if 0 typedef LONG32 mdToken; @@ -297,7 +312,7 @@ typedef /* [public][public][public][public] */ struct __MIDL___MIDL_itf_corprof_ DWORD dwOSPlatformId; DWORD dwOSMajorVersion; DWORD dwOSMinorVersion; - } OSINFO; + } OSINFO; typedef /* [public][public][public] */ struct __MIDL___MIDL_itf_corprof_0000_0000_0002 { @@ -311,7 +326,7 @@ typedef /* [public][public][public] */ struct __MIDL___MIDL_itf_corprof_0000_000 ULONG ulProcessor; OSINFO *rOS; ULONG ulOS; - } ASSEMBLYMETADATA; + } ASSEMBLYMETADATA; #endif typedef const BYTE *LPCBYTE; @@ -331,25 +346,25 @@ typedef struct _COR_IL_MAP ULONG32 oldOffset; ULONG32 newOffset; BOOL fAccurate; - } COR_IL_MAP; + } COR_IL_MAP; #endif //_COR_IL_MAP #ifndef _COR_DEBUG_IL_TO_NATIVE_MAP_ #define _COR_DEBUG_IL_TO_NATIVE_MAP_ -typedef +typedef enum CorDebugIlToNativeMappingTypes { - NO_MAPPING = -1, - PROLOG = -2, - EPILOG = -3 - } CorDebugIlToNativeMappingTypes; + NO_MAPPING = -1, + PROLOG = -2, + EPILOG = -3 + } CorDebugIlToNativeMappingTypes; typedef struct COR_DEBUG_IL_TO_NATIVE_MAP { ULONG32 ilOffset; ULONG32 nativeStartOffset; ULONG32 nativeEndOffset; - } COR_DEBUG_IL_TO_NATIVE_MAP; + } COR_DEBUG_IL_TO_NATIVE_MAP; #endif // _COR_DEBUG_IL_TO_NATIVE_MAP_ #ifndef _COR_FIELD_OFFSET_ @@ -358,7 +373,7 @@ typedef struct _COR_FIELD_OFFSET { mdFieldDef ridOfField; ULONG ulOffset; - } COR_FIELD_OFFSET; + } COR_FIELD_OFFSET; #endif // _COR_FIELD_OFFSET_ typedef UINT_PTR ProcessID; @@ -389,24 +404,24 @@ typedef /* [public][public][public][public][public][public][public][public][publ { FunctionID functionID; UINT_PTR clientID; - } FunctionIDOrClientID; + } FunctionIDOrClientID; -typedef UINT_PTR __stdcall __stdcall FunctionIDMapper( +typedef UINT_PTR __stdcall __stdcall FunctionIDMapper( FunctionID funcId, BOOL *pbHookFunction); -typedef UINT_PTR __stdcall __stdcall FunctionIDMapper2( +typedef UINT_PTR __stdcall __stdcall FunctionIDMapper2( FunctionID funcId, void *clientData, BOOL *pbHookFunction); -typedef +typedef enum _COR_PRF_SNAPSHOT_INFO { - COR_PRF_SNAPSHOT_DEFAULT = 0, - COR_PRF_SNAPSHOT_REGISTER_CONTEXT = 0x1, - COR_PRF_SNAPSHOT_X86_OPTIMIZED = 0x2 - } COR_PRF_SNAPSHOT_INFO; + COR_PRF_SNAPSHOT_DEFAULT = 0, + COR_PRF_SNAPSHOT_REGISTER_CONTEXT = 0x1, + COR_PRF_SNAPSHOT_X86_OPTIMIZED = 0x2 + } COR_PRF_SNAPSHOT_INFO; typedef UINT_PTR COR_PRF_FRAME_INFO; @@ -414,36 +429,36 @@ typedef struct _COR_PRF_FUNCTION_ARGUMENT_RANGE { UINT_PTR startAddress; ULONG length; - } COR_PRF_FUNCTION_ARGUMENT_RANGE; + } COR_PRF_FUNCTION_ARGUMENT_RANGE; typedef struct _COR_PRF_FUNCTION_ARGUMENT_INFO { ULONG numRanges; ULONG totalArgumentSize; COR_PRF_FUNCTION_ARGUMENT_RANGE ranges[ 1 ]; - } COR_PRF_FUNCTION_ARGUMENT_INFO; + } COR_PRF_FUNCTION_ARGUMENT_INFO; typedef struct _COR_PRF_CODE_INFO { UINT_PTR startAddress; SIZE_T size; - } COR_PRF_CODE_INFO; + } COR_PRF_CODE_INFO; -typedef /* [public][public] */ +typedef /* [public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0004 { - COR_PRF_FIELD_NOT_A_STATIC = 0, - COR_PRF_FIELD_APP_DOMAIN_STATIC = 0x1, - COR_PRF_FIELD_THREAD_STATIC = 0x2, - COR_PRF_FIELD_CONTEXT_STATIC = 0x4, - COR_PRF_FIELD_RVA_STATIC = 0x8 - } COR_PRF_STATIC_TYPE; + COR_PRF_FIELD_NOT_A_STATIC = 0, + COR_PRF_FIELD_APP_DOMAIN_STATIC = 0x1, + COR_PRF_FIELD_THREAD_STATIC = 0x2, + COR_PRF_FIELD_CONTEXT_STATIC = 0x4, + COR_PRF_FIELD_RVA_STATIC = 0x8 + } COR_PRF_STATIC_TYPE; typedef struct _COR_PRF_FUNCTION { FunctionID functionId; ReJITID reJitId; - } COR_PRF_FUNCTION; + } COR_PRF_FUNCTION; typedef struct _COR_PRF_ASSEMBLY_REFERENCE_INFO { @@ -454,62 +469,62 @@ typedef struct _COR_PRF_ASSEMBLY_REFERENCE_INFO void *pbHashValue; ULONG cbHashValue; DWORD dwAssemblyRefFlags; - } COR_PRF_ASSEMBLY_REFERENCE_INFO; + } COR_PRF_ASSEMBLY_REFERENCE_INFO; typedef struct _COR_PRF_METHOD { ModuleID moduleId; mdMethodDef methodId; - } COR_PRF_METHOD; + } COR_PRF_METHOD; -typedef void FunctionEnter( +typedef void FunctionEnter( FunctionID funcID); -typedef void FunctionLeave( +typedef void FunctionLeave( FunctionID funcID); -typedef void FunctionTailcall( +typedef void FunctionTailcall( FunctionID funcID); -typedef void FunctionEnter2( +typedef void FunctionEnter2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func, COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo); -typedef void FunctionLeave2( +typedef void FunctionLeave2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func, COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange); -typedef void FunctionTailcall2( +typedef void FunctionTailcall2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func); -typedef void FunctionEnter3( +typedef void FunctionEnter3( FunctionIDOrClientID functionIDOrClientID); -typedef void FunctionLeave3( +typedef void FunctionLeave3( FunctionIDOrClientID functionIDOrClientID); -typedef void FunctionTailcall3( +typedef void FunctionTailcall3( FunctionIDOrClientID functionIDOrClientID); -typedef void FunctionEnter3WithInfo( +typedef void FunctionEnter3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); -typedef void FunctionLeave3WithInfo( +typedef void FunctionLeave3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); -typedef void FunctionTailcall3WithInfo( +typedef void FunctionTailcall3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); -typedef HRESULT __stdcall __stdcall StackSnapshotCallback( +typedef HRESULT __stdcall __stdcall StackSnapshotCallback( FunctionID funcId, UINT_PTR ip, COR_PRF_FRAME_INFO frameInfo, @@ -517,123 +532,123 @@ typedef HRESULT __stdcall __stdcall StackSnapshotCallback( BYTE context[ ], void *clientData); -typedef BOOL ObjectReferenceCallback( +typedef BOOL ObjectReferenceCallback( ObjectID root, ObjectID *reference, void *clientData); -typedef /* [public] */ +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0005 { - COR_PRF_MONITOR_NONE = 0, - COR_PRF_MONITOR_FUNCTION_UNLOADS = 0x1, - COR_PRF_MONITOR_CLASS_LOADS = 0x2, - COR_PRF_MONITOR_MODULE_LOADS = 0x4, - COR_PRF_MONITOR_ASSEMBLY_LOADS = 0x8, - COR_PRF_MONITOR_APPDOMAIN_LOADS = 0x10, - COR_PRF_MONITOR_JIT_COMPILATION = 0x20, - COR_PRF_MONITOR_EXCEPTIONS = 0x40, - COR_PRF_MONITOR_GC = 0x80, - COR_PRF_MONITOR_OBJECT_ALLOCATED = 0x100, - COR_PRF_MONITOR_THREADS = 0x200, - COR_PRF_MONITOR_REMOTING = 0x400, - COR_PRF_MONITOR_CODE_TRANSITIONS = 0x800, - COR_PRF_MONITOR_ENTERLEAVE = 0x1000, - COR_PRF_MONITOR_CCW = 0x2000, - COR_PRF_MONITOR_REMOTING_COOKIE = ( 0x4000 | COR_PRF_MONITOR_REMOTING ) , - COR_PRF_MONITOR_REMOTING_ASYNC = ( 0x8000 | COR_PRF_MONITOR_REMOTING ) , - COR_PRF_MONITOR_SUSPENDS = 0x10000, - COR_PRF_MONITOR_CACHE_SEARCHES = 0x20000, - COR_PRF_ENABLE_REJIT = 0x40000, - COR_PRF_ENABLE_INPROC_DEBUGGING = 0x80000, - COR_PRF_ENABLE_JIT_MAPS = 0x100000, - COR_PRF_DISABLE_INLINING = 0x200000, - COR_PRF_DISABLE_OPTIMIZATIONS = 0x400000, - COR_PRF_ENABLE_OBJECT_ALLOCATED = 0x800000, - COR_PRF_MONITOR_CLR_EXCEPTIONS = 0x1000000, - COR_PRF_MONITOR_ALL = 0x107ffff, - COR_PRF_ENABLE_FUNCTION_ARGS = 0x2000000, - COR_PRF_ENABLE_FUNCTION_RETVAL = 0x4000000, - COR_PRF_ENABLE_FRAME_INFO = 0x8000000, - COR_PRF_ENABLE_STACK_SNAPSHOT = 0x10000000, - COR_PRF_USE_PROFILE_IMAGES = 0x20000000, - COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST = 0x40000000, - COR_PRF_DISABLE_ALL_NGEN_IMAGES = 0x80000000, - COR_PRF_ALL = 0x8fffffff, - COR_PRF_REQUIRE_PROFILE_IMAGE = ( ( COR_PRF_USE_PROFILE_IMAGES | COR_PRF_MONITOR_CODE_TRANSITIONS ) | COR_PRF_MONITOR_ENTERLEAVE ) , - COR_PRF_ALLOWABLE_AFTER_ATTACH = ( ( ( ( ( ( ( ( ( ( COR_PRF_MONITOR_THREADS | COR_PRF_MONITOR_MODULE_LOADS ) | COR_PRF_MONITOR_ASSEMBLY_LOADS ) | COR_PRF_MONITOR_APPDOMAIN_LOADS ) | COR_PRF_ENABLE_STACK_SNAPSHOT ) | COR_PRF_MONITOR_GC ) | COR_PRF_MONITOR_SUSPENDS ) | COR_PRF_MONITOR_CLASS_LOADS ) | COR_PRF_MONITOR_EXCEPTIONS ) | COR_PRF_MONITOR_JIT_COMPILATION ) | COR_PRF_ENABLE_REJIT ) , - COR_PRF_ALLOWABLE_NOTIFICATION_PROFILER = ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( COR_PRF_MONITOR_FUNCTION_UNLOADS | COR_PRF_MONITOR_CLASS_LOADS ) | COR_PRF_MONITOR_MODULE_LOADS ) | COR_PRF_MONITOR_ASSEMBLY_LOADS ) | COR_PRF_MONITOR_APPDOMAIN_LOADS ) | COR_PRF_MONITOR_JIT_COMPILATION ) | COR_PRF_MONITOR_EXCEPTIONS ) | COR_PRF_MONITOR_OBJECT_ALLOCATED ) | COR_PRF_MONITOR_THREADS ) | COR_PRF_MONITOR_CODE_TRANSITIONS ) | COR_PRF_MONITOR_CCW ) | COR_PRF_MONITOR_SUSPENDS ) | COR_PRF_MONITOR_CACHE_SEARCHES ) | COR_PRF_DISABLE_INLINING ) | COR_PRF_DISABLE_OPTIMIZATIONS ) | COR_PRF_ENABLE_OBJECT_ALLOCATED ) | COR_PRF_MONITOR_CLR_EXCEPTIONS ) | COR_PRF_ENABLE_STACK_SNAPSHOT ) | COR_PRF_USE_PROFILE_IMAGES ) | COR_PRF_DISABLE_ALL_NGEN_IMAGES ) , - COR_PRF_MONITOR_IMMUTABLE = ( ( ( ( ( ( ( ( ( ( ( ( ( ( COR_PRF_MONITOR_CODE_TRANSITIONS | COR_PRF_MONITOR_REMOTING ) | COR_PRF_MONITOR_REMOTING_COOKIE ) | COR_PRF_MONITOR_REMOTING_ASYNC ) | COR_PRF_ENABLE_INPROC_DEBUGGING ) | COR_PRF_ENABLE_JIT_MAPS ) | COR_PRF_DISABLE_OPTIMIZATIONS ) | COR_PRF_DISABLE_INLINING ) | COR_PRF_ENABLE_OBJECT_ALLOCATED ) | COR_PRF_ENABLE_FUNCTION_ARGS ) | COR_PRF_ENABLE_FUNCTION_RETVAL ) | COR_PRF_ENABLE_FRAME_INFO ) | COR_PRF_USE_PROFILE_IMAGES ) | COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST ) | COR_PRF_DISABLE_ALL_NGEN_IMAGES ) - } COR_PRF_MONITOR; - -typedef /* [public] */ + COR_PRF_MONITOR_NONE = 0, + COR_PRF_MONITOR_FUNCTION_UNLOADS = 0x1, + COR_PRF_MONITOR_CLASS_LOADS = 0x2, + COR_PRF_MONITOR_MODULE_LOADS = 0x4, + COR_PRF_MONITOR_ASSEMBLY_LOADS = 0x8, + COR_PRF_MONITOR_APPDOMAIN_LOADS = 0x10, + COR_PRF_MONITOR_JIT_COMPILATION = 0x20, + COR_PRF_MONITOR_EXCEPTIONS = 0x40, + COR_PRF_MONITOR_GC = 0x80, + COR_PRF_MONITOR_OBJECT_ALLOCATED = 0x100, + COR_PRF_MONITOR_THREADS = 0x200, + COR_PRF_MONITOR_REMOTING = 0x400, + COR_PRF_MONITOR_CODE_TRANSITIONS = 0x800, + COR_PRF_MONITOR_ENTERLEAVE = 0x1000, + COR_PRF_MONITOR_CCW = 0x2000, + COR_PRF_MONITOR_REMOTING_COOKIE = ( 0x4000 | COR_PRF_MONITOR_REMOTING ) , + COR_PRF_MONITOR_REMOTING_ASYNC = ( 0x8000 | COR_PRF_MONITOR_REMOTING ) , + COR_PRF_MONITOR_SUSPENDS = 0x10000, + COR_PRF_MONITOR_CACHE_SEARCHES = 0x20000, + COR_PRF_ENABLE_REJIT = 0x40000, + COR_PRF_ENABLE_INPROC_DEBUGGING = 0x80000, + COR_PRF_ENABLE_JIT_MAPS = 0x100000, + COR_PRF_DISABLE_INLINING = 0x200000, + COR_PRF_DISABLE_OPTIMIZATIONS = 0x400000, + COR_PRF_ENABLE_OBJECT_ALLOCATED = 0x800000, + COR_PRF_MONITOR_CLR_EXCEPTIONS = 0x1000000, + COR_PRF_MONITOR_ALL = 0x107ffff, + COR_PRF_ENABLE_FUNCTION_ARGS = 0x2000000, + COR_PRF_ENABLE_FUNCTION_RETVAL = 0x4000000, + COR_PRF_ENABLE_FRAME_INFO = 0x8000000, + COR_PRF_ENABLE_STACK_SNAPSHOT = 0x10000000, + COR_PRF_USE_PROFILE_IMAGES = 0x20000000, + COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST = 0x40000000, + COR_PRF_DISABLE_ALL_NGEN_IMAGES = 0x80000000, + COR_PRF_ALL = 0x8fffffff, + COR_PRF_REQUIRE_PROFILE_IMAGE = ( ( COR_PRF_USE_PROFILE_IMAGES | COR_PRF_MONITOR_CODE_TRANSITIONS ) | COR_PRF_MONITOR_ENTERLEAVE ) , + COR_PRF_ALLOWABLE_AFTER_ATTACH = ( ( ( ( ( ( ( ( ( ( COR_PRF_MONITOR_THREADS | COR_PRF_MONITOR_MODULE_LOADS ) | COR_PRF_MONITOR_ASSEMBLY_LOADS ) | COR_PRF_MONITOR_APPDOMAIN_LOADS ) | COR_PRF_ENABLE_STACK_SNAPSHOT ) | COR_PRF_MONITOR_GC ) | COR_PRF_MONITOR_SUSPENDS ) | COR_PRF_MONITOR_CLASS_LOADS ) | COR_PRF_MONITOR_EXCEPTIONS ) | COR_PRF_MONITOR_JIT_COMPILATION ) | COR_PRF_ENABLE_REJIT ) , + COR_PRF_ALLOWABLE_NOTIFICATION_PROFILER = ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( COR_PRF_MONITOR_FUNCTION_UNLOADS | COR_PRF_MONITOR_CLASS_LOADS ) | COR_PRF_MONITOR_MODULE_LOADS ) | COR_PRF_MONITOR_ASSEMBLY_LOADS ) | COR_PRF_MONITOR_APPDOMAIN_LOADS ) | COR_PRF_MONITOR_JIT_COMPILATION ) | COR_PRF_MONITOR_EXCEPTIONS ) | COR_PRF_MONITOR_OBJECT_ALLOCATED ) | COR_PRF_MONITOR_THREADS ) | COR_PRF_MONITOR_CODE_TRANSITIONS ) | COR_PRF_MONITOR_CCW ) | COR_PRF_MONITOR_SUSPENDS ) | COR_PRF_MONITOR_CACHE_SEARCHES ) | COR_PRF_DISABLE_INLINING ) | COR_PRF_DISABLE_OPTIMIZATIONS ) | COR_PRF_ENABLE_OBJECT_ALLOCATED ) | COR_PRF_MONITOR_CLR_EXCEPTIONS ) | COR_PRF_ENABLE_STACK_SNAPSHOT ) | COR_PRF_USE_PROFILE_IMAGES ) | COR_PRF_DISABLE_ALL_NGEN_IMAGES ) , + COR_PRF_MONITOR_IMMUTABLE = ( ( ( ( ( ( ( ( ( ( ( ( ( ( COR_PRF_MONITOR_CODE_TRANSITIONS | COR_PRF_MONITOR_REMOTING ) | COR_PRF_MONITOR_REMOTING_COOKIE ) | COR_PRF_MONITOR_REMOTING_ASYNC ) | COR_PRF_ENABLE_INPROC_DEBUGGING ) | COR_PRF_ENABLE_JIT_MAPS ) | COR_PRF_DISABLE_OPTIMIZATIONS ) | COR_PRF_DISABLE_INLINING ) | COR_PRF_ENABLE_OBJECT_ALLOCATED ) | COR_PRF_ENABLE_FUNCTION_ARGS ) | COR_PRF_ENABLE_FUNCTION_RETVAL ) | COR_PRF_ENABLE_FRAME_INFO ) | COR_PRF_USE_PROFILE_IMAGES ) | COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST ) | COR_PRF_DISABLE_ALL_NGEN_IMAGES ) + } COR_PRF_MONITOR; + +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0006 { - COR_PRF_HIGH_MONITOR_NONE = 0, - COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES = 0x1, - COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x2, - COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS = 0x4, - COR_PRF_HIGH_DISABLE_TIERED_COMPILATION = 0x8, - COR_PRF_HIGH_BASIC_GC = 0x10, - COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS = 0x20, - COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0, - COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED = 0x40, - COR_PRF_HIGH_MONITOR_EVENT_PIPE = 0x80, - COR_PRF_HIGH_MONITOR_PINNEDOBJECT_ALLOCATED = 0x100, - COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = ( ( ( ( ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) | COR_PRF_HIGH_BASIC_GC ) | COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS ) | COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED ) | COR_PRF_HIGH_MONITOR_EVENT_PIPE ) , - COR_PRF_HIGH_ALLOWABLE_NOTIFICATION_PROFILER = ( ( ( ( ( ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) | COR_PRF_HIGH_DISABLE_TIERED_COMPILATION ) | COR_PRF_HIGH_BASIC_GC ) | COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS ) | COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED ) | COR_PRF_HIGH_MONITOR_EVENT_PIPE ) , - COR_PRF_HIGH_MONITOR_IMMUTABLE = COR_PRF_HIGH_DISABLE_TIERED_COMPILATION - } COR_PRF_HIGH_MONITOR; - -typedef /* [public] */ + COR_PRF_HIGH_MONITOR_NONE = 0, + COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES = 0x1, + COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x2, + COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS = 0x4, + COR_PRF_HIGH_DISABLE_TIERED_COMPILATION = 0x8, + COR_PRF_HIGH_BASIC_GC = 0x10, + COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS = 0x20, + COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0, + COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED = 0x40, + COR_PRF_HIGH_MONITOR_EVENT_PIPE = 0x80, + COR_PRF_HIGH_MONITOR_PINNEDOBJECT_ALLOCATED = 0x100, + COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = ( ( ( ( ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) | COR_PRF_HIGH_BASIC_GC ) | COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS ) | COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED ) | COR_PRF_HIGH_MONITOR_EVENT_PIPE ) , + COR_PRF_HIGH_ALLOWABLE_NOTIFICATION_PROFILER = ( ( ( ( ( ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) | COR_PRF_HIGH_DISABLE_TIERED_COMPILATION ) | COR_PRF_HIGH_BASIC_GC ) | COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS ) | COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED ) | COR_PRF_HIGH_MONITOR_EVENT_PIPE ) , + COR_PRF_HIGH_MONITOR_IMMUTABLE = COR_PRF_HIGH_DISABLE_TIERED_COMPILATION + } COR_PRF_HIGH_MONITOR; + +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0007 { - PROFILER_PARENT_UNKNOWN = 0xfffffffd, - PROFILER_GLOBAL_CLASS = 0xfffffffe, - PROFILER_GLOBAL_MODULE = 0xffffffff - } COR_PRF_MISC; + PROFILER_PARENT_UNKNOWN = 0xfffffffd, + PROFILER_GLOBAL_CLASS = 0xfffffffe, + PROFILER_GLOBAL_MODULE = 0xffffffff + } COR_PRF_MISC; -typedef /* [public][public] */ +typedef /* [public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0008 { - COR_PRF_CACHED_FUNCTION_FOUND = 0, - COR_PRF_CACHED_FUNCTION_NOT_FOUND = ( COR_PRF_CACHED_FUNCTION_FOUND + 1 ) - } COR_PRF_JIT_CACHE; + COR_PRF_CACHED_FUNCTION_FOUND = 0, + COR_PRF_CACHED_FUNCTION_NOT_FOUND = ( COR_PRF_CACHED_FUNCTION_FOUND + 1 ) + } COR_PRF_JIT_CACHE; -typedef /* [public][public][public] */ +typedef /* [public][public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0009 { - COR_PRF_TRANSITION_CALL = 0, - COR_PRF_TRANSITION_RETURN = ( COR_PRF_TRANSITION_CALL + 1 ) - } COR_PRF_TRANSITION_REASON; + COR_PRF_TRANSITION_CALL = 0, + COR_PRF_TRANSITION_RETURN = ( COR_PRF_TRANSITION_CALL + 1 ) + } COR_PRF_TRANSITION_REASON; -typedef /* [public][public] */ +typedef /* [public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0010 { - COR_PRF_SUSPEND_OTHER = 0, - COR_PRF_SUSPEND_FOR_GC = 1, - COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN = 2, - COR_PRF_SUSPEND_FOR_CODE_PITCHING = 3, - COR_PRF_SUSPEND_FOR_SHUTDOWN = 4, - COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER = 6, - COR_PRF_SUSPEND_FOR_GC_PREP = 7, - COR_PRF_SUSPEND_FOR_REJIT = 8, - COR_PRF_SUSPEND_FOR_PROFILER = 9 - } COR_PRF_SUSPEND_REASON; - -typedef /* [public][public] */ + COR_PRF_SUSPEND_OTHER = 0, + COR_PRF_SUSPEND_FOR_GC = 1, + COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN = 2, + COR_PRF_SUSPEND_FOR_CODE_PITCHING = 3, + COR_PRF_SUSPEND_FOR_SHUTDOWN = 4, + COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER = 6, + COR_PRF_SUSPEND_FOR_GC_PREP = 7, + COR_PRF_SUSPEND_FOR_REJIT = 8, + COR_PRF_SUSPEND_FOR_PROFILER = 9 + } COR_PRF_SUSPEND_REASON; + +typedef /* [public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0011 { - COR_PRF_DESKTOP_CLR = 0x1, - COR_PRF_CORE_CLR = 0x2 - } COR_PRF_RUNTIME_TYPE; + COR_PRF_DESKTOP_CLR = 0x1, + COR_PRF_CORE_CLR = 0x2 + } COR_PRF_RUNTIME_TYPE; -typedef /* [public] */ +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0012 { - COR_PRF_REJIT_BLOCK_INLINING = 0x1, - COR_PRF_REJIT_INLINING_CALLBACKS = 0x2 - } COR_PRF_REJIT_FLAGS; + COR_PRF_REJIT_BLOCK_INLINING = 0x1, + COR_PRF_REJIT_INLINING_CALLBACKS = 0x2 + } COR_PRF_REJIT_FLAGS; typedef UINT_PTR EVENTPIPE_PROVIDER; @@ -641,39 +656,39 @@ typedef UINT_PTR EVENTPIPE_EVENT; typedef UINT64 EVENTPIPE_SESSION; -typedef /* [public] */ +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0013 { - COR_PRF_EVENTPIPE_OBJECT = 1, - COR_PRF_EVENTPIPE_BOOLEAN = 3, - COR_PRF_EVENTPIPE_CHAR = 4, - COR_PRF_EVENTPIPE_SBYTE = 5, - COR_PRF_EVENTPIPE_BYTE = 6, - COR_PRF_EVENTPIPE_INT16 = 7, - COR_PRF_EVENTPIPE_UINT16 = 8, - COR_PRF_EVENTPIPE_INT32 = 9, - COR_PRF_EVENTPIPE_UINT32 = 10, - COR_PRF_EVENTPIPE_INT64 = 11, - COR_PRF_EVENTPIPE_UINT64 = 12, - COR_PRF_EVENTPIPE_SINGLE = 13, - COR_PRF_EVENTPIPE_DOUBLE = 14, - COR_PRF_EVENTPIPE_DECIMAL = 15, - COR_PRF_EVENTPIPE_DATETIME = 16, - COR_PRF_EVENTPIPE_GUID = 17, - COR_PRF_EVENTPIPE_STRING = 18, - COR_PRF_EVENTPIPE_ARRAY = 19 - } COR_PRF_EVENTPIPE_PARAM_TYPE; - -typedef /* [public] */ + COR_PRF_EVENTPIPE_OBJECT = 1, + COR_PRF_EVENTPIPE_BOOLEAN = 3, + COR_PRF_EVENTPIPE_CHAR = 4, + COR_PRF_EVENTPIPE_SBYTE = 5, + COR_PRF_EVENTPIPE_BYTE = 6, + COR_PRF_EVENTPIPE_INT16 = 7, + COR_PRF_EVENTPIPE_UINT16 = 8, + COR_PRF_EVENTPIPE_INT32 = 9, + COR_PRF_EVENTPIPE_UINT32 = 10, + COR_PRF_EVENTPIPE_INT64 = 11, + COR_PRF_EVENTPIPE_UINT64 = 12, + COR_PRF_EVENTPIPE_SINGLE = 13, + COR_PRF_EVENTPIPE_DOUBLE = 14, + COR_PRF_EVENTPIPE_DECIMAL = 15, + COR_PRF_EVENTPIPE_DATETIME = 16, + COR_PRF_EVENTPIPE_GUID = 17, + COR_PRF_EVENTPIPE_STRING = 18, + COR_PRF_EVENTPIPE_ARRAY = 19 + } COR_PRF_EVENTPIPE_PARAM_TYPE; + +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0000_0014 { - COR_PRF_EVENTPIPE_LOGALWAYS = 0, - COR_PRF_EVENTPIPE_CRITICAL = 1, - COR_PRF_EVENTPIPE_ERROR = 2, - COR_PRF_EVENTPIPE_WARNING = 3, - COR_PRF_EVENTPIPE_INFORMATIONAL = 4, - COR_PRF_EVENTPIPE_VERBOSE = 5 - } COR_PRF_EVENTPIPE_LEVEL; + COR_PRF_EVENTPIPE_LOGALWAYS = 0, + COR_PRF_EVENTPIPE_CRITICAL = 1, + COR_PRF_EVENTPIPE_ERROR = 2, + COR_PRF_EVENTPIPE_WARNING = 3, + COR_PRF_EVENTPIPE_INFORMATIONAL = 4, + COR_PRF_EVENTPIPE_VERBOSE = 5 + } COR_PRF_EVENTPIPE_LEVEL; typedef /* [public][public][public] */ struct __MIDL___MIDL_itf_corprof_0000_0000_0015 { @@ -681,29 +696,29 @@ typedef /* [public][public][public] */ struct __MIDL___MIDL_itf_corprof_0000_000 UINT64 keywords; UINT32 loggingLevel; const WCHAR *filterData; - } COR_PRF_EVENTPIPE_PROVIDER_CONFIG; + } COR_PRF_EVENTPIPE_PROVIDER_CONFIG; typedef /* [public][public] */ struct __MIDL___MIDL_itf_corprof_0000_0000_0016 { UINT32 type; UINT32 elementType; const WCHAR *name; - } COR_PRF_EVENTPIPE_PARAM_DESC; + } COR_PRF_EVENTPIPE_PARAM_DESC; typedef /* [public][public] */ struct __MIDL___MIDL_itf_corprof_0000_0000_0017 { UINT64 ptr; UINT32 size; UINT32 reserved; - } COR_PRF_EVENT_DATA; + } COR_PRF_EVENT_DATA; -typedef +typedef enum _COR_PRF_HANDLE_TYPE { - COR_PRF_HANDLE_TYPE_WEAK = 0x1, - COR_PRF_HANDLE_TYPE_STRONG = 0x2, - COR_PRF_HANDLE_TYPE_PINNED = 0x3 - } COR_PRF_HANDLE_TYPE; + COR_PRF_HANDLE_TYPE_WEAK = 0x1, + COR_PRF_HANDLE_TYPE_STRONG = 0x2, + COR_PRF_HANDLE_TYPE_PINNED = 0x3 + } COR_PRF_HANDLE_TYPE; typedef void **ObjectHandleID; @@ -723,6 +738,8 @@ typedef void **ObjectHandleID; + + extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0000_v0_0_c_ifspec; extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0000_v0_0_s_ifspec; @@ -730,567 +747,639 @@ extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0000_v0_0_s_ifspec; #define __ICorProfilerCallback_INTERFACE_DEFINED__ /* interface ICorProfilerCallback */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("176FBED1-A55C-4796-98CA-A9DA0EF883E7") ICorProfilerCallback : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Initialize( + virtual HRESULT STDMETHODCALLTYPE Initialize( /* [in] */ IUnknown *pICorProfilerInfoUnk) = 0; - + virtual HRESULT STDMETHODCALLTYPE Shutdown( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE AppDomainCreationStarted( + + virtual HRESULT STDMETHODCALLTYPE AppDomainCreationStarted( /* [in] */ AppDomainID appDomainId) = 0; - - virtual HRESULT STDMETHODCALLTYPE AppDomainCreationFinished( + + virtual HRESULT STDMETHODCALLTYPE AppDomainCreationFinished( /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownStarted( + + virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownStarted( /* [in] */ AppDomainID appDomainId) = 0; - - virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownFinished( + + virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownFinished( /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE AssemblyLoadStarted( + + virtual HRESULT STDMETHODCALLTYPE AssemblyLoadStarted( /* [in] */ AssemblyID assemblyId) = 0; - - virtual HRESULT STDMETHODCALLTYPE AssemblyLoadFinished( + + virtual HRESULT STDMETHODCALLTYPE AssemblyLoadFinished( /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadStarted( + + virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadStarted( /* [in] */ AssemblyID assemblyId) = 0; - - virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadFinished( + + virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadFinished( /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE ModuleLoadStarted( + + virtual HRESULT STDMETHODCALLTYPE ModuleLoadStarted( /* [in] */ ModuleID moduleId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ModuleLoadFinished( + + virtual HRESULT STDMETHODCALLTYPE ModuleLoadFinished( /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE ModuleUnloadStarted( + + virtual HRESULT STDMETHODCALLTYPE ModuleUnloadStarted( /* [in] */ ModuleID moduleId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ModuleUnloadFinished( + + virtual HRESULT STDMETHODCALLTYPE ModuleUnloadFinished( /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE ModuleAttachedToAssembly( + + virtual HRESULT STDMETHODCALLTYPE ModuleAttachedToAssembly( /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClassLoadStarted( + + virtual HRESULT STDMETHODCALLTYPE ClassLoadStarted( /* [in] */ ClassID classId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClassLoadFinished( + + virtual HRESULT STDMETHODCALLTYPE ClassLoadFinished( /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClassUnloadStarted( + + virtual HRESULT STDMETHODCALLTYPE ClassUnloadStarted( /* [in] */ ClassID classId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClassUnloadFinished( + + virtual HRESULT STDMETHODCALLTYPE ClassUnloadFinished( /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE FunctionUnloadStarted( + + virtual HRESULT STDMETHODCALLTYPE FunctionUnloadStarted( /* [in] */ FunctionID functionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE JITCompilationStarted( + + virtual HRESULT STDMETHODCALLTYPE JITCompilationStarted( /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock) = 0; - - virtual HRESULT STDMETHODCALLTYPE JITCompilationFinished( + + virtual HRESULT STDMETHODCALLTYPE JITCompilationFinished( /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock) = 0; - - virtual HRESULT STDMETHODCALLTYPE JITCachedFunctionSearchStarted( + + virtual HRESULT STDMETHODCALLTYPE JITCachedFunctionSearchStarted( /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE JITCachedFunctionSearchFinished( + + virtual HRESULT STDMETHODCALLTYPE JITCachedFunctionSearchFinished( /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result) = 0; - - virtual HRESULT STDMETHODCALLTYPE JITFunctionPitched( + + virtual HRESULT STDMETHODCALLTYPE JITFunctionPitched( /* [in] */ FunctionID functionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE JITInlining( + + virtual HRESULT STDMETHODCALLTYPE JITInlining( /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline) = 0; - - virtual HRESULT STDMETHODCALLTYPE ThreadCreated( + + virtual HRESULT STDMETHODCALLTYPE ThreadCreated( /* [in] */ ThreadID threadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ThreadDestroyed( + + virtual HRESULT STDMETHODCALLTYPE ThreadDestroyed( /* [in] */ ThreadID threadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ThreadAssignedToOSThread( + + virtual HRESULT STDMETHODCALLTYPE ThreadAssignedToOSThread( /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId) = 0; - + virtual HRESULT STDMETHODCALLTYPE RemotingClientInvocationStarted( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE RemotingClientSendingMessage( + + virtual HRESULT STDMETHODCALLTYPE RemotingClientSendingMessage( /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync) = 0; - - virtual HRESULT STDMETHODCALLTYPE RemotingClientReceivingReply( + + virtual HRESULT STDMETHODCALLTYPE RemotingClientReceivingReply( /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync) = 0; - + virtual HRESULT STDMETHODCALLTYPE RemotingClientInvocationFinished( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE RemotingServerReceivingMessage( + + virtual HRESULT STDMETHODCALLTYPE RemotingServerReceivingMessage( /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync) = 0; - + virtual HRESULT STDMETHODCALLTYPE RemotingServerInvocationStarted( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE RemotingServerInvocationReturned( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE RemotingServerSendingReply( + + virtual HRESULT STDMETHODCALLTYPE RemotingServerSendingReply( /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync) = 0; - - virtual HRESULT STDMETHODCALLTYPE UnmanagedToManagedTransition( + + virtual HRESULT STDMETHODCALLTYPE UnmanagedToManagedTransition( /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason) = 0; - - virtual HRESULT STDMETHODCALLTYPE ManagedToUnmanagedTransition( + + virtual HRESULT STDMETHODCALLTYPE ManagedToUnmanagedTransition( /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason) = 0; - - virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendStarted( + + virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendStarted( /* [in] */ COR_PRF_SUSPEND_REASON suspendReason) = 0; - + virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendFinished( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendAborted( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE RuntimeResumeStarted( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE RuntimeResumeFinished( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE RuntimeThreadSuspended( + + virtual HRESULT STDMETHODCALLTYPE RuntimeThreadSuspended( /* [in] */ ThreadID threadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE RuntimeThreadResumed( + + virtual HRESULT STDMETHODCALLTYPE RuntimeThreadResumed( /* [in] */ ThreadID threadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE MovedReferences( + + virtual HRESULT STDMETHODCALLTYPE MovedReferences( /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE ObjectAllocated( + + virtual HRESULT STDMETHODCALLTYPE ObjectAllocated( /* [in] */ ObjectID objectId, /* [in] */ ClassID classId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ObjectsAllocatedByClass( + + virtual HRESULT STDMETHODCALLTYPE ObjectsAllocatedByClass( /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE ObjectReferences( + + virtual HRESULT STDMETHODCALLTYPE ObjectReferences( /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE RootReferences( + + virtual HRESULT STDMETHODCALLTYPE RootReferences( /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionThrown( + + virtual HRESULT STDMETHODCALLTYPE ExceptionThrown( /* [in] */ ObjectID thrownObjectId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFunctionEnter( + + virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFunctionEnter( /* [in] */ FunctionID functionId) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFunctionLeave( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFilterEnter( + + virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFilterEnter( /* [in] */ FunctionID functionId) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFilterLeave( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionSearchCatcherFound( + + virtual HRESULT STDMETHODCALLTYPE ExceptionSearchCatcherFound( /* [in] */ FunctionID functionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionOSHandlerEnter( + + virtual HRESULT STDMETHODCALLTYPE ExceptionOSHandlerEnter( /* [in] */ UINT_PTR __unused) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionOSHandlerLeave( + + virtual HRESULT STDMETHODCALLTYPE ExceptionOSHandlerLeave( /* [in] */ UINT_PTR __unused) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFunctionEnter( + + virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFunctionEnter( /* [in] */ FunctionID functionId) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFunctionLeave( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFinallyEnter( + + virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFinallyEnter( /* [in] */ FunctionID functionId) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFinallyLeave( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionCatcherEnter( + + virtual HRESULT STDMETHODCALLTYPE ExceptionCatcherEnter( /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExceptionCatcherLeave( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE COMClassicVTableCreated( + + virtual HRESULT STDMETHODCALLTYPE COMClassicVTableCreated( /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots) = 0; - - virtual HRESULT STDMETHODCALLTYPE COMClassicVTableDestroyed( + + virtual HRESULT STDMETHODCALLTYPE COMClassicVTableDestroyed( /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExceptionCLRCatcherFound( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExceptionCLRCatcherExecute( void) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallbackVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback * This); - + END_INTERFACE } ICorProfilerCallbackVtbl; @@ -1299,275 +1388,275 @@ EXTERN_C const IID IID_ICorProfilerCallback; CONST_VTBL struct ICorProfilerCallbackVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback_INTERFACE_DEFINED__ */ /* interface __MIDL_itf_corprof_0000_0001 */ -/* [local] */ +/* [local] */ -typedef /* [public][public] */ +typedef /* [public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0001_0001 { - COR_PRF_GC_ROOT_STACK = 1, - COR_PRF_GC_ROOT_FINALIZER = 2, - COR_PRF_GC_ROOT_HANDLE = 3, - COR_PRF_GC_ROOT_OTHER = 0 - } COR_PRF_GC_ROOT_KIND; + COR_PRF_GC_ROOT_STACK = 1, + COR_PRF_GC_ROOT_FINALIZER = 2, + COR_PRF_GC_ROOT_HANDLE = 3, + COR_PRF_GC_ROOT_OTHER = 0 + } COR_PRF_GC_ROOT_KIND; -typedef /* [public][public] */ +typedef /* [public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0001_0002 { - COR_PRF_GC_ROOT_PINNING = 0x1, - COR_PRF_GC_ROOT_WEAKREF = 0x2, - COR_PRF_GC_ROOT_INTERIOR = 0x4, - COR_PRF_GC_ROOT_REFCOUNTED = 0x8 - } COR_PRF_GC_ROOT_FLAGS; + COR_PRF_GC_ROOT_PINNING = 0x1, + COR_PRF_GC_ROOT_WEAKREF = 0x2, + COR_PRF_GC_ROOT_INTERIOR = 0x4, + COR_PRF_GC_ROOT_REFCOUNTED = 0x8 + } COR_PRF_GC_ROOT_FLAGS; -typedef /* [public] */ +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0001_0003 { - COR_PRF_FINALIZER_CRITICAL = 0x1 - } COR_PRF_FINALIZER_FLAGS; + COR_PRF_FINALIZER_CRITICAL = 0x1 + } COR_PRF_FINALIZER_FLAGS; -typedef /* [public][public][public][public] */ +typedef /* [public][public][public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0001_0004 { - COR_PRF_GC_GEN_0 = 0, - COR_PRF_GC_GEN_1 = 1, - COR_PRF_GC_GEN_2 = 2, - COR_PRF_GC_LARGE_OBJECT_HEAP = 3, - COR_PRF_GC_PINNED_OBJECT_HEAP = 4 - } COR_PRF_GC_GENERATION; + COR_PRF_GC_GEN_0 = 0, + COR_PRF_GC_GEN_1 = 1, + COR_PRF_GC_GEN_2 = 2, + COR_PRF_GC_LARGE_OBJECT_HEAP = 3, + COR_PRF_GC_PINNED_OBJECT_HEAP = 4 + } COR_PRF_GC_GENERATION; typedef struct COR_PRF_GC_GENERATION_RANGE { @@ -1575,16 +1664,23 @@ typedef struct COR_PRF_GC_GENERATION_RANGE ObjectID rangeStart; UINT_PTR rangeLength; UINT_PTR rangeLengthReserved; - } COR_PRF_GC_GENERATION_RANGE; + } COR_PRF_GC_GENERATION_RANGE; + +typedef struct COR_PRF_NONGC_HEAP_RANGE + { + ObjectID rangeStart; + UINT_PTR rangeLength; + UINT_PTR rangeLengthReserved; + } COR_PRF_NONGC_HEAP_RANGE; -typedef /* [public][public][public] */ +typedef /* [public][public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0001_0005 { - COR_PRF_CLAUSE_NONE = 0, - COR_PRF_CLAUSE_FILTER = 1, - COR_PRF_CLAUSE_CATCH = 2, - COR_PRF_CLAUSE_FINALLY = 3 - } COR_PRF_CLAUSE_TYPE; + COR_PRF_CLAUSE_NONE = 0, + COR_PRF_CLAUSE_FILTER = 1, + COR_PRF_CLAUSE_CATCH = 2, + COR_PRF_CLAUSE_FINALLY = 3 + } COR_PRF_CLAUSE_TYPE; typedef struct COR_PRF_EX_CLAUSE_INFO { @@ -1592,26 +1688,26 @@ typedef struct COR_PRF_EX_CLAUSE_INFO UINT_PTR programCounter; UINT_PTR framePointer; UINT_PTR shadowStackPointer; - } COR_PRF_EX_CLAUSE_INFO; + } COR_PRF_EX_CLAUSE_INFO; -typedef /* [public][public] */ +typedef /* [public][public] */ enum __MIDL___MIDL_itf_corprof_0000_0001_0006 { - COR_PRF_GC_INDUCED = 1, - COR_PRF_GC_OTHER = 0 - } COR_PRF_GC_REASON; + COR_PRF_GC_INDUCED = 1, + COR_PRF_GC_OTHER = 0 + } COR_PRF_GC_REASON; -typedef /* [public] */ +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0001_0007 { - COR_PRF_MODULE_DISK = 0x1, - COR_PRF_MODULE_NGEN = 0x2, - COR_PRF_MODULE_DYNAMIC = 0x4, - COR_PRF_MODULE_COLLECTIBLE = 0x8, - COR_PRF_MODULE_RESOURCE = 0x10, - COR_PRF_MODULE_FLAT_LAYOUT = 0x20, - COR_PRF_MODULE_WINDOWS_RUNTIME = 0x40 - } COR_PRF_MODULE_FLAGS; + COR_PRF_MODULE_DISK = 0x1, + COR_PRF_MODULE_NGEN = 0x2, + COR_PRF_MODULE_DYNAMIC = 0x4, + COR_PRF_MODULE_COLLECTIBLE = 0x8, + COR_PRF_MODULE_RESOURCE = 0x10, + COR_PRF_MODULE_FLAT_LAYOUT = 0x20, + COR_PRF_MODULE_WINDOWS_RUNTIME = 0x40 + } COR_PRF_MODULE_FLAGS; @@ -1622,417 +1718,497 @@ extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0001_v0_0_s_ifspec; #define __ICorProfilerCallback2_INTERFACE_DEFINED__ /* interface ICorProfilerCallback2 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("8A8CC829-CCF2-49fe-BBAE-0F022228071A") ICorProfilerCallback2 : public ICorProfilerCallback { public: - virtual HRESULT STDMETHODCALLTYPE ThreadNameChanged( + virtual HRESULT STDMETHODCALLTYPE ThreadNameChanged( /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GarbageCollectionStarted( + + virtual HRESULT STDMETHODCALLTYPE GarbageCollectionStarted( /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason) = 0; - - virtual HRESULT STDMETHODCALLTYPE SurvivingReferences( + + virtual HRESULT STDMETHODCALLTYPE SurvivingReferences( /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]) = 0; - + virtual HRESULT STDMETHODCALLTYPE GarbageCollectionFinished( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinalizeableObjectQueued( + + virtual HRESULT STDMETHODCALLTYPE FinalizeableObjectQueued( /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID) = 0; - - virtual HRESULT STDMETHODCALLTYPE RootReferences2( + + virtual HRESULT STDMETHODCALLTYPE RootReferences2( /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE HandleCreated( + + virtual HRESULT STDMETHODCALLTYPE HandleCreated( /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId) = 0; - - virtual HRESULT STDMETHODCALLTYPE HandleDestroyed( + + virtual HRESULT STDMETHODCALLTYPE HandleDestroyed( /* [in] */ GCHandleID handleId) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback2Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback2 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback2 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback2 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback2 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback2 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback2 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback2 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback2 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback2 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback2 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback2 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback2 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback2 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback2 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback2 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback2 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback2 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback2 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback2 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback2 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback2 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback2 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback2 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback2 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback2 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback2 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback2 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback2 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback2 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback2 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback2 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback2 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback2 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback2 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback2 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback2 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback2 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback2 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback2 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback2 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback2 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback2 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback2 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback2 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback2 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback2 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback2 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback2 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback2 * This, /* [in] */ GCHandleID handleId); - + END_INTERFACE } ICorProfilerCallback2Vtbl; @@ -2041,664 +2217,747 @@ EXTERN_C const IID IID_ICorProfilerCallback2; CONST_VTBL struct ICorProfilerCallback2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback2_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback2_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback2_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback2_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback2_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback2_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback2_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback2_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback2_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback2_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback2_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback2_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback2_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback2_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback2_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback2_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback2_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback2_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback2_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback2_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback2_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback2_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback2_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback2_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback2_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback2_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback2_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback2_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback2_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback2_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback2_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback2_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback2_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback2_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback2_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback2_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback2_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback2_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback2_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback2_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback2_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback2_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback2_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback2_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback2_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback2_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback2_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback2_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback2_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback2_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback2_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback2_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback2_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback2_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback2_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback2_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback2_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback2_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback2_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback2_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback2_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback2_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback2_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback2_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback2_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback2_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback2_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback2_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback2_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback2_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback2_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback2_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback2_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback2_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback2_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback2_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback2_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback2_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback2_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback2_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback2_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback2_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback2_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback2_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback2_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback2_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback2_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback2_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback2_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback2_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback2_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback2_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback2_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback2_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback2_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback2_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback2_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback2_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback2_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback2_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback2_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback2_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback2_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback2_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback2_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback2_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback2_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback2_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback2_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback2_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback2_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback2_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback2_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback2_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback2_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback2_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback2_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback2_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback2_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback2_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback2_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback2_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback2_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback2_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback2_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback2_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback2_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback2_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback2_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback2_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback2_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback2_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback2_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback2_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback2_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback2_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback2_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback2_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback2_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback2_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback2_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback2_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback2_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback2_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback2_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback2_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback2_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback2_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback2_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback2_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback2_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback2_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback2_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback2_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback2_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback2_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback3_INTERFACE_DEFINED__ #define __ICorProfilerCallback3_INTERFACE_DEFINED__ /* interface ICorProfilerCallback3 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("4FD2ED52-7731-4b8d-9469-03D2CC3086C5") ICorProfilerCallback3 : public ICorProfilerCallback2 { public: - virtual HRESULT STDMETHODCALLTYPE InitializeForAttach( + virtual HRESULT STDMETHODCALLTYPE InitializeForAttach( /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData) = 0; - + virtual HRESULT STDMETHODCALLTYPE ProfilerAttachComplete( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE ProfilerDetachSucceeded( void) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback3Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback3 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback3 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback3 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback3 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback3 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback3 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback3 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback3 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback3 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback3 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback3 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback3 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback3 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback3 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback3 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback3 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback3 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback3 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback3 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback3 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback3 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback3 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback3 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback3 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback3 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback3 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback3 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback3 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback3 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback3 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback3 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback3 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback3 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback3 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback3 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback3 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback3 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback3 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback3 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback3 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback3 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback3 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback3 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback3 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback3 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback3 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback3 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback3 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback3 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback3 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback3 * This); - + END_INTERFACE } ICorProfilerCallback3Vtbl; @@ -2707,737 +2966,826 @@ EXTERN_C const IID IID_ICorProfilerCallback3; CONST_VTBL struct ICorProfilerCallback3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback3_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback3_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback3_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback3_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback3_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback3_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback3_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback3_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback3_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback3_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback3_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback3_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback3_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback3_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback3_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback3_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback3_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback3_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback3_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback3_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback3_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback3_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback3_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback3_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback3_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback3_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback3_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback3_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback3_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback3_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback3_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback3_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback3_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback3_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback3_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback3_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback3_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback3_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback3_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback3_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback3_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback3_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback3_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback3_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback3_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback3_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback3_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback3_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback3_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback3_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback3_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback3_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback3_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback3_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback3_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback3_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback3_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback3_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback3_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback3_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback3_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback3_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback3_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback3_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback3_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback3_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback3_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback3_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback3_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback3_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback3_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback3_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback3_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback3_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback3_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback3_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback3_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback3_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback3_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback3_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback3_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback3_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback3_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback3_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback3_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback3_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback3_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback3_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback3_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback3_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback3_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback3_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback3_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback3_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback3_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback3_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback3_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback3_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback3_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback3_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback3_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback3_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback3_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback3_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback3_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback3_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback3_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback3_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback3_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback3_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback3_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback3_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback3_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback3_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback3_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback3_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback3_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback3_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback3_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback3_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback3_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback3_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback3_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback3_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback3_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback3_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback3_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback3_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback3_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback3_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback3_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback3_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback3_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback3_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback3_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback3_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback3_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback3_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback3_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback3_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback3_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback3_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback3_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback3_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback3_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback3_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback3_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback3_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback3_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback3_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback3_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback3_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback3_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback3_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback3_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback3_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback3_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback3_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback3_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback3_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback3_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback3_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback4_INTERFACE_DEFINED__ #define __ICorProfilerCallback4_INTERFACE_DEFINED__ /* interface ICorProfilerCallback4 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("7B63B2E3-107D-4d48-B2F6-F61E229470D2") ICorProfilerCallback4 : public ICorProfilerCallback3 { public: - virtual HRESULT STDMETHODCALLTYPE ReJITCompilationStarted( + virtual HRESULT STDMETHODCALLTYPE ReJITCompilationStarted( /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetReJITParameters( + + virtual HRESULT STDMETHODCALLTYPE GetReJITParameters( /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl) = 0; - - virtual HRESULT STDMETHODCALLTYPE ReJITCompilationFinished( + + virtual HRESULT STDMETHODCALLTYPE ReJITCompilationFinished( /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock) = 0; - - virtual HRESULT STDMETHODCALLTYPE ReJITError( + + virtual HRESULT STDMETHODCALLTYPE ReJITError( /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus) = 0; - - virtual HRESULT STDMETHODCALLTYPE MovedReferences2( + + virtual HRESULT STDMETHODCALLTYPE MovedReferences2( /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SurvivingReferences2( + + virtual HRESULT STDMETHODCALLTYPE SurvivingReferences2( /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback4Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback4 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback4 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback4 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback4 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback4 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback4 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback4 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback4 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback4 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback4 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback4 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback4 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback4 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback4 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback4 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback4 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback4 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback4 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback4 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback4 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback4 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback4 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback4 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback4 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback4 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback4 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback4 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback4 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback4 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback4 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback4 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback4 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback4 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback4 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback4 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback4 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback4 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback4 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback4 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback4 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback4 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback4 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback4 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback4 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback4 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback4 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback4 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback4 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback4 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback4 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback4 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback4 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback4 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback4 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - + END_INTERFACE } ICorProfilerCallback4Vtbl; @@ -3446,736 +3794,826 @@ EXTERN_C const IID IID_ICorProfilerCallback4; CONST_VTBL struct ICorProfilerCallback4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback4_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback4_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback4_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback4_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback4_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback4_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback4_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback4_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback4_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback4_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback4_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback4_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback4_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback4_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback4_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback4_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback4_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback4_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback4_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback4_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback4_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback4_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback4_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback4_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback4_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback4_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback4_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback4_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback4_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback4_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback4_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback4_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback4_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback4_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback4_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback4_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback4_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback4_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback4_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback4_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback4_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback4_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback4_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback4_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback4_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback4_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback4_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback4_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback4_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback4_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback4_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback4_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback4_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback4_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback4_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback4_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback4_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback4_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback4_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback4_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback4_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback4_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback4_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback4_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback4_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback4_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback4_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback4_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback4_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback4_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback4_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback4_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback4_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback4_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback4_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback4_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback4_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback4_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback4_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback4_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback4_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback4_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback4_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback4_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback4_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback4_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback4_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback4_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback4_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback4_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback4_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback4_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback4_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback4_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback4_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback4_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback4_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback4_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback4_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback4_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback4_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback4_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback4_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback4_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback4_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback4_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback4_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback4_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback4_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback4_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback4_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback4_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback4_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback4_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback4_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback4_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback4_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback4_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback4_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback4_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback4_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback4_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback4_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback4_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback4_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback4_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback4_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback4_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback4_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback4_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback4_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback4_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback4_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback4_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback4_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback4_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback4_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback4_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback4_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback4_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback4_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback4_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback4_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback4_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback4_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback4_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback4_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback4_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback4_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback4_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback4_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback4_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback4_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback4_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback4_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback4_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback4_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback4_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback4_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback4_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback4_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback4_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback4_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback4_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback4_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback4_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback4_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback4_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback4_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback4_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback4_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback4_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback4_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback4_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback5_INTERFACE_DEFINED__ #define __ICorProfilerCallback5_INTERFACE_DEFINED__ /* interface ICorProfilerCallback5 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback5; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("8DFBA405-8C9F-45F8-BFFA-83B14CEF78B5") ICorProfilerCallback5 : public ICorProfilerCallback4 { public: - virtual HRESULT STDMETHODCALLTYPE ConditionalWeakTableElementReferences( + virtual HRESULT STDMETHODCALLTYPE ConditionalWeakTableElementReferences( /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback5Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback5 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback5 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback5 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback5 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback5 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback5 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback5 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback5 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback5 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback5 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback5 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback5 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback5 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback5 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback5 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback5 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback5 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback5 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback5 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback5 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback5 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback5 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback5 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback5 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback5 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback5 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback5 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback5 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback5 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback5 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback5 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback5 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback5 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback5 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback5 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback5 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback5 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback5 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback5 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback5 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback5 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback5 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback5 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback5 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback5 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback5 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback5 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback5 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback5 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback5 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback5 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback5 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback5 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback5 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback5 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback5, ConditionalWeakTableElementReferences) + HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( ICorProfilerCallback5 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]); - + END_INTERFACE } ICorProfilerCallback5Vtbl; @@ -4184,743 +4622,834 @@ EXTERN_C const IID IID_ICorProfilerCallback5; CONST_VTBL struct ICorProfilerCallback5Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback5_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback5_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback5_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback5_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback5_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback5_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback5_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback5_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback5_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback5_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback5_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback5_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback5_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback5_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback5_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback5_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback5_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback5_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback5_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback5_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback5_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback5_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback5_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback5_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback5_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback5_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback5_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback5_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback5_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback5_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback5_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback5_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback5_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback5_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback5_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback5_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback5_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback5_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback5_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback5_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback5_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback5_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback5_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback5_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback5_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback5_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback5_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback5_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback5_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback5_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback5_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback5_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback5_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback5_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback5_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback5_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback5_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback5_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback5_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback5_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback5_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback5_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback5_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback5_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback5_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback5_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback5_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback5_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback5_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback5_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback5_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback5_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback5_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback5_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback5_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback5_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback5_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback5_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback5_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback5_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback5_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback5_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback5_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback5_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback5_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback5_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback5_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback5_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback5_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback5_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback5_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback5_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback5_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback5_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback5_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback5_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback5_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback5_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback5_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback5_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback5_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback5_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback5_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback5_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback5_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback5_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback5_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback5_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback5_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback5_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback5_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback5_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback5_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback5_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback5_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback5_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback5_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback5_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback5_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback5_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback5_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback5_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback5_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback5_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback5_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback5_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback5_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback5_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback5_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback5_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback5_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback5_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback5_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback5_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback5_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback5_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback5_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback5_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback5_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback5_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback5_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback5_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback5_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback5_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback5_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback5_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback5_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback5_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback5_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback5_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback5_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback5_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback5_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback5_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback5_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback5_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback5_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback5_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback5_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback5_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback5_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback5_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback5_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback5_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback5_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback5_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback5_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback5_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback5_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback5_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback5_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback5_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback5_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback5_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback5_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback5_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback5_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback5_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback5_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ - ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) +#define ICorProfilerCallback5_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ + ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback5_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback5_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback6_INTERFACE_DEFINED__ #define __ICorProfilerCallback6_INTERFACE_DEFINED__ /* interface ICorProfilerCallback6 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback6; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("FC13DF4B-4448-4F4F-950C-BA8D19D00C36") ICorProfilerCallback6 : public ICorProfilerCallback5 { public: - virtual HRESULT STDMETHODCALLTYPE GetAssemblyReferences( + virtual HRESULT STDMETHODCALLTYPE GetAssemblyReferences( /* [string][in] */ const WCHAR *wszAssemblyPath, /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback6Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback6 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback6 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback6 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback6 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback6 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback6 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback6 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback6 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback6 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback6 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback6 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback6 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback6 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback6 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback6 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback6 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback6 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback6 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback6 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback6 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback6 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback6 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback6 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback6 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback6 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback6 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback6 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback6 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback6 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback6 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback6 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback6 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback6 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback6 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback6 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback6 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback6 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback6 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback6 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback6 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback6 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback6 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback6 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback6 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback6 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback6 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback6 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback6 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback6 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback6 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback6 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback6 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback6 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback6 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback6 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback5, ConditionalWeakTableElementReferences) + HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( ICorProfilerCallback6 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback6, GetAssemblyReferences) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( ICorProfilerCallback6 * This, /* [string][in] */ const WCHAR *wszAssemblyPath, /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider); - + END_INTERFACE } ICorProfilerCallback6Vtbl; @@ -4929,750 +5458,842 @@ EXTERN_C const IID IID_ICorProfilerCallback6; CONST_VTBL struct ICorProfilerCallback6Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback6_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback6_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback6_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback6_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback6_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback6_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback6_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback6_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback6_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback6_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback6_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback6_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback6_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback6_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback6_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback6_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback6_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback6_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback6_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback6_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback6_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback6_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback6_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback6_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback6_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback6_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback6_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback6_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback6_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback6_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback6_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback6_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback6_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback6_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback6_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback6_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback6_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback6_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback6_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback6_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback6_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback6_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback6_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback6_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback6_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback6_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback6_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback6_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback6_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback6_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback6_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback6_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback6_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback6_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback6_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback6_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback6_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback6_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback6_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback6_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback6_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback6_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback6_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback6_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback6_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback6_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback6_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback6_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback6_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback6_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback6_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback6_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback6_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback6_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback6_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback6_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback6_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback6_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback6_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback6_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback6_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback6_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback6_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback6_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback6_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback6_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback6_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback6_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback6_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback6_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback6_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback6_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback6_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback6_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback6_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback6_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback6_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback6_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback6_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback6_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback6_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback6_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback6_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback6_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback6_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback6_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback6_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback6_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback6_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback6_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback6_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback6_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback6_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback6_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback6_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback6_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback6_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback6_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback6_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback6_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback6_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback6_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback6_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback6_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback6_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback6_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback6_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback6_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback6_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback6_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback6_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback6_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback6_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback6_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback6_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback6_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback6_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback6_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback6_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback6_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback6_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback6_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback6_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback6_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback6_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback6_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback6_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback6_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback6_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback6_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback6_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback6_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback6_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback6_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback6_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback6_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback6_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback6_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback6_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback6_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback6_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback6_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback6_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback6_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback6_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback6_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback6_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback6_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback6_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback6_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback6_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback6_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback6_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback6_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback6_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback6_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback6_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback6_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback6_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ - ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) +#define ICorProfilerCallback6_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ + ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) -#define ICorProfilerCallback6_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ - ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) +#define ICorProfilerCallback6_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ + ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback6_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback6_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback7_INTERFACE_DEFINED__ #define __ICorProfilerCallback7_INTERFACE_DEFINED__ /* interface ICorProfilerCallback7 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback7; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F76A2DBA-1D52-4539-866C-2AA518F9EFC3") ICorProfilerCallback7 : public ICorProfilerCallback6 { public: - virtual HRESULT STDMETHODCALLTYPE ModuleInMemorySymbolsUpdated( + virtual HRESULT STDMETHODCALLTYPE ModuleInMemorySymbolsUpdated( ModuleID moduleId) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback7Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback7 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback7 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback7 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback7 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback7 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback7 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback7 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback7 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback7 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback7 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback7 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback7 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback7 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback7 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback7 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback7 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback7 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback7 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback7 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback7 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback7 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback7 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback7 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback7 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback7 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback7 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback7 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback7 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback7 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback7 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback7 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback7 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback7 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback7 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback7 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback7 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback7 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback7 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback7 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback7 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback7 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback7 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback7 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback7 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback7 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback7 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback7 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback7 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback7 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback7 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback7 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback7 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback7 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback7 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback7 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback5, ConditionalWeakTableElementReferences) + HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( ICorProfilerCallback7 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback6, GetAssemblyReferences) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( ICorProfilerCallback7 * This, /* [string][in] */ const WCHAR *wszAssemblyPath, /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider); - - HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback7, ModuleInMemorySymbolsUpdated) + HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( ICorProfilerCallback7 * This, ModuleID moduleId); - + END_INTERFACE } ICorProfilerCallback7Vtbl; @@ -5681,775 +6302,869 @@ EXTERN_C const IID IID_ICorProfilerCallback7; CONST_VTBL struct ICorProfilerCallback7Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback7_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback7_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback7_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback7_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback7_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback7_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback7_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback7_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback7_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback7_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback7_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback7_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback7_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback7_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback7_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback7_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback7_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback7_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback7_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback7_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback7_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback7_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback7_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback7_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback7_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback7_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback7_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback7_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback7_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback7_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback7_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback7_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback7_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback7_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback7_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback7_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback7_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback7_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback7_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback7_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback7_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback7_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback7_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback7_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback7_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback7_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback7_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback7_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback7_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback7_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback7_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback7_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback7_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback7_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback7_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback7_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback7_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback7_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback7_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback7_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback7_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback7_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback7_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback7_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback7_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback7_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback7_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback7_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback7_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback7_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback7_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback7_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback7_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback7_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback7_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback7_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback7_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback7_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback7_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback7_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback7_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback7_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback7_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback7_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback7_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback7_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback7_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback7_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback7_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback7_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback7_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback7_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback7_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback7_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback7_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback7_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback7_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback7_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback7_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback7_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback7_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback7_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback7_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback7_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback7_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback7_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback7_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback7_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback7_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback7_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback7_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback7_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback7_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback7_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback7_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback7_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback7_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback7_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback7_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback7_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback7_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback7_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback7_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback7_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback7_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback7_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback7_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback7_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback7_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback7_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback7_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback7_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback7_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback7_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback7_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback7_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback7_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback7_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback7_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback7_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback7_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback7_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback7_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback7_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback7_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback7_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback7_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback7_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback7_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback7_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback7_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback7_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback7_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback7_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback7_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback7_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback7_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback7_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback7_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback7_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback7_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback7_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback7_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback7_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback7_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback7_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback7_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback7_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback7_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback7_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback7_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback7_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback7_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback7_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback7_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback7_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback7_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback7_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback7_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ - ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) +#define ICorProfilerCallback7_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ + ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) -#define ICorProfilerCallback7_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ - ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) +#define ICorProfilerCallback7_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ + ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) -#define ICorProfilerCallback7_ModuleInMemorySymbolsUpdated(This,moduleId) \ - ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) +#define ICorProfilerCallback7_ModuleInMemorySymbolsUpdated(This,moduleId) \ + ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback7_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback7_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback8_INTERFACE_DEFINED__ #define __ICorProfilerCallback8_INTERFACE_DEFINED__ /* interface ICorProfilerCallback8 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback8; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("5BED9B15-C079-4D47-BFE2-215A140C07E0") ICorProfilerCallback8 : public ICorProfilerCallback7 { public: - virtual HRESULT STDMETHODCALLTYPE DynamicMethodJITCompilationStarted( + virtual HRESULT STDMETHODCALLTYPE DynamicMethodJITCompilationStarted( /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock, /* [in] */ LPCBYTE pILHeader, /* [in] */ ULONG cbILHeader) = 0; - - virtual HRESULT STDMETHODCALLTYPE DynamicMethodJITCompilationFinished( + + virtual HRESULT STDMETHODCALLTYPE DynamicMethodJITCompilationFinished( /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback8Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback8 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback8 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback8 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback8 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback8 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback8 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback8 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback8 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback8 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback8 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback8 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback8 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback8 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback8 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback8 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback8 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback8 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback8 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback8 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback8 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback8 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback8 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback8 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback8 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback8 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback8 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback8 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback8 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback8 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback8 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback8 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback8 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback8 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback8 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback8 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback8 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback8 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback8 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback8 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback8 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback8 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback8 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback8 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback8 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback8 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback8 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback8 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback8 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback8 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback8 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback8 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback8 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback8 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback8 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback5, ConditionalWeakTableElementReferences) + HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( ICorProfilerCallback8 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback6, GetAssemblyReferences) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( ICorProfilerCallback8 * This, /* [string][in] */ const WCHAR *wszAssemblyPath, /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider); - - HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback7, ModuleInMemorySymbolsUpdated) + HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( ICorProfilerCallback8 * This, ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock, /* [in] */ LPCBYTE pILHeader, /* [in] */ ULONG cbILHeader); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( ICorProfilerCallback8 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - + END_INTERFACE } ICorProfilerCallback8Vtbl; @@ -6458,778 +7173,873 @@ EXTERN_C const IID IID_ICorProfilerCallback8; CONST_VTBL struct ICorProfilerCallback8Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback8_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback8_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback8_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback8_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback8_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback8_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback8_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback8_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback8_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback8_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback8_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback8_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback8_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback8_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback8_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback8_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback8_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback8_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback8_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback8_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback8_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback8_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback8_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback8_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback8_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback8_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback8_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback8_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback8_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback8_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback8_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback8_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback8_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback8_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback8_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback8_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback8_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback8_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback8_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback8_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback8_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback8_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback8_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback8_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback8_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback8_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback8_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback8_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback8_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback8_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback8_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback8_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback8_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback8_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback8_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback8_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback8_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback8_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback8_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback8_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback8_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback8_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback8_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback8_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback8_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback8_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback8_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback8_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback8_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback8_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback8_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback8_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback8_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback8_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback8_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback8_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback8_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback8_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback8_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback8_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback8_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback8_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback8_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback8_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback8_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback8_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback8_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback8_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback8_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback8_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback8_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback8_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback8_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback8_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback8_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback8_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback8_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback8_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback8_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback8_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback8_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback8_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback8_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback8_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback8_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback8_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback8_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback8_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback8_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback8_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback8_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback8_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback8_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback8_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback8_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback8_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback8_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback8_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback8_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback8_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback8_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback8_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback8_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback8_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback8_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback8_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback8_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback8_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback8_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback8_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback8_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback8_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback8_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback8_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback8_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback8_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback8_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback8_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback8_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback8_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback8_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback8_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback8_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback8_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback8_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback8_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback8_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback8_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback8_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback8_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback8_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback8_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback8_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback8_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback8_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback8_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback8_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback8_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback8_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback8_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback8_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback8_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback8_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback8_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback8_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback8_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback8_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback8_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback8_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback8_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback8_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback8_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback8_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback8_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback8_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback8_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback8_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback8_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback8_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ - ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) +#define ICorProfilerCallback8_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ + ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) -#define ICorProfilerCallback8_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ - ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) +#define ICorProfilerCallback8_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ + ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) -#define ICorProfilerCallback8_ModuleInMemorySymbolsUpdated(This,moduleId) \ - ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) +#define ICorProfilerCallback8_ModuleInMemorySymbolsUpdated(This,moduleId) \ + ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) -#define ICorProfilerCallback8_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) +#define ICorProfilerCallback8_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) -#define ICorProfilerCallback8_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback8_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback8_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback8_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback9_INTERFACE_DEFINED__ #define __ICorProfilerCallback9_INTERFACE_DEFINED__ /* interface ICorProfilerCallback9 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback9; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("27583EC3-C8F5-482F-8052-194B8CE4705A") ICorProfilerCallback9 : public ICorProfilerCallback8 { public: - virtual HRESULT STDMETHODCALLTYPE DynamicMethodUnloaded( + virtual HRESULT STDMETHODCALLTYPE DynamicMethodUnloaded( /* [in] */ FunctionID functionId) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback9Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback9 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback9 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback9 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback9 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback9 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback9 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback9 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback9 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback9 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback9 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback9 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback9 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback9 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback9 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback9 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback9 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback9 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback9 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback9 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback9 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback9 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback9 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback9 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback9 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback9 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback9 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback9 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback9 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback9 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback9 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback9 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback9 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback9 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback9 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback9 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback9 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback9 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback9 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback9 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback9 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback9 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback9 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback9 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback9 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback9 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback9 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback9 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback9 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback9 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback9 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback9 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback9 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback9 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback9 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback5, ConditionalWeakTableElementReferences) + HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( ICorProfilerCallback9 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback6, GetAssemblyReferences) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( ICorProfilerCallback9 * This, /* [string][in] */ const WCHAR *wszAssemblyPath, /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider); - - HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback7, ModuleInMemorySymbolsUpdated) + HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( ICorProfilerCallback9 * This, ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock, /* [in] */ LPCBYTE pILHeader, /* [in] */ ULONG cbILHeader); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodUnloaded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback9, DynamicMethodUnloaded) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodUnloaded )( ICorProfilerCallback9 * This, /* [in] */ FunctionID functionId); - + END_INTERFACE } ICorProfilerCallback9Vtbl; @@ -7238,332 +8048,332 @@ EXTERN_C const IID IID_ICorProfilerCallback9; CONST_VTBL struct ICorProfilerCallback9Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback9_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback9_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback9_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback9_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback9_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback9_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback9_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback9_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback9_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback9_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback9_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback9_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback9_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback9_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback9_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback9_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback9_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback9_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback9_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback9_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback9_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback9_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback9_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback9_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback9_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback9_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback9_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback9_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback9_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback9_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback9_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback9_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback9_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback9_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback9_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback9_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback9_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback9_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback9_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback9_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback9_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback9_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback9_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback9_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback9_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback9_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback9_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback9_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback9_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback9_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback9_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback9_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback9_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback9_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback9_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback9_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback9_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback9_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback9_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback9_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback9_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback9_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback9_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback9_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback9_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback9_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback9_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback9_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback9_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback9_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback9_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback9_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback9_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback9_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback9_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback9_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback9_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback9_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback9_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback9_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback9_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback9_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback9_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback9_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback9_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback9_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback9_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback9_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback9_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback9_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback9_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback9_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback9_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback9_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback9_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback9_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback9_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback9_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback9_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback9_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback9_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback9_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback9_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback9_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback9_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback9_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback9_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback9_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback9_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback9_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback9_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback9_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback9_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback9_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback9_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback9_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback9_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback9_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback9_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback9_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback9_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback9_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback9_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback9_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback9_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback9_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback9_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback9_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback9_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback9_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback9_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback9_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback9_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback9_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback9_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback9_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback9_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback9_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback9_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback9_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback9_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback9_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback9_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback9_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback9_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback9_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback9_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback9_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback9_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback9_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback9_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback9_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback9_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback9_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback9_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback9_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback9_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback9_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback9_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback9_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback9_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback9_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback9_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback9_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback9_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback9_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback9_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback9_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback9_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback9_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback9_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback9_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback9_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback9_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback9_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback9_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback9_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback9_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback9_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ - ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) +#define ICorProfilerCallback9_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ + ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) -#define ICorProfilerCallback9_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ - ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) +#define ICorProfilerCallback9_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ + ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) -#define ICorProfilerCallback9_ModuleInMemorySymbolsUpdated(This,moduleId) \ - ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) +#define ICorProfilerCallback9_ModuleInMemorySymbolsUpdated(This,moduleId) \ + ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) -#define ICorProfilerCallback9_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) +#define ICorProfilerCallback9_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) -#define ICorProfilerCallback9_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback9_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback9_DynamicMethodUnloaded(This,functionId) \ - ( (This)->lpVtbl -> DynamicMethodUnloaded(This,functionId) ) +#define ICorProfilerCallback9_DynamicMethodUnloaded(This,functionId) \ + ( (This)->lpVtbl -> DynamicMethodUnloaded(This,functionId) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback9_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback9_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback10_INTERFACE_DEFINED__ #define __ICorProfilerCallback10_INTERFACE_DEFINED__ /* interface ICorProfilerCallback10 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback10; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CEC5B60E-C69C-495F-87F6-84D28EE16FFB") ICorProfilerCallback10 : public ICorProfilerCallback9 { public: - virtual HRESULT STDMETHODCALLTYPE EventPipeEventDelivered( + virtual HRESULT STDMETHODCALLTYPE EventPipeEventDelivered( /* [in] */ EVENTPIPE_PROVIDER provider, /* [in] */ DWORD eventId, /* [in] */ DWORD eventVersion, @@ -7576,459 +8386,555 @@ EXTERN_C const IID IID_ICorProfilerCallback10; /* [in] */ ThreadID eventThread, /* [in] */ ULONG numStackFrames, /* [length_is][in] */ UINT_PTR stackFrames[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE EventPipeProviderCreated( + + virtual HRESULT STDMETHODCALLTYPE EventPipeProviderCreated( /* [in] */ EVENTPIPE_PROVIDER provider) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback10Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback10 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback10 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback10 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback10 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback10 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback10 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback10 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback10 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback10 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback10 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback10 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback10 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback10 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback10 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback10 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback10 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback10 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback10 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback10 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback10 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback10 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback10 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback10 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback10 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback10 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback10 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback10 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback10 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback10 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback10 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback10 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback10 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback10 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback10 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback10 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback10 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback10 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback10 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback10 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback10 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback10 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback10 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback10 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback10 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback10 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback10 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback10 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback10 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback10 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback10 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback10 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback10 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback10 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback10 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback5, ConditionalWeakTableElementReferences) + HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( ICorProfilerCallback10 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback6, GetAssemblyReferences) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( ICorProfilerCallback10 * This, /* [string][in] */ const WCHAR *wszAssemblyPath, /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider); - - HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback7, ModuleInMemorySymbolsUpdated) + HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( ICorProfilerCallback10 * This, ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock, /* [in] */ LPCBYTE pILHeader, /* [in] */ ULONG cbILHeader); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodUnloaded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback9, DynamicMethodUnloaded) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodUnloaded )( ICorProfilerCallback10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *EventPipeEventDelivered )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback10, EventPipeEventDelivered) + HRESULT ( STDMETHODCALLTYPE *EventPipeEventDelivered )( ICorProfilerCallback10 * This, /* [in] */ EVENTPIPE_PROVIDER provider, /* [in] */ DWORD eventId, @@ -8042,11 +8948,12 @@ EXTERN_C const IID IID_ICorProfilerCallback10; /* [in] */ ThreadID eventThread, /* [in] */ ULONG numStackFrames, /* [length_is][in] */ UINT_PTR stackFrames[ ]); - - HRESULT ( STDMETHODCALLTYPE *EventPipeProviderCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback10, EventPipeProviderCreated) + HRESULT ( STDMETHODCALLTYPE *EventPipeProviderCreated )( ICorProfilerCallback10 * This, /* [in] */ EVENTPIPE_PROVIDER provider); - + END_INTERFACE } ICorProfilerCallback10Vtbl; @@ -8055,790 +8962,886 @@ EXTERN_C const IID IID_ICorProfilerCallback10; CONST_VTBL struct ICorProfilerCallback10Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback10_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback10_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback10_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback10_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback10_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback10_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback10_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback10_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback10_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback10_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback10_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback10_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback10_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback10_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback10_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback10_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback10_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback10_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback10_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback10_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback10_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback10_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback10_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback10_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback10_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback10_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback10_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback10_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback10_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback10_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback10_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback10_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback10_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback10_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback10_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback10_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback10_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback10_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback10_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback10_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback10_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback10_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback10_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback10_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback10_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback10_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback10_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback10_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback10_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback10_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback10_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback10_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback10_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback10_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback10_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback10_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback10_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback10_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback10_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback10_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback10_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback10_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback10_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback10_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback10_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback10_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback10_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback10_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback10_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback10_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback10_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback10_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback10_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback10_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback10_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback10_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback10_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback10_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback10_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback10_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback10_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback10_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback10_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback10_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback10_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback10_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback10_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback10_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback10_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback10_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback10_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback10_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback10_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback10_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback10_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback10_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback10_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback10_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback10_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback10_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback10_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback10_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback10_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback10_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback10_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback10_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback10_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback10_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback10_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback10_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback10_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback10_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback10_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback10_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback10_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback10_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback10_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback10_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback10_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback10_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback10_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback10_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback10_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback10_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback10_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback10_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback10_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback10_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback10_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback10_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback10_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback10_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback10_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback10_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback10_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback10_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback10_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback10_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback10_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback10_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback10_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback10_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback10_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback10_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback10_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback10_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback10_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback10_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback10_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback10_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback10_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback10_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback10_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback10_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback10_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback10_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback10_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback10_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback10_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback10_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback10_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback10_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback10_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback10_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback10_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback10_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback10_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback10_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback10_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback10_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback10_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback10_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback10_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback10_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback10_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback10_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback10_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback10_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback10_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ - ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) +#define ICorProfilerCallback10_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ + ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) -#define ICorProfilerCallback10_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ - ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) +#define ICorProfilerCallback10_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ + ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) -#define ICorProfilerCallback10_ModuleInMemorySymbolsUpdated(This,moduleId) \ - ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) +#define ICorProfilerCallback10_ModuleInMemorySymbolsUpdated(This,moduleId) \ + ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) -#define ICorProfilerCallback10_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) +#define ICorProfilerCallback10_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) -#define ICorProfilerCallback10_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback10_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback10_DynamicMethodUnloaded(This,functionId) \ - ( (This)->lpVtbl -> DynamicMethodUnloaded(This,functionId) ) +#define ICorProfilerCallback10_DynamicMethodUnloaded(This,functionId) \ + ( (This)->lpVtbl -> DynamicMethodUnloaded(This,functionId) ) -#define ICorProfilerCallback10_EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) \ - ( (This)->lpVtbl -> EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) ) +#define ICorProfilerCallback10_EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) \ + ( (This)->lpVtbl -> EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) ) -#define ICorProfilerCallback10_EventPipeProviderCreated(This,provider) \ - ( (This)->lpVtbl -> EventPipeProviderCreated(This,provider) ) +#define ICorProfilerCallback10_EventPipeProviderCreated(This,provider) \ + ( (This)->lpVtbl -> EventPipeProviderCreated(This,provider) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback10_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback10_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerCallback11_INTERFACE_DEFINED__ #define __ICorProfilerCallback11_INTERFACE_DEFINED__ /* interface ICorProfilerCallback11 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerCallback11; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("42350846-AAED-47F7-B128-FD0C98881CDE") ICorProfilerCallback11 : public ICorProfilerCallback10 { public: - virtual HRESULT STDMETHODCALLTYPE LoadAsNotificationOnly( + virtual HRESULT STDMETHODCALLTYPE LoadAsNotificationOnly( BOOL *pbNotificationOnly) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerCallback11Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerCallback11 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerCallback11 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *Initialize )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Initialize) + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorProfilerCallback11 * This, /* [in] */ IUnknown *pICorProfilerInfoUnk); - - HRESULT ( STDMETHODCALLTYPE *Shutdown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, Shutdown) + HRESULT ( STDMETHODCALLTYPE *Shutdown )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )( ICorProfilerCallback11 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainCreationFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )( ICorProfilerCallback11 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownStarted) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )( ICorProfilerCallback11 * This, /* [in] */ AppDomainID appDomainId); - - HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AppDomainShutdownFinished) + HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )( ICorProfilerCallback11 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )( ICorProfilerCallback11 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyLoadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )( ICorProfilerCallback11 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )( ICorProfilerCallback11 * This, /* [in] */ AssemblyID assemblyId); - - HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, AssemblyUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )( ICorProfilerCallback11 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )( ICorProfilerCallback11 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )( ICorProfilerCallback11 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )( ICorProfilerCallback11 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )( ICorProfilerCallback11 * This, /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ModuleAttachedToAssembly) + HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )( ICorProfilerCallback11 * This, /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID AssemblyId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )( ICorProfilerCallback11 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassLoadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )( ICorProfilerCallback11 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )( ICorProfilerCallback11 * This, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ClassUnloadFinished) + HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )( ICorProfilerCallback11 * This, /* [in] */ ClassID classId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, FunctionUnloadStarted) + HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchStarted) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *pbUseCachedFunction); - - HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITCachedFunctionSearchFinished) + HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_JIT_CACHE result); - - HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITFunctionPitched) + HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *JITInlining )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, JITInlining) + HRESULT ( STDMETHODCALLTYPE *JITInlining )( ICorProfilerCallback11 * This, /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, /* [out] */ BOOL *pfShouldInline); - - HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadCreated) + HRESULT ( STDMETHODCALLTYPE *ThreadCreated )( ICorProfilerCallback11 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadDestroyed) + HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )( ICorProfilerCallback11 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ThreadAssignedToOSThread) + HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )( ICorProfilerCallback11 * This, /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientSendingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )( ICorProfilerCallback11 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientReceivingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )( ICorProfilerCallback11 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingClientInvocationFinished) + HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerReceivingMessage) + HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )( ICorProfilerCallback11 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationStarted) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerInvocationReturned) + HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RemotingServerSendingReply) + HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )( ICorProfilerCallback11 * This, /* [in] */ GUID *pCookie, /* [in] */ BOOL fIsAsync); - - HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, UnmanagedToManagedTransition) + HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ManagedToUnmanagedTransition) + HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_TRANSITION_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )( ICorProfilerCallback11 * This, /* [in] */ COR_PRF_SUSPEND_REASON suspendReason); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeSuspendAborted) + HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeStarted) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeResumeFinished) + HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadSuspended) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )( ICorProfilerCallback11 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RuntimeThreadResumed) + HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )( ICorProfilerCallback11 * This, /* [in] */ ThreadID threadId); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, MovedReferences) + HRESULT ( STDMETHODCALLTYPE *MovedReferences )( ICorProfilerCallback11 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectAllocated) + HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )( ICorProfilerCallback11 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId); - - HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectsAllocatedByClass) + HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )( ICorProfilerCallback11 * This, /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], /* [size_is][in] */ ULONG cObjects[ ]); - - HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ObjectReferences) + HRESULT ( STDMETHODCALLTYPE *ObjectReferences )( ICorProfilerCallback11 * This, /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, /* [size_is][in] */ ObjectID objectRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RootReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, RootReferences) + HRESULT ( STDMETHODCALLTYPE *RootReferences )( ICorProfilerCallback11 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionThrown) + HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )( ICorProfilerCallback11 * This, /* [in] */ ObjectID thrownObjectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchFilterLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionSearchCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )( ICorProfilerCallback11 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionOSHandlerLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )( ICorProfilerCallback11 * This, /* [in] */ UINT_PTR __unused); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFunctionLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionUnwindFinallyLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherEnter) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ ObjectID objectId); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCatcherLeave) + HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableCreated) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )( ICorProfilerCallback11 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, /* [in] */ ULONG cSlots); - - HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, COMClassicVTableDestroyed) + HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )( ICorProfilerCallback11 * This, /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherFound) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback, ExceptionCLRCatcherExecute) + HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, ThreadNameChanged) + HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )( ICorProfilerCallback11 * This, /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, - /* [annotation][in] */ + /* [annotation][in] */ _In_reads_opt_(cchName) WCHAR name[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionStarted) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )( ICorProfilerCallback11 * This, /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], /* [in] */ COR_PRF_GC_REASON reason); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, SurvivingReferences) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )( ICorProfilerCallback11 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, GarbageCollectionFinished) + HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, FinalizeableObjectQueued) + HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )( ICorProfilerCallback11 * This, /* [in] */ DWORD finalizerFlags, /* [in] */ ObjectID objectID); - - HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, RootReferences2) + HRESULT ( STDMETHODCALLTYPE *RootReferences2 )( ICorProfilerCallback11 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], /* [size_is][in] */ UINT_PTR rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *HandleCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleCreated) + HRESULT ( STDMETHODCALLTYPE *HandleCreated )( ICorProfilerCallback11 * This, /* [in] */ GCHandleID handleId, /* [in] */ ObjectID initialObjectId); - - HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback2, HandleDestroyed) + HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )( ICorProfilerCallback11 * This, /* [in] */ GCHandleID handleId); - - HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, InitializeForAttach) + HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )( ICorProfilerCallback11 * This, /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, /* [in] */ UINT cbClientData); - - HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerAttachComplete) + HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback3, ProfilerDetachSucceeded) + HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )( ICorProfilerCallback11 * This); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, GetReJITParameters) + HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )( ICorProfilerCallback11 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ ICorProfilerFunctionControl *pFunctionControl); - - HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *ReJITError )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, ReJITError) + HRESULT ( STDMETHODCALLTYPE *ReJITError )( ICorProfilerCallback11 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus); - - HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, MovedReferences2) + HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )( ICorProfilerCallback11 * This, /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback4, SurvivingReferences2) + HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )( ICorProfilerCallback11 * This, /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]); - - HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback5, ConditionalWeakTableElementReferences) + HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )( ICorProfilerCallback11 * This, /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], /* [size_is][in] */ GCHandleID rootIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback6, GetAssemblyReferences) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )( ICorProfilerCallback11 * This, /* [string][in] */ const WCHAR *wszAssemblyPath, /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider); - - HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback7, ModuleInMemorySymbolsUpdated) + HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )( ICorProfilerCallback11 * This, ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationStarted) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fIsSafeToBlock, /* [in] */ LPCBYTE pILHeader, /* [in] */ ULONG cbILHeader); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback8, DynamicMethodJITCompilationFinished) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, /* [in] */ BOOL fIsSafeToBlock); - - HRESULT ( STDMETHODCALLTYPE *DynamicMethodUnloaded )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback9, DynamicMethodUnloaded) + HRESULT ( STDMETHODCALLTYPE *DynamicMethodUnloaded )( ICorProfilerCallback11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *EventPipeEventDelivered )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback10, EventPipeEventDelivered) + HRESULT ( STDMETHODCALLTYPE *EventPipeEventDelivered )( ICorProfilerCallback11 * This, /* [in] */ EVENTPIPE_PROVIDER provider, /* [in] */ DWORD eventId, @@ -8852,15 +9855,17 @@ EXTERN_C const IID IID_ICorProfilerCallback11; /* [in] */ ThreadID eventThread, /* [in] */ ULONG numStackFrames, /* [length_is][in] */ UINT_PTR stackFrames[ ]); - - HRESULT ( STDMETHODCALLTYPE *EventPipeProviderCreated )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback10, EventPipeProviderCreated) + HRESULT ( STDMETHODCALLTYPE *EventPipeProviderCreated )( ICorProfilerCallback11 * This, /* [in] */ EVENTPIPE_PROVIDER provider); - - HRESULT ( STDMETHODCALLTYPE *LoadAsNotificationOnly )( + + DECLSPEC_XFGVIRT(ICorProfilerCallback11, LoadAsNotificationOnly) + HRESULT ( STDMETHODCALLTYPE *LoadAsNotificationOnly )( ICorProfilerCallback11 * This, BOOL *pbNotificationOnly); - + END_INTERFACE } ICorProfilerCallback11Vtbl; @@ -8869,336 +9874,336 @@ EXTERN_C const IID IID_ICorProfilerCallback11; CONST_VTBL struct ICorProfilerCallback11Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerCallback11_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerCallback11_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerCallback11_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerCallback11_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerCallback11_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerCallback11_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerCallback11_Initialize(This,pICorProfilerInfoUnk) \ - ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) +#define ICorProfilerCallback11_Initialize(This,pICorProfilerInfoUnk) \ + ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) ) -#define ICorProfilerCallback11_Shutdown(This) \ - ( (This)->lpVtbl -> Shutdown(This) ) +#define ICorProfilerCallback11_Shutdown(This) \ + ( (This)->lpVtbl -> Shutdown(This) ) -#define ICorProfilerCallback11_AppDomainCreationStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) +#define ICorProfilerCallback11_AppDomainCreationStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) ) -#define ICorProfilerCallback11_AppDomainCreationFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback11_AppDomainCreationFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback11_AppDomainShutdownStarted(This,appDomainId) \ - ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) +#define ICorProfilerCallback11_AppDomainShutdownStarted(This,appDomainId) \ + ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) ) -#define ICorProfilerCallback11_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ - ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) +#define ICorProfilerCallback11_AppDomainShutdownFinished(This,appDomainId,hrStatus) \ + ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) ) -#define ICorProfilerCallback11_AssemblyLoadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) +#define ICorProfilerCallback11_AssemblyLoadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) ) -#define ICorProfilerCallback11_AssemblyLoadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback11_AssemblyLoadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback11_AssemblyUnloadStarted(This,assemblyId) \ - ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) +#define ICorProfilerCallback11_AssemblyUnloadStarted(This,assemblyId) \ + ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) ) -#define ICorProfilerCallback11_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ - ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) +#define ICorProfilerCallback11_AssemblyUnloadFinished(This,assemblyId,hrStatus) \ + ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) ) -#define ICorProfilerCallback11_ModuleLoadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) +#define ICorProfilerCallback11_ModuleLoadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) ) -#define ICorProfilerCallback11_ModuleLoadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback11_ModuleLoadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback11_ModuleUnloadStarted(This,moduleId) \ - ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) +#define ICorProfilerCallback11_ModuleUnloadStarted(This,moduleId) \ + ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) ) -#define ICorProfilerCallback11_ModuleUnloadFinished(This,moduleId,hrStatus) \ - ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) +#define ICorProfilerCallback11_ModuleUnloadFinished(This,moduleId,hrStatus) \ + ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) ) -#define ICorProfilerCallback11_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ - ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) +#define ICorProfilerCallback11_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \ + ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) ) -#define ICorProfilerCallback11_ClassLoadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) +#define ICorProfilerCallback11_ClassLoadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassLoadStarted(This,classId) ) -#define ICorProfilerCallback11_ClassLoadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback11_ClassLoadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback11_ClassUnloadStarted(This,classId) \ - ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) +#define ICorProfilerCallback11_ClassUnloadStarted(This,classId) \ + ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) ) -#define ICorProfilerCallback11_ClassUnloadFinished(This,classId,hrStatus) \ - ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) +#define ICorProfilerCallback11_ClassUnloadFinished(This,classId,hrStatus) \ + ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) ) -#define ICorProfilerCallback11_FunctionUnloadStarted(This,functionId) \ - ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) +#define ICorProfilerCallback11_FunctionUnloadStarted(This,functionId) \ + ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) ) -#define ICorProfilerCallback11_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) +#define ICorProfilerCallback11_JITCompilationStarted(This,functionId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) ) -#define ICorProfilerCallback11_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback11_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback11_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) +#define ICorProfilerCallback11_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) ) -#define ICorProfilerCallback11_JITCachedFunctionSearchFinished(This,functionId,result) \ - ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) +#define ICorProfilerCallback11_JITCachedFunctionSearchFinished(This,functionId,result) \ + ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) ) -#define ICorProfilerCallback11_JITFunctionPitched(This,functionId) \ - ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) +#define ICorProfilerCallback11_JITFunctionPitched(This,functionId) \ + ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) ) -#define ICorProfilerCallback11_JITInlining(This,callerId,calleeId,pfShouldInline) \ - ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) +#define ICorProfilerCallback11_JITInlining(This,callerId,calleeId,pfShouldInline) \ + ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) ) -#define ICorProfilerCallback11_ThreadCreated(This,threadId) \ - ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) +#define ICorProfilerCallback11_ThreadCreated(This,threadId) \ + ( (This)->lpVtbl -> ThreadCreated(This,threadId) ) -#define ICorProfilerCallback11_ThreadDestroyed(This,threadId) \ - ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) +#define ICorProfilerCallback11_ThreadDestroyed(This,threadId) \ + ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) ) -#define ICorProfilerCallback11_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ - ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) +#define ICorProfilerCallback11_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \ + ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) ) -#define ICorProfilerCallback11_RemotingClientInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) +#define ICorProfilerCallback11_RemotingClientInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) ) -#define ICorProfilerCallback11_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback11_RemotingClientSendingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback11_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback11_RemotingClientReceivingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback11_RemotingClientInvocationFinished(This) \ - ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) +#define ICorProfilerCallback11_RemotingClientInvocationFinished(This) \ + ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) ) -#define ICorProfilerCallback11_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback11_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback11_RemotingServerInvocationStarted(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) +#define ICorProfilerCallback11_RemotingServerInvocationStarted(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) ) -#define ICorProfilerCallback11_RemotingServerInvocationReturned(This) \ - ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) +#define ICorProfilerCallback11_RemotingServerInvocationReturned(This) \ + ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) ) -#define ICorProfilerCallback11_RemotingServerSendingReply(This,pCookie,fIsAsync) \ - ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) +#define ICorProfilerCallback11_RemotingServerSendingReply(This,pCookie,fIsAsync) \ + ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) ) -#define ICorProfilerCallback11_UnmanagedToManagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback11_UnmanagedToManagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback11_ManagedToUnmanagedTransition(This,functionId,reason) \ - ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) +#define ICorProfilerCallback11_ManagedToUnmanagedTransition(This,functionId,reason) \ + ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) ) -#define ICorProfilerCallback11_RuntimeSuspendStarted(This,suspendReason) \ - ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) +#define ICorProfilerCallback11_RuntimeSuspendStarted(This,suspendReason) \ + ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) ) -#define ICorProfilerCallback11_RuntimeSuspendFinished(This) \ - ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) +#define ICorProfilerCallback11_RuntimeSuspendFinished(This) \ + ( (This)->lpVtbl -> RuntimeSuspendFinished(This) ) -#define ICorProfilerCallback11_RuntimeSuspendAborted(This) \ - ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) +#define ICorProfilerCallback11_RuntimeSuspendAborted(This) \ + ( (This)->lpVtbl -> RuntimeSuspendAborted(This) ) -#define ICorProfilerCallback11_RuntimeResumeStarted(This) \ - ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) +#define ICorProfilerCallback11_RuntimeResumeStarted(This) \ + ( (This)->lpVtbl -> RuntimeResumeStarted(This) ) -#define ICorProfilerCallback11_RuntimeResumeFinished(This) \ - ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) +#define ICorProfilerCallback11_RuntimeResumeFinished(This) \ + ( (This)->lpVtbl -> RuntimeResumeFinished(This) ) -#define ICorProfilerCallback11_RuntimeThreadSuspended(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) +#define ICorProfilerCallback11_RuntimeThreadSuspended(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) ) -#define ICorProfilerCallback11_RuntimeThreadResumed(This,threadId) \ - ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) +#define ICorProfilerCallback11_RuntimeThreadResumed(This,threadId) \ + ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) ) -#define ICorProfilerCallback11_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback11_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback11_ObjectAllocated(This,objectId,classId) \ - ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) +#define ICorProfilerCallback11_ObjectAllocated(This,objectId,classId) \ + ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) ) -#define ICorProfilerCallback11_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ - ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) +#define ICorProfilerCallback11_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \ + ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) ) -#define ICorProfilerCallback11_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ - ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) +#define ICorProfilerCallback11_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \ + ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) ) -#define ICorProfilerCallback11_RootReferences(This,cRootRefs,rootRefIds) \ - ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) +#define ICorProfilerCallback11_RootReferences(This,cRootRefs,rootRefIds) \ + ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) ) -#define ICorProfilerCallback11_ExceptionThrown(This,thrownObjectId) \ - ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) +#define ICorProfilerCallback11_ExceptionThrown(This,thrownObjectId) \ + ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) ) -#define ICorProfilerCallback11_ExceptionSearchFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) +#define ICorProfilerCallback11_ExceptionSearchFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) ) -#define ICorProfilerCallback11_ExceptionSearchFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) +#define ICorProfilerCallback11_ExceptionSearchFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) ) -#define ICorProfilerCallback11_ExceptionSearchFilterEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) +#define ICorProfilerCallback11_ExceptionSearchFilterEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) ) -#define ICorProfilerCallback11_ExceptionSearchFilterLeave(This) \ - ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) +#define ICorProfilerCallback11_ExceptionSearchFilterLeave(This) \ + ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) ) -#define ICorProfilerCallback11_ExceptionSearchCatcherFound(This,functionId) \ - ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) +#define ICorProfilerCallback11_ExceptionSearchCatcherFound(This,functionId) \ + ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) ) -#define ICorProfilerCallback11_ExceptionOSHandlerEnter(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) +#define ICorProfilerCallback11_ExceptionOSHandlerEnter(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) ) -#define ICorProfilerCallback11_ExceptionOSHandlerLeave(This,__unused) \ - ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) +#define ICorProfilerCallback11_ExceptionOSHandlerLeave(This,__unused) \ + ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) ) -#define ICorProfilerCallback11_ExceptionUnwindFunctionEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) +#define ICorProfilerCallback11_ExceptionUnwindFunctionEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) ) -#define ICorProfilerCallback11_ExceptionUnwindFunctionLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) +#define ICorProfilerCallback11_ExceptionUnwindFunctionLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) ) -#define ICorProfilerCallback11_ExceptionUnwindFinallyEnter(This,functionId) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) +#define ICorProfilerCallback11_ExceptionUnwindFinallyEnter(This,functionId) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) ) -#define ICorProfilerCallback11_ExceptionUnwindFinallyLeave(This) \ - ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) +#define ICorProfilerCallback11_ExceptionUnwindFinallyLeave(This) \ + ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) ) -#define ICorProfilerCallback11_ExceptionCatcherEnter(This,functionId,objectId) \ - ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) +#define ICorProfilerCallback11_ExceptionCatcherEnter(This,functionId,objectId) \ + ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) ) -#define ICorProfilerCallback11_ExceptionCatcherLeave(This) \ - ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) +#define ICorProfilerCallback11_ExceptionCatcherLeave(This) \ + ( (This)->lpVtbl -> ExceptionCatcherLeave(This) ) -#define ICorProfilerCallback11_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ - ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) +#define ICorProfilerCallback11_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \ + ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) ) -#define ICorProfilerCallback11_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ - ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) +#define ICorProfilerCallback11_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \ + ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) ) -#define ICorProfilerCallback11_ExceptionCLRCatcherFound(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) +#define ICorProfilerCallback11_ExceptionCLRCatcherFound(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) ) -#define ICorProfilerCallback11_ExceptionCLRCatcherExecute(This) \ - ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) +#define ICorProfilerCallback11_ExceptionCLRCatcherExecute(This) \ + ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) ) -#define ICorProfilerCallback11_ThreadNameChanged(This,threadId,cchName,name) \ - ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) +#define ICorProfilerCallback11_ThreadNameChanged(This,threadId,cchName,name) \ + ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) ) -#define ICorProfilerCallback11_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ - ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) +#define ICorProfilerCallback11_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \ + ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) ) -#define ICorProfilerCallback11_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback11_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback11_GarbageCollectionFinished(This) \ - ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) +#define ICorProfilerCallback11_GarbageCollectionFinished(This) \ + ( (This)->lpVtbl -> GarbageCollectionFinished(This) ) -#define ICorProfilerCallback11_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ - ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) +#define ICorProfilerCallback11_FinalizeableObjectQueued(This,finalizerFlags,objectID) \ + ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) ) -#define ICorProfilerCallback11_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ - ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) +#define ICorProfilerCallback11_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \ + ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) ) -#define ICorProfilerCallback11_HandleCreated(This,handleId,initialObjectId) \ - ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) +#define ICorProfilerCallback11_HandleCreated(This,handleId,initialObjectId) \ + ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) ) -#define ICorProfilerCallback11_HandleDestroyed(This,handleId) \ - ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) +#define ICorProfilerCallback11_HandleDestroyed(This,handleId) \ + ( (This)->lpVtbl -> HandleDestroyed(This,handleId) ) -#define ICorProfilerCallback11_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ - ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) +#define ICorProfilerCallback11_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \ + ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) ) -#define ICorProfilerCallback11_ProfilerAttachComplete(This) \ - ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) +#define ICorProfilerCallback11_ProfilerAttachComplete(This) \ + ( (This)->lpVtbl -> ProfilerAttachComplete(This) ) -#define ICorProfilerCallback11_ProfilerDetachSucceeded(This) \ - ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) +#define ICorProfilerCallback11_ProfilerDetachSucceeded(This) \ + ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) ) -#define ICorProfilerCallback11_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) +#define ICorProfilerCallback11_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) ) -#define ICorProfilerCallback11_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ - ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) +#define ICorProfilerCallback11_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \ + ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) ) -#define ICorProfilerCallback11_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback11_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback11_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ - ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) +#define ICorProfilerCallback11_ReJITError(This,moduleId,methodId,functionId,hrStatus) \ + ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) ) -#define ICorProfilerCallback11_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback11_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback11_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ - ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) +#define ICorProfilerCallback11_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \ + ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) ) -#define ICorProfilerCallback11_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ - ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) +#define ICorProfilerCallback11_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \ + ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) ) -#define ICorProfilerCallback11_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ - ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) +#define ICorProfilerCallback11_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \ + ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) ) -#define ICorProfilerCallback11_ModuleInMemorySymbolsUpdated(This,moduleId) \ - ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) +#define ICorProfilerCallback11_ModuleInMemorySymbolsUpdated(This,moduleId) \ + ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) ) -#define ICorProfilerCallback11_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) +#define ICorProfilerCallback11_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) ) -#define ICorProfilerCallback11_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ - ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) +#define ICorProfilerCallback11_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \ + ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) ) -#define ICorProfilerCallback11_DynamicMethodUnloaded(This,functionId) \ - ( (This)->lpVtbl -> DynamicMethodUnloaded(This,functionId) ) +#define ICorProfilerCallback11_DynamicMethodUnloaded(This,functionId) \ + ( (This)->lpVtbl -> DynamicMethodUnloaded(This,functionId) ) -#define ICorProfilerCallback11_EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) \ - ( (This)->lpVtbl -> EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) ) +#define ICorProfilerCallback11_EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) \ + ( (This)->lpVtbl -> EventPipeEventDelivered(This,provider,eventId,eventVersion,cbMetadataBlob,metadataBlob,cbEventData,eventData,pActivityId,pRelatedActivityId,eventThread,numStackFrames,stackFrames) ) -#define ICorProfilerCallback11_EventPipeProviderCreated(This,provider) \ - ( (This)->lpVtbl -> EventPipeProviderCreated(This,provider) ) +#define ICorProfilerCallback11_EventPipeProviderCreated(This,provider) \ + ( (This)->lpVtbl -> EventPipeProviderCreated(This,provider) ) -#define ICorProfilerCallback11_LoadAsNotificationOnly(This,pbNotificationOnly) \ - ( (This)->lpVtbl -> LoadAsNotificationOnly(This,pbNotificationOnly) ) +#define ICorProfilerCallback11_LoadAsNotificationOnly(This,pbNotificationOnly) \ + ( (This)->lpVtbl -> LoadAsNotificationOnly(This,pbNotificationOnly) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerCallback11_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerCallback11_INTERFACE_DEFINED__ */ /* interface __MIDL_itf_corprof_0000_0011 */ -/* [local] */ +/* [local] */ -typedef /* [public] */ +typedef /* [public] */ enum __MIDL___MIDL_itf_corprof_0000_0011_0001 { - COR_PRF_CODEGEN_DISABLE_INLINING = 0x1, - COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS = 0x2 - } COR_PRF_CODEGEN_FLAGS; + COR_PRF_CODEGEN_DISABLE_INLINING = 0x1, + COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS = 0x2 + } COR_PRF_CODEGEN_FLAGS; @@ -9209,383 +10214,419 @@ extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0011_v0_0_s_ifspec; #define __ICorProfilerInfo_INTERFACE_DEFINED__ /* interface ICorProfilerInfo */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("28B5557D-3F3F-48b4-90B2-5F9EEA2F6C48") ICorProfilerInfo : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetClassFromObject( + virtual HRESULT STDMETHODCALLTYPE GetClassFromObject( /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClassFromToken( + + virtual HRESULT STDMETHODCALLTYPE GetClassFromToken( /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCodeInfo( + + virtual HRESULT STDMETHODCALLTYPE GetCodeInfo( /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetEventMask( + + virtual HRESULT STDMETHODCALLTYPE GetEventMask( /* [out] */ DWORD *pdwEvents) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP( /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionFromToken( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionFromToken( /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetHandleFromThread( + + virtual HRESULT STDMETHODCALLTYPE GetHandleFromThread( /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObjectSize( + + virtual HRESULT STDMETHODCALLTYPE GetObjectSize( /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsArrayClass( + + virtual HRESULT STDMETHODCALLTYPE IsArrayClass( /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadInfo( + + virtual HRESULT STDMETHODCALLTYPE GetThreadInfo( /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadID( + + virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadID( /* [out] */ ThreadID *pThreadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClassIDInfo( + + virtual HRESULT STDMETHODCALLTYPE GetClassIDInfo( /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionInfo( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionInfo( /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEventMask( + + virtual HRESULT STDMETHODCALLTYPE SetEventMask( /* [in] */ DWORD dwEvents) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks( + + virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks( /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFunctionIDMapper( + + virtual HRESULT STDMETHODCALLTYPE SetFunctionIDMapper( /* [in] */ FunctionIDMapper *pFunc) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTokenAndMetaDataFromFunction( + + virtual HRESULT STDMETHODCALLTYPE GetTokenAndMetaDataFromFunction( /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetModuleInfo( + + virtual HRESULT STDMETHODCALLTYPE GetModuleInfo( /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetModuleMetaData( + + virtual HRESULT STDMETHODCALLTYPE GetModuleMetaData( /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetILFunctionBody( + + virtual HRESULT STDMETHODCALLTYPE GetILFunctionBody( /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetILFunctionBodyAllocator( + + virtual HRESULT STDMETHODCALLTYPE GetILFunctionBodyAllocator( /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetILFunctionBody( + + virtual HRESULT STDMETHODCALLTYPE SetILFunctionBody( /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAppDomainInfo( + + virtual HRESULT STDMETHODCALLTYPE GetAppDomainInfo( /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAssemblyInfo( + + virtual HRESULT STDMETHODCALLTYPE GetAssemblyInfo( /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFunctionReJIT( + + virtual HRESULT STDMETHODCALLTYPE SetFunctionReJIT( /* [in] */ FunctionID functionId) = 0; - + virtual HRESULT STDMETHODCALLTYPE ForceGC( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetILInstrumentedCodeMap( + + virtual HRESULT STDMETHODCALLTYPE SetILInstrumentedCodeMap( /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetInprocInspectionInterface( + + virtual HRESULT STDMETHODCALLTYPE GetInprocInspectionInterface( /* [out] */ IUnknown **ppicd) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetInprocInspectionIThisThread( + + virtual HRESULT STDMETHODCALLTYPE GetInprocInspectionIThisThread( /* [out] */ IUnknown **ppicd) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadContext( + + virtual HRESULT STDMETHODCALLTYPE GetThreadContext( /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginInprocDebugging( + + virtual HRESULT STDMETHODCALLTYPE BeginInprocDebugging( /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE EndInprocDebugging( + + virtual HRESULT STDMETHODCALLTYPE EndInprocDebugging( /* [in] */ DWORD dwProfilerContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping( + + virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping( /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfoVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - + END_INTERFACE } ICorProfilerInfoVtbl; @@ -9594,160 +10635,160 @@ EXTERN_C const IID IID_ICorProfilerInfo; CONST_VTBL struct ICorProfilerInfoVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo2_INTERFACE_DEFINED__ #define __ICorProfilerInfo2_INTERFACE_DEFINED__ /* interface ICorProfilerInfo2 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC0935CD-A518-487d-B0BB-A93214E65478") ICorProfilerInfo2 : public ICorProfilerInfo { public: - virtual HRESULT STDMETHODCALLTYPE DoStackSnapshot( + virtual HRESULT STDMETHODCALLTYPE DoStackSnapshot( /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, /* [in] */ ULONG32 infoFlags, /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks2( + + virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks2( /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionInfo2( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionInfo2( /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, /* [out] */ ClassID *pClassId, @@ -9756,20 +10797,20 @@ EXTERN_C const IID IID_ICorProfilerInfo2; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStringLayout( + + virtual HRESULT STDMETHODCALLTYPE GetStringLayout( /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClassLayout( + + virtual HRESULT STDMETHODCALLTYPE GetClassLayout( /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClassIDInfo2( + + virtual HRESULT STDMETHODCALLTYPE GetClassIDInfo2( /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken, @@ -9777,298 +10818,335 @@ EXTERN_C const IID IID_ICorProfilerInfo2; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCodeInfo2( + + virtual HRESULT STDMETHODCALLTYPE GetCodeInfo2( /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClassFromTokenAndTypeArgs( + + virtual HRESULT STDMETHODCALLTYPE GetClassFromTokenAndTypeArgs( /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionFromTokenAndTypeArgs( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionFromTokenAndTypeArgs( /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, /* [in] */ ClassID classId, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumModuleFrozenObjects( + + virtual HRESULT STDMETHODCALLTYPE EnumModuleFrozenObjects( /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetArrayObjectInfo( + + virtual HRESULT STDMETHODCALLTYPE GetArrayObjectInfo( /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetBoxClassLayout( + + virtual HRESULT STDMETHODCALLTYPE GetBoxClassLayout( /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadAppDomain( + + virtual HRESULT STDMETHODCALLTYPE GetThreadAppDomain( /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRVAStaticAddress( + + virtual HRESULT STDMETHODCALLTYPE GetRVAStaticAddress( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAppDomainStaticAddress( + + virtual HRESULT STDMETHODCALLTYPE GetAppDomainStaticAddress( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadStaticAddress( + + virtual HRESULT STDMETHODCALLTYPE GetThreadStaticAddress( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetContextStaticAddress( + + virtual HRESULT STDMETHODCALLTYPE GetContextStaticAddress( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStaticFieldInfo( + + virtual HRESULT STDMETHODCALLTYPE GetStaticFieldInfo( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetGenerationBounds( + + virtual HRESULT STDMETHODCALLTYPE GetGenerationBounds( /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObjectGeneration( + + virtual HRESULT STDMETHODCALLTYPE GetObjectGeneration( /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetNotifiedExceptionClauseInfo( + + virtual HRESULT STDMETHODCALLTYPE GetNotifiedExceptionClauseInfo( /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo2Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo2 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo2 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo2 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo2 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo2 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo2 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo2 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo2 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo2 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo2 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo2 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo2 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo2 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo2 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo2 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo2 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo2 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo2 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo2 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo2 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo2 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo2 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo2 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo2 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo2 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo2 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo2 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -10076,14 +11154,16 @@ EXTERN_C const IID IID_ICorProfilerInfo2; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo2 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo2 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -10093,22 +11173,25 @@ EXTERN_C const IID IID_ICorProfilerInfo2; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo2 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo2 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -10117,23 +11200,26 @@ EXTERN_C const IID IID_ICorProfilerInfo2; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo2 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -10141,78 +11227,90 @@ EXTERN_C const IID IID_ICorProfilerInfo2; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo2 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo2 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo2 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo2 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo2 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo2 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo2 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - + END_INTERFACE } ICorProfilerInfo2Vtbl; @@ -10221,256 +11319,256 @@ EXTERN_C const IID IID_ICorProfilerInfo2; CONST_VTBL struct ICorProfilerInfo2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo2_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo2_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo2_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo2_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo2_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo2_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo2_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo2_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo2_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo2_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo2_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo2_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo2_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo2_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo2_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo2_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo2_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo2_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo2_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo2_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo2_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo2_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo2_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo2_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo2_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo2_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo2_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo2_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo2_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo2_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo2_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo2_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo2_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo2_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo2_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo2_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo2_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo2_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo2_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo2_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo2_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo2_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo2_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo2_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo2_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo2_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo2_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo2_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo2_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo2_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo2_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo2_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo2_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo2_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo2_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo2_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo2_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo2_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo2_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo2_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo2_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo2_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo2_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo2_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo2_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo2_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo2_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo2_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo2_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo2_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo2_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo2_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo2_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo2_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo2_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo2_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo2_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo2_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo2_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo2_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo2_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo2_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo2_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo2_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo2_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo2_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo2_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo2_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo2_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo2_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo2_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo2_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo2_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo2_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo2_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo2_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo2_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo2_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo2_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo2_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo2_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo2_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo2_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo2_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo2_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo2_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo2_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo2_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo2_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo2_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo3_INTERFACE_DEFINED__ #define __ICorProfilerInfo3_INTERFACE_DEFINED__ /* interface ICorProfilerInfo3 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("B555ED4F-452A-4E54-8B39-B5360BAD32A0") ICorProfilerInfo3 : public ICorProfilerInfo2 { public: - virtual HRESULT STDMETHODCALLTYPE EnumJITedFunctions( + virtual HRESULT STDMETHODCALLTYPE EnumJITedFunctions( /* [out] */ ICorProfilerFunctionEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE RequestProfilerDetach( + + virtual HRESULT STDMETHODCALLTYPE RequestProfilerDetach( /* [in] */ DWORD dwExpectedCompletionMilliseconds) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFunctionIDMapper2( + + virtual HRESULT STDMETHODCALLTYPE SetFunctionIDMapper2( /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStringLayout2( + + virtual HRESULT STDMETHODCALLTYPE GetStringLayout2( /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks3( + + virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks3( /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks3WithInfo( + + virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks3WithInfo( /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionEnter3Info( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionEnter3Info( /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionLeave3Info( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionLeave3Info( /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionTailcall3Info( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionTailcall3Info( /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumModules( + + virtual HRESULT STDMETHODCALLTYPE EnumModules( /* [out] */ ICorProfilerModuleEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRuntimeInformation( + + virtual HRESULT STDMETHODCALLTYPE GetRuntimeInformation( /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, /* [out] */ USHORT *pMajorVersion, @@ -10479,243 +11577,280 @@ EXTERN_C const IID IID_ICorProfilerInfo3; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadStaticAddress2( + + virtual HRESULT STDMETHODCALLTYPE GetThreadStaticAddress2( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAppDomainsContainingModule( + + virtual HRESULT STDMETHODCALLTYPE GetAppDomainsContainingModule( /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetModuleInfo2( + + virtual HRESULT STDMETHODCALLTYPE GetModuleInfo2( /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo3Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo3 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo3 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo3 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo3 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo3 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo3 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo3 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo3 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo3 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo3 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo3 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo3 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo3 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo3 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo3 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo3 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo3 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo3 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo3 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo3 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo3 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -10723,14 +11858,16 @@ EXTERN_C const IID IID_ICorProfilerInfo3; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo3 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo3 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -10740,22 +11877,25 @@ EXTERN_C const IID IID_ICorProfilerInfo3; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo3 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo3 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -10764,23 +11904,26 @@ EXTERN_C const IID IID_ICorProfilerInfo3; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -10788,134 +11931,157 @@ EXTERN_C const IID IID_ICorProfilerInfo3; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo3 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo3 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo3 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo3 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo3 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo3 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo3 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo3 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo3 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo3 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo3 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo3 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo3 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo3 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -10925,35 +12091,38 @@ EXTERN_C const IID IID_ICorProfilerInfo3; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo3 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo3 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - + END_INTERFACE } ICorProfilerInfo3Vtbl; @@ -10962,311 +12131,319 @@ EXTERN_C const IID IID_ICorProfilerInfo3; CONST_VTBL struct ICorProfilerInfo3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo3_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo3_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo3_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo3_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo3_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo3_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo3_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo3_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo3_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo3_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo3_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo3_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo3_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo3_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo3_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo3_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo3_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo3_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo3_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo3_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo3_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo3_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo3_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo3_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo3_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo3_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo3_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo3_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo3_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo3_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo3_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo3_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo3_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo3_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo3_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo3_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo3_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo3_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo3_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo3_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo3_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo3_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo3_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo3_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo3_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo3_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo3_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo3_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo3_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo3_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo3_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo3_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo3_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo3_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo3_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo3_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo3_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo3_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo3_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo3_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo3_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo3_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo3_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo3_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo3_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo3_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo3_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo3_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo3_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo3_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo3_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo3_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo3_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo3_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo3_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo3_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo3_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo3_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo3_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo3_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo3_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo3_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo3_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo3_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo3_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo3_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo3_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo3_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo3_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo3_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo3_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo3_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo3_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo3_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo3_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo3_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo3_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo3_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo3_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo3_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo3_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo3_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo3_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo3_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo3_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo3_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo3_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo3_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo3_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo3_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo3_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo3_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo3_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo3_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo3_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo3_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo3_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo3_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo3_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo3_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo3_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo3_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo3_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo3_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo3_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo3_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo3_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo3_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo3_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo3_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo3_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerObjectEnum_INTERFACE_DEFINED__ #define __ICorProfilerObjectEnum_INTERFACE_DEFINED__ /* interface ICorProfilerObjectEnum */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerObjectEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("2C6269BD-2D13-4321-AE12-6686365FD6AF") ICorProfilerObjectEnum : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Skip( + virtual HRESULT STDMETHODCALLTYPE Skip( /* [in] */ ULONG celt) = 0; - + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( + + virtual HRESULT STDMETHODCALLTYPE Clone( /* [out] */ ICorProfilerObjectEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( + + virtual HRESULT STDMETHODCALLTYPE GetCount( /* [out] */ ULONG *pcelt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Next( + + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ObjectID objects[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerObjectEnumVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerObjectEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerObjectEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerObjectEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( + + DECLSPEC_XFGVIRT(ICorProfilerObjectEnum, Skip) + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorProfilerObjectEnum * This, /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( + + DECLSPEC_XFGVIRT(ICorProfilerObjectEnum, Reset) + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorProfilerObjectEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( + + DECLSPEC_XFGVIRT(ICorProfilerObjectEnum, Clone) + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorProfilerObjectEnum * This, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( + + DECLSPEC_XFGVIRT(ICorProfilerObjectEnum, GetCount) + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorProfilerObjectEnum * This, /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( + + DECLSPEC_XFGVIRT(ICorProfilerObjectEnum, Next) + HRESULT ( STDMETHODCALLTYPE *Next )( ICorProfilerObjectEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ObjectID objects[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorProfilerObjectEnumVtbl; @@ -11275,120 +12452,128 @@ EXTERN_C const IID IID_ICorProfilerObjectEnum; CONST_VTBL struct ICorProfilerObjectEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerObjectEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerObjectEnum_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerObjectEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerObjectEnum_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerObjectEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerObjectEnum_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerObjectEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) +#define ICorProfilerObjectEnum_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) -#define ICorProfilerObjectEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) +#define ICorProfilerObjectEnum_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) -#define ICorProfilerObjectEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) +#define ICorProfilerObjectEnum_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) -#define ICorProfilerObjectEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) +#define ICorProfilerObjectEnum_GetCount(This,pcelt) \ + ( (This)->lpVtbl -> GetCount(This,pcelt) ) -#define ICorProfilerObjectEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) +#define ICorProfilerObjectEnum_Next(This,celt,objects,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerObjectEnum_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerObjectEnum_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerFunctionEnum_INTERFACE_DEFINED__ #define __ICorProfilerFunctionEnum_INTERFACE_DEFINED__ /* interface ICorProfilerFunctionEnum */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerFunctionEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("FF71301A-B994-429D-A10B-B345A65280EF") ICorProfilerFunctionEnum : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Skip( + virtual HRESULT STDMETHODCALLTYPE Skip( /* [in] */ ULONG celt) = 0; - + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( + + virtual HRESULT STDMETHODCALLTYPE Clone( /* [out] */ ICorProfilerFunctionEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( + + virtual HRESULT STDMETHODCALLTYPE GetCount( /* [out] */ ULONG *pcelt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Next( + + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_PRF_FUNCTION ids[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerFunctionEnumVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerFunctionEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerFunctionEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerFunctionEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionEnum, Skip) + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorProfilerFunctionEnum * This, /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionEnum, Reset) + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorProfilerFunctionEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionEnum, Clone) + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorProfilerFunctionEnum * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionEnum, GetCount) + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorProfilerFunctionEnum * This, /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionEnum, Next) + HRESULT ( STDMETHODCALLTYPE *Next )( ICorProfilerFunctionEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_PRF_FUNCTION ids[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorProfilerFunctionEnumVtbl; @@ -11397,120 +12582,128 @@ EXTERN_C const IID IID_ICorProfilerFunctionEnum; CONST_VTBL struct ICorProfilerFunctionEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerFunctionEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerFunctionEnum_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerFunctionEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerFunctionEnum_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerFunctionEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerFunctionEnum_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerFunctionEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) +#define ICorProfilerFunctionEnum_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) -#define ICorProfilerFunctionEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) +#define ICorProfilerFunctionEnum_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) -#define ICorProfilerFunctionEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) +#define ICorProfilerFunctionEnum_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) -#define ICorProfilerFunctionEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) +#define ICorProfilerFunctionEnum_GetCount(This,pcelt) \ + ( (This)->lpVtbl -> GetCount(This,pcelt) ) -#define ICorProfilerFunctionEnum_Next(This,celt,ids,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,ids,pceltFetched) ) +#define ICorProfilerFunctionEnum_Next(This,celt,ids,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,ids,pceltFetched) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerFunctionEnum_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerFunctionEnum_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerModuleEnum_INTERFACE_DEFINED__ #define __ICorProfilerModuleEnum_INTERFACE_DEFINED__ /* interface ICorProfilerModuleEnum */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerModuleEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("b0266d75-2081-4493-af7f-028ba34db891") ICorProfilerModuleEnum : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Skip( + virtual HRESULT STDMETHODCALLTYPE Skip( /* [in] */ ULONG celt) = 0; - + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( + + virtual HRESULT STDMETHODCALLTYPE Clone( /* [out] */ ICorProfilerModuleEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( + + virtual HRESULT STDMETHODCALLTYPE GetCount( /* [out] */ ULONG *pcelt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Next( + + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ModuleID ids[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerModuleEnumVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerModuleEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerModuleEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerModuleEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( + + DECLSPEC_XFGVIRT(ICorProfilerModuleEnum, Skip) + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorProfilerModuleEnum * This, /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( + + DECLSPEC_XFGVIRT(ICorProfilerModuleEnum, Reset) + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorProfilerModuleEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( + + DECLSPEC_XFGVIRT(ICorProfilerModuleEnum, Clone) + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorProfilerModuleEnum * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( + + DECLSPEC_XFGVIRT(ICorProfilerModuleEnum, GetCount) + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorProfilerModuleEnum * This, /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( + + DECLSPEC_XFGVIRT(ICorProfilerModuleEnum, Next) + HRESULT ( STDMETHODCALLTYPE *Next )( ICorProfilerModuleEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ModuleID ids[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorProfilerModuleEnumVtbl; @@ -11519,90 +12712,94 @@ EXTERN_C const IID IID_ICorProfilerModuleEnum; CONST_VTBL struct ICorProfilerModuleEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerModuleEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerModuleEnum_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerModuleEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerModuleEnum_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerModuleEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerModuleEnum_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerModuleEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) +#define ICorProfilerModuleEnum_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) -#define ICorProfilerModuleEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) +#define ICorProfilerModuleEnum_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) -#define ICorProfilerModuleEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) +#define ICorProfilerModuleEnum_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) -#define ICorProfilerModuleEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) +#define ICorProfilerModuleEnum_GetCount(This,pcelt) \ + ( (This)->lpVtbl -> GetCount(This,pcelt) ) -#define ICorProfilerModuleEnum_Next(This,celt,ids,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,ids,pceltFetched) ) +#define ICorProfilerModuleEnum_Next(This,celt,ids,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,ids,pceltFetched) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerModuleEnum_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerModuleEnum_INTERFACE_DEFINED__ */ #ifndef __IMethodMalloc_INTERFACE_DEFINED__ #define __IMethodMalloc_INTERFACE_DEFINED__ /* interface IMethodMalloc */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_IMethodMalloc; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("A0EFB28B-6EE2-4d7b-B983-A75EF7BEEDB8") IMethodMalloc : public IUnknown { public: - virtual PVOID STDMETHODCALLTYPE Alloc( + virtual PVOID STDMETHODCALLTYPE Alloc( /* [in] */ ULONG cb) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct IMethodMallocVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IMethodMalloc * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( IMethodMalloc * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( IMethodMalloc * This); - - PVOID ( STDMETHODCALLTYPE *Alloc )( + + DECLSPEC_XFGVIRT(IMethodMalloc, Alloc) + PVOID ( STDMETHODCALLTYPE *Alloc )( IMethodMalloc * This, /* [in] */ ULONG cb); - + END_INTERFACE } IMethodMallocVtbl; @@ -11611,96 +12808,102 @@ EXTERN_C const IID IID_IMethodMalloc; CONST_VTBL struct IMethodMallocVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define IMethodMalloc_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define IMethodMalloc_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define IMethodMalloc_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define IMethodMalloc_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define IMethodMalloc_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define IMethodMalloc_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define IMethodMalloc_Alloc(This,cb) \ - ( (This)->lpVtbl -> Alloc(This,cb) ) +#define IMethodMalloc_Alloc(This,cb) \ + ( (This)->lpVtbl -> Alloc(This,cb) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __IMethodMalloc_INTERFACE_DEFINED__ */ +#endif /* __IMethodMalloc_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerFunctionControl_INTERFACE_DEFINED__ #define __ICorProfilerFunctionControl_INTERFACE_DEFINED__ /* interface ICorProfilerFunctionControl */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerFunctionControl; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F0963021-E1EA-4732-8581-E01B0BD3C0C6") ICorProfilerFunctionControl : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE SetCodegenFlags( + virtual HRESULT STDMETHODCALLTYPE SetCodegenFlags( /* [in] */ DWORD flags) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetILFunctionBody( + + virtual HRESULT STDMETHODCALLTYPE SetILFunctionBody( /* [in] */ ULONG cbNewILMethodHeader, /* [size_is][in] */ LPCBYTE pbNewILMethodHeader) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetILInstrumentedCodeMap( + + virtual HRESULT STDMETHODCALLTYPE SetILInstrumentedCodeMap( /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerFunctionControlVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerFunctionControl * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerFunctionControl * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerFunctionControl * This); - - HRESULT ( STDMETHODCALLTYPE *SetCodegenFlags )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionControl, SetCodegenFlags) + HRESULT ( STDMETHODCALLTYPE *SetCodegenFlags )( ICorProfilerFunctionControl * This, /* [in] */ DWORD flags); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionControl, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerFunctionControl * This, /* [in] */ ULONG cbNewILMethodHeader, /* [size_is][in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerFunctionControl, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerFunctionControl * This, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - + END_INTERFACE } ICorProfilerFunctionControlVtbl; @@ -11709,315 +12912,352 @@ EXTERN_C const IID IID_ICorProfilerFunctionControl; CONST_VTBL struct ICorProfilerFunctionControlVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerFunctionControl_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerFunctionControl_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerFunctionControl_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerFunctionControl_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerFunctionControl_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerFunctionControl_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerFunctionControl_SetCodegenFlags(This,flags) \ - ( (This)->lpVtbl -> SetCodegenFlags(This,flags) ) +#define ICorProfilerFunctionControl_SetCodegenFlags(This,flags) \ + ( (This)->lpVtbl -> SetCodegenFlags(This,flags) ) -#define ICorProfilerFunctionControl_SetILFunctionBody(This,cbNewILMethodHeader,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,cbNewILMethodHeader,pbNewILMethodHeader) ) +#define ICorProfilerFunctionControl_SetILFunctionBody(This,cbNewILMethodHeader,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,cbNewILMethodHeader,pbNewILMethodHeader) ) -#define ICorProfilerFunctionControl_SetILInstrumentedCodeMap(This,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerFunctionControl_SetILInstrumentedCodeMap(This,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,cILMapEntries,rgILMapEntries) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerFunctionControl_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerFunctionControl_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo4_INTERFACE_DEFINED__ #define __ICorProfilerInfo4_INTERFACE_DEFINED__ /* interface ICorProfilerInfo4 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("0d8fdcaa-6257-47bf-b1bf-94dac88466ee") ICorProfilerInfo4 : public ICorProfilerInfo3 { public: - virtual HRESULT STDMETHODCALLTYPE EnumThreads( + virtual HRESULT STDMETHODCALLTYPE EnumThreads( /* [out] */ ICorProfilerThreadEnum **ppEnum) = 0; - + virtual HRESULT STDMETHODCALLTYPE InitializeCurrentThread( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE RequestReJIT( + + virtual HRESULT STDMETHODCALLTYPE RequestReJIT( /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE RequestRevert( + + virtual HRESULT STDMETHODCALLTYPE RequestRevert( /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCodeInfo3( + + virtual HRESULT STDMETHODCALLTYPE GetCodeInfo3( /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP2( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP2( /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetReJITIDs( + + virtual HRESULT STDMETHODCALLTYPE GetReJITIDs( /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping2( + + virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping2( /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumJITedFunctions2( + + virtual HRESULT STDMETHODCALLTYPE EnumJITedFunctions2( /* [out] */ ICorProfilerFunctionEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObjectSize2( + + virtual HRESULT STDMETHODCALLTYPE GetObjectSize2( /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo4Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo4 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo4 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo4 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo4 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo4 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo4 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo4 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo4 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo4 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo4 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo4 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo4 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo4 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo4 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo4 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo4 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo4 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo4 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo4 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo4 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo4 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -12025,14 +13265,16 @@ EXTERN_C const IID IID_ICorProfilerInfo4; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo4 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo4 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -12042,22 +13284,25 @@ EXTERN_C const IID IID_ICorProfilerInfo4; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo4 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo4 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -12066,23 +13311,26 @@ EXTERN_C const IID IID_ICorProfilerInfo4; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -12090,134 +13338,157 @@ EXTERN_C const IID IID_ICorProfilerInfo4; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo4 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo4 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo4 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo4 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo4 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo4 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo4 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo4 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo4 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo4 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo4 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo4 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo4 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -12227,93 +13498,106 @@ EXTERN_C const IID IID_ICorProfilerInfo4; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo4 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo4 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo4 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo4 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo4 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo4 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo4 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo4 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo4 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo4 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - + END_INTERFACE } ICorProfilerInfo4Vtbl; @@ -12322,503 +13606,540 @@ EXTERN_C const IID IID_ICorProfilerInfo4; CONST_VTBL struct ICorProfilerInfo4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo4_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo4_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo4_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo4_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo4_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo4_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo4_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo4_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo4_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo4_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo4_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo4_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo4_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo4_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo4_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo4_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo4_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo4_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo4_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo4_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo4_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo4_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo4_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo4_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo4_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo4_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo4_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo4_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo4_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo4_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo4_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo4_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo4_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo4_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo4_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo4_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo4_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo4_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo4_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo4_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo4_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo4_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo4_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo4_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo4_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo4_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo4_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo4_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo4_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo4_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo4_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo4_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo4_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo4_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo4_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo4_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo4_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo4_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo4_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo4_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo4_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo4_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo4_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo4_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo4_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo4_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo4_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo4_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo4_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo4_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo4_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo4_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo4_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo4_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo4_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo4_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo4_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo4_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo4_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo4_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo4_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo4_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo4_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo4_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo4_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo4_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo4_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo4_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo4_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo4_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo4_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo4_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo4_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo4_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo4_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo4_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo4_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo4_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo4_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo4_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo4_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo4_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo4_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo4_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo4_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo4_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo4_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo4_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo4_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo4_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo4_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo4_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo4_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo4_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo4_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo4_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo4_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo4_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo4_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo4_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo4_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo4_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo4_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo4_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo4_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo4_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo4_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo4_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo4_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo4_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo4_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo4_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo4_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo4_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo4_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo4_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo4_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo4_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo4_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo4_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo4_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo4_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo4_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo4_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo4_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo4_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo4_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo4_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo4_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo4_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo4_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo5_INTERFACE_DEFINED__ #define __ICorProfilerInfo5_INTERFACE_DEFINED__ /* interface ICorProfilerInfo5 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo5; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("07602928-CE38-4B83-81E7-74ADAF781214") ICorProfilerInfo5 : public ICorProfilerInfo4 { public: - virtual HRESULT STDMETHODCALLTYPE GetEventMask2( + virtual HRESULT STDMETHODCALLTYPE GetEventMask2( /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEventMask2( + + virtual HRESULT STDMETHODCALLTYPE SetEventMask2( /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo5Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo5 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo5 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo5 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo5 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo5 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo5 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo5 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo5 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo5 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo5 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo5 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo5 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo5 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo5 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo5 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo5 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo5 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo5 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo5 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo5 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo5 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo5 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -12826,14 +14147,16 @@ EXTERN_C const IID IID_ICorProfilerInfo5; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo5 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo5 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -12843,22 +14166,25 @@ EXTERN_C const IID IID_ICorProfilerInfo5; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo5 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo5 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -12867,23 +14193,26 @@ EXTERN_C const IID IID_ICorProfilerInfo5; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -12891,134 +14220,157 @@ EXTERN_C const IID IID_ICorProfilerInfo5; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo5 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo5 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo5 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo5 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo5 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo5 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo5 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo5 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo5 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo5 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo5 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo5 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo5 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -13028,103 +14380,118 @@ EXTERN_C const IID IID_ICorProfilerInfo5; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo5 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo5 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo5 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo5 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo5 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo5 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo5 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo5 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo5 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo5 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo5 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo5 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - + END_INTERFACE } ICorProfilerInfo5Vtbl; @@ -13133,509 +14500,546 @@ EXTERN_C const IID IID_ICorProfilerInfo5; CONST_VTBL struct ICorProfilerInfo5Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo5_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo5_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo5_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo5_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo5_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo5_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo5_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo5_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo5_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo5_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo5_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo5_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo5_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo5_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo5_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo5_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo5_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo5_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo5_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo5_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo5_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo5_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo5_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo5_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo5_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo5_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo5_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo5_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo5_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo5_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo5_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo5_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo5_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo5_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo5_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo5_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo5_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo5_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo5_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo5_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo5_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo5_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo5_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo5_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo5_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo5_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo5_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo5_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo5_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo5_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo5_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo5_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo5_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo5_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo5_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo5_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo5_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo5_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo5_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo5_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo5_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo5_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo5_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo5_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo5_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo5_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo5_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo5_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo5_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo5_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo5_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo5_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo5_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo5_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo5_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo5_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo5_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo5_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo5_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo5_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo5_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo5_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo5_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo5_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo5_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo5_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo5_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo5_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo5_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo5_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo5_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo5_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo5_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo5_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo5_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo5_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo5_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo5_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo5_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo5_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo5_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo5_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo5_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo5_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo5_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo5_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo5_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo5_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo5_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo5_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo5_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo5_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo5_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo5_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo5_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo5_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo5_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo5_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo5_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo5_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo5_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo5_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo5_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo5_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo5_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo5_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo5_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo5_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo5_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo5_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo5_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo5_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo5_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo5_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo5_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo5_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo5_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo5_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo5_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo5_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo5_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo5_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo5_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo5_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo5_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo5_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo5_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo5_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo5_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo5_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo5_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo5_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo5_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo5_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo5_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo5_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo5_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo5_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo5_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo5_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo5_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo6_INTERFACE_DEFINED__ #define __ICorProfilerInfo6_INTERFACE_DEFINED__ /* interface ICorProfilerInfo6 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo6; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F30A070D-BFFB-46A7-B1D8-8781EF7B698A") ICorProfilerInfo6 : public ICorProfilerInfo5 { public: - virtual HRESULT STDMETHODCALLTYPE EnumNgenModuleMethodsInliningThisMethod( + virtual HRESULT STDMETHODCALLTYPE EnumNgenModuleMethodsInliningThisMethod( /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo6Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo6 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo6 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo6 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo6 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo6 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo6 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo6 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo6 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo6 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo6 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo6 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo6 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo6 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo6 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo6 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo6 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo6 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo6 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo6 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo6 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo6 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo6 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -13643,14 +15047,16 @@ EXTERN_C const IID IID_ICorProfilerInfo6; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo6 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo6 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -13660,22 +15066,25 @@ EXTERN_C const IID IID_ICorProfilerInfo6; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo6 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo6 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -13684,23 +15093,26 @@ EXTERN_C const IID IID_ICorProfilerInfo6; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -13708,134 +15120,157 @@ EXTERN_C const IID IID_ICorProfilerInfo6; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo6 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo6 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo6 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo6 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo6 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo6 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo6 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo6 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo6 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo6 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo6 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo6 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo6 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -13845,111 +15280,127 @@ EXTERN_C const IID IID_ICorProfilerInfo6; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo6 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo6 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo6 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo6 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo6 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo6 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo6 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo6 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo6 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo6 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo6 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo6 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo6 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - + END_INTERFACE } ICorProfilerInfo6Vtbl; @@ -13958,520 +15409,557 @@ EXTERN_C const IID IID_ICorProfilerInfo6; CONST_VTBL struct ICorProfilerInfo6Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo6_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo6_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo6_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo6_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo6_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo6_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo6_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo6_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo6_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo6_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo6_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo6_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo6_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo6_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo6_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo6_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo6_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo6_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo6_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo6_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo6_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo6_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo6_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo6_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo6_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo6_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo6_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo6_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo6_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo6_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo6_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo6_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo6_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo6_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo6_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo6_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo6_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo6_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo6_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo6_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo6_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo6_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo6_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo6_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo6_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo6_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo6_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo6_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo6_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo6_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo6_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo6_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo6_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo6_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo6_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo6_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo6_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo6_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo6_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo6_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo6_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo6_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo6_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo6_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo6_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo6_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo6_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo6_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo6_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo6_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo6_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo6_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo6_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo6_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo6_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo6_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo6_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo6_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo6_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo6_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo6_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo6_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo6_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo6_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo6_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo6_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo6_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo6_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo6_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo6_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo6_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo6_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo6_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo6_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo6_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo6_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo6_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo6_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo6_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo6_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo6_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo6_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo6_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo6_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo6_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo6_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo6_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo6_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo6_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo6_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo6_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo6_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo6_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo6_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo6_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo6_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo6_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo6_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo6_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo6_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo6_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo6_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo6_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo6_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo6_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo6_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo6_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo6_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo6_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo6_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo6_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo6_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo6_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo6_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo6_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo6_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo6_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo6_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo6_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo6_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo6_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo6_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo6_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo6_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo6_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo6_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo6_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo6_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo6_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo6_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo6_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo6_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo6_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo6_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo6_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo6_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo6_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo6_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo6_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo6_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo6_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo6_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo6_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo7_INTERFACE_DEFINED__ #define __ICorProfilerInfo7_INTERFACE_DEFINED__ /* interface ICorProfilerInfo7 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo7; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("9AEECC0D-63E0-4187-8C00-E312F503F663") ICorProfilerInfo7 : public ICorProfilerInfo6 { public: - virtual HRESULT STDMETHODCALLTYPE ApplyMetaData( + virtual HRESULT STDMETHODCALLTYPE ApplyMetaData( /* [in] */ ModuleID moduleId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetInMemorySymbolsLength( + + virtual HRESULT STDMETHODCALLTYPE GetInMemorySymbolsLength( /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes) = 0; - - virtual HRESULT STDMETHODCALLTYPE ReadInMemorySymbols( + + virtual HRESULT STDMETHODCALLTYPE ReadInMemorySymbols( /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo7Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo7 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo7 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo7 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo7 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo7 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo7 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo7 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo7 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo7 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo7 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo7 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo7 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo7 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo7 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo7 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo7 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo7 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo7 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo7 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo7 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo7 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo7 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -14479,14 +15967,16 @@ EXTERN_C const IID IID_ICorProfilerInfo7; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo7 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo7 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -14496,22 +15986,25 @@ EXTERN_C const IID IID_ICorProfilerInfo7; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo7 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo7 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -14520,23 +16013,26 @@ EXTERN_C const IID IID_ICorProfilerInfo7; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -14544,134 +16040,157 @@ EXTERN_C const IID IID_ICorProfilerInfo7; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo7 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo7 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo7 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo7 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo7 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo7 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo7 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo7 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo7 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo7 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo7 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo7 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo7 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -14681,128 +16200,147 @@ EXTERN_C const IID IID_ICorProfilerInfo7; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo7 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo7 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo7 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo7 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo7 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo7 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo7 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo7 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo7 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo7 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo7 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo7 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes); - - HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( ICorProfilerInfo7 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead); - + END_INTERFACE } ICorProfilerInfo7Vtbl; @@ -14811,315 +16349,315 @@ EXTERN_C const IID IID_ICorProfilerInfo7; CONST_VTBL struct ICorProfilerInfo7Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo7_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo7_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo7_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo7_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo7_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo7_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo7_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo7_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo7_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo7_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo7_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo7_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo7_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo7_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo7_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo7_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo7_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo7_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo7_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo7_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo7_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo7_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo7_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo7_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo7_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo7_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo7_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo7_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo7_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo7_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo7_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo7_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo7_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo7_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo7_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo7_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo7_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo7_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo7_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo7_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo7_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo7_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo7_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo7_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo7_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo7_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo7_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo7_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo7_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo7_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo7_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo7_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo7_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo7_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo7_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo7_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo7_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo7_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo7_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo7_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo7_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo7_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo7_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo7_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo7_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo7_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo7_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo7_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo7_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo7_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo7_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo7_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo7_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo7_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo7_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo7_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo7_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo7_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo7_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo7_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo7_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo7_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo7_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo7_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo7_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo7_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo7_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo7_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo7_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo7_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo7_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo7_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo7_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo7_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo7_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo7_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo7_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo7_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo7_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo7_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo7_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo7_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo7_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo7_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo7_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo7_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo7_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo7_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo7_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo7_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo7_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo7_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo7_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo7_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo7_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo7_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo7_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo7_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo7_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo7_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo7_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo7_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo7_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo7_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo7_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo7_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo7_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo7_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo7_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo7_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo7_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo7_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo7_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo7_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo7_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo7_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo7_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo7_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo7_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo7_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo7_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo7_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo7_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo7_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo7_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo7_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo7_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo7_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo7_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo7_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo7_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo7_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo7_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo7_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo7_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo7_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo7_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo7_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo7_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo7_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo7_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) -#define ICorProfilerInfo7_ApplyMetaData(This,moduleId) \ - ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo7_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) -#define ICorProfilerInfo7_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ - ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) +#define ICorProfilerInfo7_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerInfo7_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ - ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) +#define ICorProfilerInfo7_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo7_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo7_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo8_INTERFACE_DEFINED__ #define __ICorProfilerInfo8_INTERFACE_DEFINED__ /* interface ICorProfilerInfo8 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo8; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("C5AC80A6-782E-4716-8044-39598C60CFBF") ICorProfilerInfo8 : public ICorProfilerInfo7 { public: - virtual HRESULT STDMETHODCALLTYPE IsFunctionDynamic( + virtual HRESULT STDMETHODCALLTYPE IsFunctionDynamic( /* [in] */ FunctionID functionId, /* [out] */ BOOL *isDynamic) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP3( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP3( /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *functionId, /* [out] */ ReJITID *pReJitId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDynamicFunctionInfo( + + virtual HRESULT STDMETHODCALLTYPE GetDynamicFunctionInfo( /* [in] */ FunctionID functionId, /* [out] */ ModuleID *moduleId, /* [out] */ PCCOR_SIGNATURE *ppvSig, @@ -15127,218 +16665,255 @@ EXTERN_C const IID IID_ICorProfilerInfo8; /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, /* [out] */ WCHAR wszName[ ]) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo8Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo8 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo8 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo8 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo8 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo8 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo8 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo8 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo8 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo8 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo8 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo8 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo8 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo8 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo8 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo8 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo8 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo8 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo8 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo8 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo8 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo8 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo8 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -15346,14 +16921,16 @@ EXTERN_C const IID IID_ICorProfilerInfo8; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo8 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo8 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -15363,22 +16940,25 @@ EXTERN_C const IID IID_ICorProfilerInfo8; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo8 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo8 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -15387,23 +16967,26 @@ EXTERN_C const IID IID_ICorProfilerInfo8; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -15411,134 +16994,157 @@ EXTERN_C const IID IID_ICorProfilerInfo8; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo8 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo8 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo8 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo8 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo8 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo8 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo8 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo8 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo8 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo8 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo8 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo8 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo8 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -15548,140 +17154,162 @@ EXTERN_C const IID IID_ICorProfilerInfo8; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo8 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo8 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo8 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo8 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo8 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo8 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo8 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo8 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo8 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo8 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo8 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes); - - HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( ICorProfilerInfo8 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead); - - HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, IsFunctionDynamic) + HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *isDynamic); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetFunctionFromIP3) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( ICorProfilerInfo8 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *functionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetDynamicFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( ICorProfilerInfo8 * This, /* [in] */ FunctionID functionId, /* [out] */ ModuleID *moduleId, @@ -15690,7 +17318,7 @@ EXTERN_C const IID IID_ICorProfilerInfo8; /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, /* [out] */ WCHAR wszName[ ]); - + END_INTERFACE } ICorProfilerInfo8Vtbl; @@ -15699,545 +17327,582 @@ EXTERN_C const IID IID_ICorProfilerInfo8; CONST_VTBL struct ICorProfilerInfo8Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo8_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo8_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo8_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo8_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo8_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo8_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo8_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo8_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo8_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo8_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo8_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo8_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo8_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo8_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo8_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo8_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo8_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo8_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo8_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo8_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo8_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo8_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo8_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo8_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo8_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo8_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo8_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo8_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo8_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo8_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo8_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo8_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo8_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo8_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo8_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo8_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo8_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo8_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo8_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo8_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo8_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo8_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo8_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo8_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo8_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo8_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo8_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo8_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo8_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo8_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo8_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo8_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo8_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo8_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo8_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo8_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo8_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo8_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo8_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo8_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo8_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo8_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo8_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo8_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo8_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo8_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo8_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo8_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo8_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo8_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo8_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo8_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo8_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo8_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo8_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo8_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo8_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo8_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo8_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo8_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo8_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo8_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo8_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo8_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo8_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo8_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo8_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo8_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo8_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo8_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo8_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo8_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo8_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo8_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo8_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo8_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo8_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo8_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo8_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo8_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo8_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo8_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo8_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo8_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo8_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo8_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo8_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo8_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo8_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo8_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo8_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo8_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo8_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo8_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo8_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo8_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo8_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo8_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo8_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo8_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo8_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo8_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo8_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo8_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo8_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo8_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo8_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo8_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo8_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo8_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo8_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo8_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo8_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo8_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo8_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo8_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo8_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo8_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo8_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo8_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo8_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo8_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo8_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo8_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo8_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo8_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo8_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo8_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo8_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo8_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo8_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo8_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo8_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo8_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo8_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo8_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo8_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo8_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo8_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo8_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) -#define ICorProfilerInfo8_ApplyMetaData(This,moduleId) \ - ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo8_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) -#define ICorProfilerInfo8_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ - ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) +#define ICorProfilerInfo8_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerInfo8_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ - ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) +#define ICorProfilerInfo8_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) -#define ICorProfilerInfo8_IsFunctionDynamic(This,functionId,isDynamic) \ - ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) +#define ICorProfilerInfo8_IsFunctionDynamic(This,functionId,isDynamic) \ + ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) -#define ICorProfilerInfo8_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) +#define ICorProfilerInfo8_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) -#define ICorProfilerInfo8_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ - ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) +#define ICorProfilerInfo8_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ + ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo8_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo8_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo9_INTERFACE_DEFINED__ #define __ICorProfilerInfo9_INTERFACE_DEFINED__ /* interface ICorProfilerInfo9 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo9; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("008170DB-F8CC-4796-9A51-DC8AA0B47012") ICorProfilerInfo9 : public ICorProfilerInfo8 { public: - virtual HRESULT STDMETHODCALLTYPE GetNativeCodeStartAddresses( + virtual HRESULT STDMETHODCALLTYPE GetNativeCodeStartAddresses( FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping3( + + virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping3( UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCodeInfo4( + + virtual HRESULT STDMETHODCALLTYPE GetCodeInfo4( UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32 *pcCodeInfos, COR_PRF_CODE_INFO codeInfos[ ]) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo9Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo9 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo9 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo9 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo9 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo9 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo9 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo9 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo9 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo9 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo9 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo9 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo9 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo9 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo9 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo9 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo9 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo9 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo9 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo9 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo9 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo9 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo9 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -16245,14 +17910,16 @@ EXTERN_C const IID IID_ICorProfilerInfo9; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo9 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo9 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -16262,22 +17929,25 @@ EXTERN_C const IID IID_ICorProfilerInfo9; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo9 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo9 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -16286,23 +17956,26 @@ EXTERN_C const IID IID_ICorProfilerInfo9; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -16310,134 +17983,157 @@ EXTERN_C const IID IID_ICorProfilerInfo9; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo9 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo9 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo9 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo9 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo9 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo9 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo9 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo9 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo9 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo9 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo9 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo9 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo9 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -16447,140 +18143,162 @@ EXTERN_C const IID IID_ICorProfilerInfo9; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo9 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo9 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo9 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo9 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo9 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo9 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo9 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo9 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo9 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo9 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo9 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes); - - HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( ICorProfilerInfo9 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead); - - HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, IsFunctionDynamic) + HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *isDynamic); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetFunctionFromIP3) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( ICorProfilerInfo9 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *functionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetDynamicFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( ICorProfilerInfo9 * This, /* [in] */ FunctionID functionId, /* [out] */ ModuleID *moduleId, @@ -16589,29 +18307,32 @@ EXTERN_C const IID IID_ICorProfilerInfo9; /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, /* [out] */ WCHAR wszName[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetNativeCodeStartAddresses) + HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( ICorProfilerInfo9 * This, FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetILToNativeMapping3) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( ICorProfilerInfo9 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetCodeInfo4) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( ICorProfilerInfo9 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32 *pcCodeInfos, COR_PRF_CODE_INFO codeInfos[ ]); - + END_INTERFACE } ICorProfilerInfo9Vtbl; @@ -16620,558 +18341,595 @@ EXTERN_C const IID IID_ICorProfilerInfo9; CONST_VTBL struct ICorProfilerInfo9Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo9_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo9_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo9_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo9_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo9_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo9_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo9_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo9_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo9_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo9_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo9_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo9_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo9_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo9_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo9_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo9_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo9_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo9_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo9_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo9_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo9_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo9_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo9_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo9_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo9_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo9_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo9_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo9_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo9_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo9_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo9_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo9_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo9_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo9_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo9_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo9_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo9_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo9_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo9_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo9_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo9_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo9_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo9_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo9_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo9_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo9_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo9_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo9_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo9_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo9_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo9_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo9_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo9_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo9_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo9_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo9_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo9_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo9_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo9_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo9_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo9_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo9_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo9_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo9_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo9_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo9_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo9_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo9_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo9_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo9_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo9_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo9_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo9_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo9_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo9_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo9_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo9_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo9_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo9_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo9_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo9_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo9_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo9_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo9_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo9_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo9_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo9_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo9_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo9_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo9_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo9_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo9_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo9_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo9_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo9_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo9_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo9_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo9_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo9_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo9_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo9_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo9_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo9_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo9_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo9_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo9_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo9_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo9_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo9_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo9_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo9_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo9_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo9_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo9_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo9_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo9_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo9_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo9_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo9_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo9_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo9_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo9_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo9_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo9_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo9_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo9_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo9_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo9_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo9_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo9_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo9_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo9_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo9_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo9_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo9_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo9_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo9_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo9_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo9_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo9_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo9_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo9_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo9_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo9_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo9_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo9_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo9_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo9_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo9_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo9_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo9_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo9_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo9_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo9_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo9_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo9_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo9_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo9_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo9_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo9_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo9_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) -#define ICorProfilerInfo9_ApplyMetaData(This,moduleId) \ - ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo9_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) -#define ICorProfilerInfo9_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ - ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) +#define ICorProfilerInfo9_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerInfo9_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ - ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) +#define ICorProfilerInfo9_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) -#define ICorProfilerInfo9_IsFunctionDynamic(This,functionId,isDynamic) \ - ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) +#define ICorProfilerInfo9_IsFunctionDynamic(This,functionId,isDynamic) \ + ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) -#define ICorProfilerInfo9_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) +#define ICorProfilerInfo9_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) -#define ICorProfilerInfo9_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ - ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) +#define ICorProfilerInfo9_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ + ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) -#define ICorProfilerInfo9_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ - ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) +#define ICorProfilerInfo9_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ + ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) -#define ICorProfilerInfo9_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) +#define ICorProfilerInfo9_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) -#define ICorProfilerInfo9_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo9_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo9_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo9_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo10_INTERFACE_DEFINED__ #define __ICorProfilerInfo10_INTERFACE_DEFINED__ /* interface ICorProfilerInfo10 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo10; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("2F1B5152-C869-40C9-AA5F-3ABE026BD720") ICorProfilerInfo10 : public ICorProfilerInfo9 { public: - virtual HRESULT STDMETHODCALLTYPE EnumerateObjectReferences( + virtual HRESULT STDMETHODCALLTYPE EnumerateObjectReferences( ObjectID objectId, ObjectReferenceCallback callback, void *clientData) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsFrozenObject( + + virtual HRESULT STDMETHODCALLTYPE IsFrozenObject( ObjectID objectId, BOOL *pbFrozen) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLOHObjectSizeThreshold( + + virtual HRESULT STDMETHODCALLTYPE GetLOHObjectSizeThreshold( DWORD *pThreshold) = 0; - - virtual HRESULT STDMETHODCALLTYPE RequestReJITWithInliners( + + virtual HRESULT STDMETHODCALLTYPE RequestReJITWithInliners( /* [in] */ DWORD dwRejitFlags, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]) = 0; - + virtual HRESULT STDMETHODCALLTYPE SuspendRuntime( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE ResumeRuntime( void) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo10Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo10 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo10 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo10 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo10 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo10 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo10 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo10 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo10 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo10 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo10 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo10 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo10 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo10 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo10 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo10 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo10 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo10 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo10 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo10 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo10 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo10 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo10 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -17179,14 +18937,16 @@ EXTERN_C const IID IID_ICorProfilerInfo10; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo10 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo10 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -17196,22 +18956,25 @@ EXTERN_C const IID IID_ICorProfilerInfo10; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo10 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo10 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -17220,23 +18983,26 @@ EXTERN_C const IID IID_ICorProfilerInfo10; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -17244,134 +19010,157 @@ EXTERN_C const IID IID_ICorProfilerInfo10; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo10 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo10 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo10 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo10 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo10 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo10 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo10 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo10 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo10 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo10 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo10 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo10 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo10 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -17381,140 +19170,162 @@ EXTERN_C const IID IID_ICorProfilerInfo10; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo10 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo10 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo10 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo10 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo10 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo10 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo10 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo10 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo10 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo10 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo10 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes); - - HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( ICorProfilerInfo10 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead); - - HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, IsFunctionDynamic) + HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *isDynamic); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetFunctionFromIP3) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( ICorProfilerInfo10 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *functionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetDynamicFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( ICorProfilerInfo10 * This, /* [in] */ FunctionID functionId, /* [out] */ ModuleID *moduleId, @@ -17523,57 +19334,66 @@ EXTERN_C const IID IID_ICorProfilerInfo10; /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, /* [out] */ WCHAR wszName[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetNativeCodeStartAddresses) + HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( ICorProfilerInfo10 * This, FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetILToNativeMapping3) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( ICorProfilerInfo10 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetCodeInfo4) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( ICorProfilerInfo10 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32 *pcCodeInfos, COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, EnumerateObjectReferences) + HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( ICorProfilerInfo10 * This, ObjectID objectId, ObjectReferenceCallback callback, void *clientData); - - HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, IsFrozenObject) + HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( ICorProfilerInfo10 * This, ObjectID objectId, BOOL *pbFrozen); - - HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, GetLOHObjectSizeThreshold) + HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( ICorProfilerInfo10 * This, DWORD *pThreshold); - - HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, RequestReJITWithInliners) + HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( ICorProfilerInfo10 * This, /* [in] */ DWORD dwRejitFlags, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, SuspendRuntime) + HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( ICorProfilerInfo10 * This); - - HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, ResumeRuntime) + HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( ICorProfilerInfo10 * This); - + END_INTERFACE } ICorProfilerInfo10Vtbl; @@ -17582,566 +19402,603 @@ EXTERN_C const IID IID_ICorProfilerInfo10; CONST_VTBL struct ICorProfilerInfo10Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo10_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo10_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo10_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo10_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo10_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo10_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo10_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo10_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo10_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo10_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo10_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo10_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo10_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo10_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo10_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo10_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo10_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo10_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo10_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo10_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo10_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo10_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo10_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo10_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo10_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo10_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo10_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo10_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo10_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo10_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo10_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo10_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo10_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo10_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo10_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo10_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo10_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo10_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo10_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo10_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo10_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo10_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo10_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo10_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo10_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo10_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo10_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo10_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo10_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo10_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo10_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo10_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo10_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo10_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo10_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo10_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo10_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo10_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo10_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo10_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo10_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo10_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo10_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo10_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo10_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo10_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo10_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo10_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo10_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo10_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo10_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo10_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo10_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo10_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo10_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo10_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo10_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo10_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo10_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo10_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo10_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo10_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo10_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo10_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo10_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo10_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo10_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo10_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo10_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo10_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo10_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo10_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo10_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo10_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo10_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo10_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo10_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo10_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo10_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo10_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo10_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo10_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo10_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo10_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo10_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo10_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo10_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo10_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo10_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo10_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo10_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo10_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo10_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo10_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo10_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo10_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo10_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo10_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo10_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo10_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo10_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo10_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo10_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo10_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo10_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo10_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo10_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo10_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo10_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo10_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo10_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo10_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo10_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo10_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo10_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo10_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo10_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo10_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo10_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo10_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo10_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo10_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo10_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo10_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo10_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo10_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo10_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo10_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo10_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo10_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo10_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo10_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo10_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo10_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo10_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo10_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo10_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo10_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo10_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo10_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo10_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) -#define ICorProfilerInfo10_ApplyMetaData(This,moduleId) \ - ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo10_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) -#define ICorProfilerInfo10_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ - ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) +#define ICorProfilerInfo10_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerInfo10_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ - ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) +#define ICorProfilerInfo10_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) -#define ICorProfilerInfo10_IsFunctionDynamic(This,functionId,isDynamic) \ - ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) +#define ICorProfilerInfo10_IsFunctionDynamic(This,functionId,isDynamic) \ + ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) -#define ICorProfilerInfo10_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) +#define ICorProfilerInfo10_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) -#define ICorProfilerInfo10_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ - ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) +#define ICorProfilerInfo10_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ + ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) -#define ICorProfilerInfo10_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ - ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) +#define ICorProfilerInfo10_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ + ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) -#define ICorProfilerInfo10_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) +#define ICorProfilerInfo10_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) -#define ICorProfilerInfo10_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo10_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo10_EnumerateObjectReferences(This,objectId,callback,clientData) \ - ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) +#define ICorProfilerInfo10_EnumerateObjectReferences(This,objectId,callback,clientData) \ + ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) -#define ICorProfilerInfo10_IsFrozenObject(This,objectId,pbFrozen) \ - ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) +#define ICorProfilerInfo10_IsFrozenObject(This,objectId,pbFrozen) \ + ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) -#define ICorProfilerInfo10_GetLOHObjectSizeThreshold(This,pThreshold) \ - ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) +#define ICorProfilerInfo10_GetLOHObjectSizeThreshold(This,pThreshold) \ + ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) -#define ICorProfilerInfo10_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo10_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo10_SuspendRuntime(This) \ - ( (This)->lpVtbl -> SuspendRuntime(This) ) +#define ICorProfilerInfo10_SuspendRuntime(This) \ + ( (This)->lpVtbl -> SuspendRuntime(This) ) -#define ICorProfilerInfo10_ResumeRuntime(This) \ - ( (This)->lpVtbl -> ResumeRuntime(This) ) +#define ICorProfilerInfo10_ResumeRuntime(This) \ + ( (This)->lpVtbl -> ResumeRuntime(This) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo10_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo10_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo11_INTERFACE_DEFINED__ #define __ICorProfilerInfo11_INTERFACE_DEFINED__ /* interface ICorProfilerInfo11 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo11; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("06398876-8987-4154-B621-40A00D6E4D04") ICorProfilerInfo11 : public ICorProfilerInfo10 { public: - virtual HRESULT STDMETHODCALLTYPE GetEnvironmentVariable( + virtual HRESULT STDMETHODCALLTYPE GetEnvironmentVariable( /* [string][in] */ const WCHAR *szName, /* [in] */ ULONG cchValue, /* [out] */ ULONG *pcchValue, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchValue, *pcchValue) WCHAR szValue[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEnvironmentVariable( + + virtual HRESULT STDMETHODCALLTYPE SetEnvironmentVariable( /* [string][in] */ const WCHAR *szName, /* [string][in] */ const WCHAR *szValue) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo11Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo11 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo11 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo11 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo11 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo11 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo11 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo11 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo11 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo11 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo11 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo11 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo11 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo11 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo11 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo11 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo11 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo11 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo11 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo11 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo11 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo11 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo11 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -18149,14 +20006,16 @@ EXTERN_C const IID IID_ICorProfilerInfo11; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo11 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo11 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -18166,22 +20025,25 @@ EXTERN_C const IID IID_ICorProfilerInfo11; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo11 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo11 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -18190,23 +20052,26 @@ EXTERN_C const IID IID_ICorProfilerInfo11; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -18214,134 +20079,157 @@ EXTERN_C const IID IID_ICorProfilerInfo11; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo11 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo11 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo11 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo11 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo11 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo11 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo11 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo11 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo11 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo11 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo11 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo11 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo11 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -18351,140 +20239,162 @@ EXTERN_C const IID IID_ICorProfilerInfo11; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo11 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo11 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo11 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo11 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo11 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo11 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo11 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo11 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo11 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo11 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo11 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes); - - HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( ICorProfilerInfo11 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead); - - HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, IsFunctionDynamic) + HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *isDynamic); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetFunctionFromIP3) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( ICorProfilerInfo11 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *functionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetDynamicFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( ICorProfilerInfo11 * This, /* [in] */ FunctionID functionId, /* [out] */ ModuleID *moduleId, @@ -18493,70 +20403,81 @@ EXTERN_C const IID IID_ICorProfilerInfo11; /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, /* [out] */ WCHAR wszName[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetNativeCodeStartAddresses) + HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( ICorProfilerInfo11 * This, FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetILToNativeMapping3) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( ICorProfilerInfo11 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetCodeInfo4) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( ICorProfilerInfo11 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32 *pcCodeInfos, COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, EnumerateObjectReferences) + HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( ICorProfilerInfo11 * This, ObjectID objectId, ObjectReferenceCallback callback, void *clientData); - - HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, IsFrozenObject) + HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( ICorProfilerInfo11 * This, ObjectID objectId, BOOL *pbFrozen); - - HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, GetLOHObjectSizeThreshold) + HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( ICorProfilerInfo11 * This, DWORD *pThreshold); - - HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, RequestReJITWithInliners) + HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( ICorProfilerInfo11 * This, /* [in] */ DWORD dwRejitFlags, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, SuspendRuntime) + HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( ICorProfilerInfo11 * This); - - HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, ResumeRuntime) + HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( ICorProfilerInfo11 * This); - - HRESULT ( STDMETHODCALLTYPE *GetEnvironmentVariable )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, GetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *GetEnvironmentVariable )( ICorProfilerInfo11 * This, /* [string][in] */ const WCHAR *szName, /* [in] */ ULONG cchValue, /* [out] */ ULONG *pcchValue, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchValue, *pcchValue) WCHAR szValue[ ]); - - HRESULT ( STDMETHODCALLTYPE *SetEnvironmentVariable )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, SetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *SetEnvironmentVariable )( ICorProfilerInfo11 * This, /* [string][in] */ const WCHAR *szName, /* [string][in] */ const WCHAR *szValue); - + END_INTERFACE } ICorProfilerInfo11Vtbl; @@ -18565,376 +20486,376 @@ EXTERN_C const IID IID_ICorProfilerInfo11; CONST_VTBL struct ICorProfilerInfo11Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo11_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo11_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo11_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo11_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo11_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo11_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo11_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo11_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo11_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo11_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo11_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo11_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo11_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo11_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo11_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo11_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo11_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo11_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo11_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo11_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo11_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo11_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo11_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo11_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo11_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo11_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo11_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo11_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo11_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo11_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo11_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo11_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo11_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo11_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo11_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo11_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo11_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo11_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo11_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo11_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo11_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo11_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo11_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo11_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo11_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo11_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo11_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo11_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo11_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo11_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo11_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo11_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo11_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo11_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo11_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo11_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo11_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo11_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo11_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo11_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo11_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo11_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo11_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo11_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo11_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo11_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo11_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo11_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo11_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo11_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo11_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo11_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo11_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo11_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo11_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo11_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo11_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo11_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo11_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo11_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo11_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo11_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo11_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo11_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo11_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo11_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo11_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo11_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo11_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo11_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo11_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo11_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo11_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo11_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo11_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo11_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo11_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo11_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo11_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo11_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo11_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo11_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo11_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo11_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo11_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo11_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo11_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo11_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo11_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo11_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo11_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo11_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo11_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo11_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo11_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo11_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo11_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo11_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo11_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo11_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo11_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo11_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo11_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo11_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo11_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo11_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo11_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo11_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo11_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo11_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo11_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo11_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo11_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo11_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo11_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo11_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo11_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo11_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo11_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo11_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo11_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo11_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo11_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo11_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo11_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo11_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo11_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo11_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo11_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo11_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo11_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo11_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo11_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo11_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo11_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo11_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo11_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo11_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo11_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo11_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo11_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) -#define ICorProfilerInfo11_ApplyMetaData(This,moduleId) \ - ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo11_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) -#define ICorProfilerInfo11_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ - ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) +#define ICorProfilerInfo11_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerInfo11_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ - ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) +#define ICorProfilerInfo11_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) -#define ICorProfilerInfo11_IsFunctionDynamic(This,functionId,isDynamic) \ - ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) +#define ICorProfilerInfo11_IsFunctionDynamic(This,functionId,isDynamic) \ + ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) -#define ICorProfilerInfo11_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) +#define ICorProfilerInfo11_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) -#define ICorProfilerInfo11_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ - ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) +#define ICorProfilerInfo11_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ + ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) -#define ICorProfilerInfo11_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ - ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) +#define ICorProfilerInfo11_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ + ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) -#define ICorProfilerInfo11_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) +#define ICorProfilerInfo11_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) -#define ICorProfilerInfo11_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo11_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo11_EnumerateObjectReferences(This,objectId,callback,clientData) \ - ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) +#define ICorProfilerInfo11_EnumerateObjectReferences(This,objectId,callback,clientData) \ + ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) -#define ICorProfilerInfo11_IsFrozenObject(This,objectId,pbFrozen) \ - ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) +#define ICorProfilerInfo11_IsFrozenObject(This,objectId,pbFrozen) \ + ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) -#define ICorProfilerInfo11_GetLOHObjectSizeThreshold(This,pThreshold) \ - ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) +#define ICorProfilerInfo11_GetLOHObjectSizeThreshold(This,pThreshold) \ + ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) -#define ICorProfilerInfo11_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo11_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo11_SuspendRuntime(This) \ - ( (This)->lpVtbl -> SuspendRuntime(This) ) +#define ICorProfilerInfo11_SuspendRuntime(This) \ + ( (This)->lpVtbl -> SuspendRuntime(This) ) -#define ICorProfilerInfo11_ResumeRuntime(This) \ - ( (This)->lpVtbl -> ResumeRuntime(This) ) +#define ICorProfilerInfo11_ResumeRuntime(This) \ + ( (This)->lpVtbl -> ResumeRuntime(This) ) -#define ICorProfilerInfo11_GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) \ - ( (This)->lpVtbl -> GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) ) +#define ICorProfilerInfo11_GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) \ + ( (This)->lpVtbl -> GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) ) -#define ICorProfilerInfo11_SetEnvironmentVariable(This,szName,szValue) \ - ( (This)->lpVtbl -> SetEnvironmentVariable(This,szName,szValue) ) +#define ICorProfilerInfo11_SetEnvironmentVariable(This,szName,szValue) \ + ( (This)->lpVtbl -> SetEnvironmentVariable(This,szName,szValue) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo11_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo11_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo12_INTERFACE_DEFINED__ #define __ICorProfilerInfo12_INTERFACE_DEFINED__ /* interface ICorProfilerInfo12 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo12; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("27b24ccd-1cb1-47c5-96ee-98190dc30959") ICorProfilerInfo12 : public ICorProfilerInfo11 { public: - virtual HRESULT STDMETHODCALLTYPE EventPipeStartSession( + virtual HRESULT STDMETHODCALLTYPE EventPipeStartSession( /* [in] */ UINT32 cProviderConfigs, /* [size_is][in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG pProviderConfigs[ ], /* [in] */ BOOL requestRundown, /* [out] */ EVENTPIPE_SESSION *pSession) = 0; - - virtual HRESULT STDMETHODCALLTYPE EventPipeAddProviderToSession( + + virtual HRESULT STDMETHODCALLTYPE EventPipeAddProviderToSession( /* [in] */ EVENTPIPE_SESSION session, /* [in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG providerConfig) = 0; - - virtual HRESULT STDMETHODCALLTYPE EventPipeStopSession( + + virtual HRESULT STDMETHODCALLTYPE EventPipeStopSession( /* [in] */ EVENTPIPE_SESSION session) = 0; - - virtual HRESULT STDMETHODCALLTYPE EventPipeCreateProvider( + + virtual HRESULT STDMETHODCALLTYPE EventPipeCreateProvider( /* [string][in] */ const WCHAR *providerName, /* [out] */ EVENTPIPE_PROVIDER *pProvider) = 0; - - virtual HRESULT STDMETHODCALLTYPE EventPipeGetProviderInfo( + + virtual HRESULT STDMETHODCALLTYPE EventPipeGetProviderInfo( /* [in] */ EVENTPIPE_PROVIDER provider, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR providerName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE EventPipeDefineEvent( + + virtual HRESULT STDMETHODCALLTYPE EventPipeDefineEvent( /* [in] */ EVENTPIPE_PROVIDER provider, /* [string][in] */ const WCHAR *eventName, /* [in] */ UINT32 eventID, @@ -18946,225 +20867,262 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [in] */ UINT32 cParamDescs, /* [size_is][in] */ COR_PRF_EVENTPIPE_PARAM_DESC pParamDescs[ ], /* [out] */ EVENTPIPE_EVENT *pEvent) = 0; - - virtual HRESULT STDMETHODCALLTYPE EventPipeWriteEvent( + + virtual HRESULT STDMETHODCALLTYPE EventPipeWriteEvent( /* [in] */ EVENTPIPE_EVENT event, /* [in] */ UINT32 cData, /* [size_is][in] */ COR_PRF_EVENT_DATA data[ ], /* [in] */ LPCGUID pActivityId, /* [in] */ LPCGUID pRelatedActivityId) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo12Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo12 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo12 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo12 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo12 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo12 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo12 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo12 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo12 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo12 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo12 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo12 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo12 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo12 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo12 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo12 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo12 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo12 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo12 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo12 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo12 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo12 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo12 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -19172,14 +21130,16 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo12 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo12 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -19189,22 +21149,25 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo12 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo12 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -19213,23 +21176,26 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -19237,134 +21203,157 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo12 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo12 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo12 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo12 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo12 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo12 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo12 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo12 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo12 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo12 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo12 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo12 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo12 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -19374,140 +21363,162 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo12 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo12 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo12 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo12 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo12 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo12 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo12 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo12 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo12 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo12 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo12 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes); - - HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( ICorProfilerInfo12 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead); - - HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, IsFunctionDynamic) + HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *isDynamic); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetFunctionFromIP3) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( ICorProfilerInfo12 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *functionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetDynamicFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( ICorProfilerInfo12 * This, /* [in] */ FunctionID functionId, /* [out] */ ModuleID *moduleId, @@ -19516,100 +21527,117 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, /* [out] */ WCHAR wszName[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetNativeCodeStartAddresses) + HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( ICorProfilerInfo12 * This, FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetILToNativeMapping3) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( ICorProfilerInfo12 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetCodeInfo4) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( ICorProfilerInfo12 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32 *pcCodeInfos, COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, EnumerateObjectReferences) + HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( ICorProfilerInfo12 * This, ObjectID objectId, ObjectReferenceCallback callback, void *clientData); - - HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, IsFrozenObject) + HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( ICorProfilerInfo12 * This, ObjectID objectId, BOOL *pbFrozen); - - HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, GetLOHObjectSizeThreshold) + HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( ICorProfilerInfo12 * This, DWORD *pThreshold); - - HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, RequestReJITWithInliners) + HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( ICorProfilerInfo12 * This, /* [in] */ DWORD dwRejitFlags, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, SuspendRuntime) + HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( ICorProfilerInfo12 * This); - - HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, ResumeRuntime) + HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( ICorProfilerInfo12 * This); - - HRESULT ( STDMETHODCALLTYPE *GetEnvironmentVariable )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, GetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *GetEnvironmentVariable )( ICorProfilerInfo12 * This, /* [string][in] */ const WCHAR *szName, /* [in] */ ULONG cchValue, /* [out] */ ULONG *pcchValue, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchValue, *pcchValue) WCHAR szValue[ ]); - - HRESULT ( STDMETHODCALLTYPE *SetEnvironmentVariable )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, SetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *SetEnvironmentVariable )( ICorProfilerInfo12 * This, /* [string][in] */ const WCHAR *szName, /* [string][in] */ const WCHAR *szValue); - - HRESULT ( STDMETHODCALLTYPE *EventPipeStartSession )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeStartSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeStartSession )( ICorProfilerInfo12 * This, /* [in] */ UINT32 cProviderConfigs, /* [size_is][in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG pProviderConfigs[ ], /* [in] */ BOOL requestRundown, /* [out] */ EVENTPIPE_SESSION *pSession); - - HRESULT ( STDMETHODCALLTYPE *EventPipeAddProviderToSession )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeAddProviderToSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeAddProviderToSession )( ICorProfilerInfo12 * This, /* [in] */ EVENTPIPE_SESSION session, /* [in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG providerConfig); - - HRESULT ( STDMETHODCALLTYPE *EventPipeStopSession )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeStopSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeStopSession )( ICorProfilerInfo12 * This, /* [in] */ EVENTPIPE_SESSION session); - - HRESULT ( STDMETHODCALLTYPE *EventPipeCreateProvider )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeCreateProvider) + HRESULT ( STDMETHODCALLTYPE *EventPipeCreateProvider )( ICorProfilerInfo12 * This, /* [string][in] */ const WCHAR *providerName, /* [out] */ EVENTPIPE_PROVIDER *pProvider); - - HRESULT ( STDMETHODCALLTYPE *EventPipeGetProviderInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeGetProviderInfo) + HRESULT ( STDMETHODCALLTYPE *EventPipeGetProviderInfo )( ICorProfilerInfo12 * This, /* [in] */ EVENTPIPE_PROVIDER provider, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR providerName[ ]); - - HRESULT ( STDMETHODCALLTYPE *EventPipeDefineEvent )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeDefineEvent) + HRESULT ( STDMETHODCALLTYPE *EventPipeDefineEvent )( ICorProfilerInfo12 * This, /* [in] */ EVENTPIPE_PROVIDER provider, /* [string][in] */ const WCHAR *eventName, @@ -19622,15 +21650,16 @@ EXTERN_C const IID IID_ICorProfilerInfo12; /* [in] */ UINT32 cParamDescs, /* [size_is][in] */ COR_PRF_EVENTPIPE_PARAM_DESC pParamDescs[ ], /* [out] */ EVENTPIPE_EVENT *pEvent); - - HRESULT ( STDMETHODCALLTYPE *EventPipeWriteEvent )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeWriteEvent) + HRESULT ( STDMETHODCALLTYPE *EventPipeWriteEvent )( ICorProfilerInfo12 * This, /* [in] */ EVENTPIPE_EVENT event, /* [in] */ UINT32 cData, /* [size_is][in] */ COR_PRF_EVENT_DATA data[ ], /* [in] */ LPCGUID pActivityId, /* [in] */ LPCGUID pRelatedActivityId); - + END_INTERFACE } ICorProfilerInfo12Vtbl; @@ -19639,595 +21668,633 @@ EXTERN_C const IID IID_ICorProfilerInfo12; CONST_VTBL struct ICorProfilerInfo12Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo12_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo12_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo12_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo12_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo12_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo12_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo12_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo12_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo12_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo12_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo12_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo12_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo12_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo12_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo12_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo12_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo12_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo12_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo12_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo12_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo12_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo12_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo12_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo12_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo12_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo12_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo12_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo12_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo12_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo12_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo12_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo12_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo12_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo12_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo12_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo12_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo12_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo12_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo12_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo12_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo12_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo12_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo12_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo12_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo12_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo12_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo12_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo12_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo12_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo12_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo12_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo12_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo12_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo12_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo12_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo12_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo12_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo12_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo12_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo12_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo12_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo12_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo12_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo12_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo12_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo12_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo12_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo12_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo12_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo12_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo12_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo12_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo12_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo12_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo12_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo12_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo12_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo12_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo12_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo12_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo12_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo12_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo12_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo12_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo12_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo12_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo12_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo12_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo12_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo12_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo12_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo12_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo12_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo12_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo12_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo12_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo12_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo12_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo12_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo12_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo12_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo12_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo12_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo12_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo12_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo12_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo12_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo12_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo12_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo12_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo12_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo12_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo12_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo12_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo12_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo12_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo12_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo12_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo12_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo12_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo12_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo12_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo12_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo12_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo12_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo12_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo12_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo12_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo12_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo12_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo12_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo12_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo12_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo12_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo12_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo12_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo12_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo12_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo12_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo12_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo12_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo12_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo12_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo12_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo12_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo12_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo12_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo12_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo12_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo12_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo12_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo12_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo12_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo12_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo12_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo12_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo12_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo12_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo12_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo12_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo12_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) -#define ICorProfilerInfo12_ApplyMetaData(This,moduleId) \ - ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo12_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) -#define ICorProfilerInfo12_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ - ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) +#define ICorProfilerInfo12_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerInfo12_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ - ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) +#define ICorProfilerInfo12_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) -#define ICorProfilerInfo12_IsFunctionDynamic(This,functionId,isDynamic) \ - ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) +#define ICorProfilerInfo12_IsFunctionDynamic(This,functionId,isDynamic) \ + ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) -#define ICorProfilerInfo12_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) +#define ICorProfilerInfo12_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) -#define ICorProfilerInfo12_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ - ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) +#define ICorProfilerInfo12_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ + ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) -#define ICorProfilerInfo12_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ - ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) +#define ICorProfilerInfo12_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ + ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) -#define ICorProfilerInfo12_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) +#define ICorProfilerInfo12_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) -#define ICorProfilerInfo12_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo12_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo12_EnumerateObjectReferences(This,objectId,callback,clientData) \ - ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) +#define ICorProfilerInfo12_EnumerateObjectReferences(This,objectId,callback,clientData) \ + ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) -#define ICorProfilerInfo12_IsFrozenObject(This,objectId,pbFrozen) \ - ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) +#define ICorProfilerInfo12_IsFrozenObject(This,objectId,pbFrozen) \ + ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) -#define ICorProfilerInfo12_GetLOHObjectSizeThreshold(This,pThreshold) \ - ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) +#define ICorProfilerInfo12_GetLOHObjectSizeThreshold(This,pThreshold) \ + ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) -#define ICorProfilerInfo12_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo12_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo12_SuspendRuntime(This) \ - ( (This)->lpVtbl -> SuspendRuntime(This) ) +#define ICorProfilerInfo12_SuspendRuntime(This) \ + ( (This)->lpVtbl -> SuspendRuntime(This) ) -#define ICorProfilerInfo12_ResumeRuntime(This) \ - ( (This)->lpVtbl -> ResumeRuntime(This) ) +#define ICorProfilerInfo12_ResumeRuntime(This) \ + ( (This)->lpVtbl -> ResumeRuntime(This) ) -#define ICorProfilerInfo12_GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) \ - ( (This)->lpVtbl -> GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) ) +#define ICorProfilerInfo12_GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) \ + ( (This)->lpVtbl -> GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) ) -#define ICorProfilerInfo12_SetEnvironmentVariable(This,szName,szValue) \ - ( (This)->lpVtbl -> SetEnvironmentVariable(This,szName,szValue) ) +#define ICorProfilerInfo12_SetEnvironmentVariable(This,szName,szValue) \ + ( (This)->lpVtbl -> SetEnvironmentVariable(This,szName,szValue) ) -#define ICorProfilerInfo12_EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) \ - ( (This)->lpVtbl -> EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) ) +#define ICorProfilerInfo12_EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) \ + ( (This)->lpVtbl -> EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) ) -#define ICorProfilerInfo12_EventPipeAddProviderToSession(This,session,providerConfig) \ - ( (This)->lpVtbl -> EventPipeAddProviderToSession(This,session,providerConfig) ) +#define ICorProfilerInfo12_EventPipeAddProviderToSession(This,session,providerConfig) \ + ( (This)->lpVtbl -> EventPipeAddProviderToSession(This,session,providerConfig) ) -#define ICorProfilerInfo12_EventPipeStopSession(This,session) \ - ( (This)->lpVtbl -> EventPipeStopSession(This,session) ) +#define ICorProfilerInfo12_EventPipeStopSession(This,session) \ + ( (This)->lpVtbl -> EventPipeStopSession(This,session) ) -#define ICorProfilerInfo12_EventPipeCreateProvider(This,providerName,pProvider) \ - ( (This)->lpVtbl -> EventPipeCreateProvider(This,providerName,pProvider) ) +#define ICorProfilerInfo12_EventPipeCreateProvider(This,providerName,pProvider) \ + ( (This)->lpVtbl -> EventPipeCreateProvider(This,providerName,pProvider) ) -#define ICorProfilerInfo12_EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) \ - ( (This)->lpVtbl -> EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) ) +#define ICorProfilerInfo12_EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) \ + ( (This)->lpVtbl -> EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) ) -#define ICorProfilerInfo12_EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) \ - ( (This)->lpVtbl -> EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) ) +#define ICorProfilerInfo12_EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) \ + ( (This)->lpVtbl -> EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) ) -#define ICorProfilerInfo12_EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) \ - ( (This)->lpVtbl -> EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) ) +#define ICorProfilerInfo12_EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) \ + ( (This)->lpVtbl -> EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo12_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo12_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerInfo13_INTERFACE_DEFINED__ #define __ICorProfilerInfo13_INTERFACE_DEFINED__ /* interface ICorProfilerInfo13 */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerInfo13; #if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("6e6c7ee2-0701-4ec2-9d29-2e8733b66934") + + MIDL_INTERFACE("6E6C7EE2-0701-4EC2-9D29-2E8733B66934") ICorProfilerInfo13 : public ICorProfilerInfo12 { public: - virtual HRESULT STDMETHODCALLTYPE CreateHandle( - /* [in] */ ObjectID object, - /* [in] */ COR_PRF_HANDLE_TYPE type, - /* [out] */ ObjectHandleID* pHandle) = 0; - - virtual HRESULT STDMETHODCALLTYPE DestroyHandle( + virtual HRESULT STDMETHODCALLTYPE CreateHandle( + /* [in] */ ObjectID object, + /* [in] */ COR_PRF_HANDLE_TYPE type, + /* [out] */ ObjectHandleID *pHandle) = 0; + + virtual HRESULT STDMETHODCALLTYPE DestroyHandle( /* [in] */ ObjectHandleID handle) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObjectIDFromHandle( + + virtual HRESULT STDMETHODCALLTYPE GetObjectIDFromHandle( /* [in] */ ObjectHandleID handle, - /* [out] */ ObjectID* pObject) = 0; + /* [out] */ ObjectID *pObject) = 0; + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerInfo13Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerInfo13 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerInfo13 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerInfo13 * This); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( ICorProfilerInfo13 * This, /* [in] */ ObjectID objectId, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, /* [out] */ ClassID *pClassId); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( ICorProfilerInfo13 * This, /* [out] */ DWORD *pdwEvents); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( ICorProfilerInfo13 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, /* [out] */ FunctionID *pFunctionId); - - HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( ICorProfilerInfo13 * This, /* [in] */ ThreadID threadId, /* [out] */ HANDLE *phThread); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorProfilerInfo13 * This, /* [in] */ ObjectID objectId, /* [out] */ ULONG *pcSize); - - HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, /* [out] */ ULONG *pcRank); - - HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( ICorProfilerInfo13 * This, /* [in] */ ThreadID threadId, /* [out] */ DWORD *pdwWin32ThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( ICorProfilerInfo13 * This, /* [out] */ ThreadID *pThreadId); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdTypeDef *pTypeDefToken); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( ICorProfilerInfo13 * This, /* [in] */ DWORD dwEvents); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( ICorProfilerInfo13 * This, /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, /* [in] */ FunctionTailcall *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( ICorProfilerInfo13 * This, /* [in] */ FunctionIDMapper *pFunc); - - HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, /* [out] */ mdToken *pToken); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId); - - HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppOut); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, /* [out] */ ULONG *pcbMethodSize); - - HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [out] */ IMethodMalloc **ppMalloc); - - HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, /* [in] */ LPCBYTE pbNewILMethodHeader); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( ICorProfilerInfo13 * This, /* [in] */ AppDomainID appDomainId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ ProcessID *pProcessId); - - HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( ICorProfilerInfo13 * This, /* [in] */ AssemblyID assemblyId, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AppDomainID *pAppDomainId, /* [out] */ ModuleID *pModuleId); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId); - - HRESULT ( STDMETHODCALLTYPE *ForceGC )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( ICorProfilerInfo13 * This); - - HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( ICorProfilerInfo13 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( ICorProfilerInfo13 * This, /* [out] */ IUnknown **ppicd); - - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorProfilerInfo13 * This, /* [in] */ ThreadID threadId, /* [out] */ ContextID *pContextId); - - HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( ICorProfilerInfo13 * This, /* [in] */ BOOL fThisThreadOnly, /* [out] */ DWORD *pdwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( ICorProfilerInfo13 * This, /* [in] */ DWORD dwProfilerContext); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( ICorProfilerInfo13 * This, /* [in] */ ThreadID thread, /* [in] */ StackSnapshotCallback *callback, @@ -20235,14 +22302,16 @@ EXTERN_C const IID IID_ICorProfilerInfo13; /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 contextSize); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( ICorProfilerInfo13 * This, /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, /* [in] */ FunctionTailcall2 *pFuncTailcall); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( ICorProfilerInfo13 * This, /* [in] */ FunctionID funcId, /* [in] */ COR_PRF_FRAME_INFO frameInfo, @@ -20252,22 +22321,25 @@ EXTERN_C const IID IID_ICorProfilerInfo13; /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( ICorProfilerInfo13 * This, /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( ICorProfilerInfo13 * This, /* [in] */ ClassID classID, /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, /* [out] */ ULONG *pulClassSize); - - HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, @@ -20276,23 +22348,26 @@ EXTERN_C const IID IID_ICorProfilerInfo13; /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, /* [out] */ ClassID typeArgs[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ ClassID *pClassID); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleID, /* [in] */ mdMethodDef funcDef, @@ -20300,134 +22375,157 @@ EXTERN_C const IID IID_ICorProfilerInfo13; /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[ ], /* [out] */ FunctionID *pFunctionID); - - HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleID, /* [out] */ ICorProfilerObjectEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( ICorProfilerInfo13 * This, /* [in] */ ObjectID objectId, /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[ ], /* [size_is][out] */ int pDimensionLowerBounds[ ], /* [out] */ BYTE **ppData); - - HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [out] */ ULONG32 *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( ICorProfilerInfo13 * This, /* [in] */ ThreadID threadId, /* [out] */ AppDomainID *pAppDomainId); - - HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); - - HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( ICorProfilerInfo13 * This, /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( ICorProfilerInfo13 * This, /* [in] */ ObjectID objectId, /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); - - HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( ICorProfilerInfo13 * This, /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( ICorProfilerInfo13 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( ICorProfilerInfo13 * This, /* [in] */ DWORD dwExpectedCompletionMilliseconds); - - HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( ICorProfilerInfo13 * This, /* [in] */ FunctionIDMapper2 *pFunc, /* [in] */ void *clientData); - - HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( ICorProfilerInfo13 * This, /* [out] */ ULONG *pStringLengthOffset, /* [out] */ ULONG *pBufferOffset); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( ICorProfilerInfo13 * This, /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, /* [in] */ FunctionTailcall3 *pFuncTailcall3); - - HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( ICorProfilerInfo13 * This, /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); - - HRESULT ( STDMETHODCALLTYPE *EnumModules )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( ICorProfilerInfo13 * This, /* [out] */ ICorProfilerModuleEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( ICorProfilerInfo13 * This, /* [out] */ USHORT *pClrInstanceId, /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, @@ -20437,140 +22535,162 @@ EXTERN_C const IID IID_ICorProfilerInfo13; /* [out] */ USHORT *pQFEVersion, /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( ICorProfilerInfo13 * This, /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, /* [out] */ void **ppAddress); - - HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [out] */ LPCBYTE *ppBaseLoadAddress, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], /* [out] */ AssemblyID *pAssemblyId, /* [out] */ DWORD *pdwModuleFlags); - - HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( ICorProfilerInfo13 * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( ICorProfilerInfo13 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( ICorProfilerInfo13 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( ICorProfilerInfo13 * This, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ], /* [size_is][out] */ HRESULT status[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionID, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( ICorProfilerInfo13 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( ICorProfilerInfo13 * This, /* [out] */ ICorProfilerFunctionEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( ICorProfilerInfo13 * This, /* [in] */ ObjectID objectId, /* [out] */ SIZE_T *pcSize); - - HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( ICorProfilerInfo13 * This, /* [out] */ DWORD *pdwEventsLow, /* [out] */ DWORD *pdwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( ICorProfilerInfo13 * This, /* [in] */ DWORD dwEventsLow, /* [in] */ DWORD dwEventsHigh); - - HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( ICorProfilerInfo13 * This, /* [in] */ ModuleID inlinersModuleId, /* [in] */ ModuleID inlineeModuleId, /* [in] */ mdMethodDef inlineeMethodId, /* [out] */ BOOL *incompleteData, /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId); - - HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [out] */ DWORD *pCountSymbolBytes); - - HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( ICorProfilerInfo13 * This, /* [in] */ ModuleID moduleId, /* [in] */ DWORD symbolsReadOffset, /* [out] */ BYTE *pSymbolBytes, /* [in] */ DWORD countSymbolBytes, /* [out] */ DWORD *pCountSymbolBytesRead); - - HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, IsFunctionDynamic) + HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [out] */ BOOL *isDynamic); - - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetFunctionFromIP3) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( ICorProfilerInfo13 * This, /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *functionId, /* [out] */ ReJITID *pReJitId); - - HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetDynamicFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( ICorProfilerInfo13 * This, /* [in] */ FunctionID functionId, /* [out] */ ModuleID *moduleId, @@ -20579,100 +22699,117 @@ EXTERN_C const IID IID_ICorProfilerInfo13; /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, /* [out] */ WCHAR wszName[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetNativeCodeStartAddresses) + HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( ICorProfilerInfo13 * This, FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetILToNativeMapping3) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( ICorProfilerInfo13 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - - HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetCodeInfo4) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( ICorProfilerInfo13 * This, UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32 *pcCodeInfos, COR_PRF_CODE_INFO codeInfos[ ]); - - HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, EnumerateObjectReferences) + HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( ICorProfilerInfo13 * This, ObjectID objectId, ObjectReferenceCallback callback, void *clientData); - - HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, IsFrozenObject) + HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( ICorProfilerInfo13 * This, ObjectID objectId, BOOL *pbFrozen); - - HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, GetLOHObjectSizeThreshold) + HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( ICorProfilerInfo13 * This, DWORD *pThreshold); - - HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, RequestReJITWithInliners) + HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( ICorProfilerInfo13 * This, /* [in] */ DWORD dwRejitFlags, /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[ ], /* [size_is][in] */ mdMethodDef methodIds[ ]); - - HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, SuspendRuntime) + HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( ICorProfilerInfo13 * This); - - HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, ResumeRuntime) + HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( ICorProfilerInfo13 * This); - - HRESULT ( STDMETHODCALLTYPE *GetEnvironmentVariable )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, GetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *GetEnvironmentVariable )( ICorProfilerInfo13 * This, /* [string][in] */ const WCHAR *szName, /* [in] */ ULONG cchValue, /* [out] */ ULONG *pcchValue, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchValue, *pcchValue) WCHAR szValue[ ]); - - HRESULT ( STDMETHODCALLTYPE *SetEnvironmentVariable )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, SetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *SetEnvironmentVariable )( ICorProfilerInfo13 * This, /* [string][in] */ const WCHAR *szName, /* [string][in] */ const WCHAR *szValue); - - HRESULT ( STDMETHODCALLTYPE *EventPipeStartSession )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeStartSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeStartSession )( ICorProfilerInfo13 * This, /* [in] */ UINT32 cProviderConfigs, /* [size_is][in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG pProviderConfigs[ ], /* [in] */ BOOL requestRundown, /* [out] */ EVENTPIPE_SESSION *pSession); - - HRESULT ( STDMETHODCALLTYPE *EventPipeAddProviderToSession )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeAddProviderToSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeAddProviderToSession )( ICorProfilerInfo13 * This, /* [in] */ EVENTPIPE_SESSION session, /* [in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG providerConfig); - - HRESULT ( STDMETHODCALLTYPE *EventPipeStopSession )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeStopSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeStopSession )( ICorProfilerInfo13 * This, /* [in] */ EVENTPIPE_SESSION session); - - HRESULT ( STDMETHODCALLTYPE *EventPipeCreateProvider )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeCreateProvider) + HRESULT ( STDMETHODCALLTYPE *EventPipeCreateProvider )( ICorProfilerInfo13 * This, /* [string][in] */ const WCHAR *providerName, /* [out] */ EVENTPIPE_PROVIDER *pProvider); - - HRESULT ( STDMETHODCALLTYPE *EventPipeGetProviderInfo )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeGetProviderInfo) + HRESULT ( STDMETHODCALLTYPE *EventPipeGetProviderInfo )( ICorProfilerInfo13 * This, /* [in] */ EVENTPIPE_PROVIDER provider, /* [in] */ ULONG cchName, /* [out] */ ULONG *pcchName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR providerName[ ]); - - HRESULT ( STDMETHODCALLTYPE *EventPipeDefineEvent )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeDefineEvent) + HRESULT ( STDMETHODCALLTYPE *EventPipeDefineEvent )( ICorProfilerInfo13 * This, /* [in] */ EVENTPIPE_PROVIDER provider, /* [string][in] */ const WCHAR *eventName, @@ -20685,30 +22822,34 @@ EXTERN_C const IID IID_ICorProfilerInfo13; /* [in] */ UINT32 cParamDescs, /* [size_is][in] */ COR_PRF_EVENTPIPE_PARAM_DESC pParamDescs[ ], /* [out] */ EVENTPIPE_EVENT *pEvent); - - HRESULT ( STDMETHODCALLTYPE *EventPipeWriteEvent )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeWriteEvent) + HRESULT ( STDMETHODCALLTYPE *EventPipeWriteEvent )( ICorProfilerInfo13 * This, /* [in] */ EVENTPIPE_EVENT event, /* [in] */ UINT32 cData, /* [size_is][in] */ COR_PRF_EVENT_DATA data[ ], /* [in] */ LPCGUID pActivityId, /* [in] */ LPCGUID pRelatedActivityId); - - HRESULT ( STDMETHODCALLTYPE CreateHandle )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo13, CreateHandle) + HRESULT ( STDMETHODCALLTYPE *CreateHandle )( ICorProfilerInfo13 * This, /* [in] */ ObjectID object, /* [in] */ COR_PRF_HANDLE_TYPE type, - /* [out] */ ObjectHandleID* pHandle); - - HRESULT ( STDMETHODCALLTYPE DestroyHandle )( + /* [out] */ ObjectHandleID *pHandle); + + DECLSPEC_XFGVIRT(ICorProfilerInfo13, DestroyHandle) + HRESULT ( STDMETHODCALLTYPE *DestroyHandle )( ICorProfilerInfo13 * This, /* [in] */ ObjectHandleID handle); - - HRESULT ( STDMETHODCALLTYPE GetObjectIDFromHandle )( + + DECLSPEC_XFGVIRT(ICorProfilerInfo13, GetObjectIDFromHandle) + HRESULT ( STDMETHODCALLTYPE *GetObjectIDFromHandle )( ICorProfilerInfo13 * This, /* [in] */ ObjectHandleID handle, - /* [out] */ ObjectID* pObject); - + /* [out] */ ObjectID *pObject); + END_INTERFACE } ICorProfilerInfo13Vtbl; @@ -20717,564 +22858,1794 @@ EXTERN_C const IID IID_ICorProfilerInfo13; CONST_VTBL struct ICorProfilerInfo13Vtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerInfo13_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerInfo13_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerInfo13_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerInfo13_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerInfo13_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo13_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerInfo13_GetClassFromObject(This,objectId,pClassId) \ - ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) +#define ICorProfilerInfo13_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) -#define ICorProfilerInfo13_GetClassFromToken(This,moduleId,typeDef,pClassId) \ - ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) +#define ICorProfilerInfo13_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) -#define ICorProfilerInfo13_GetCodeInfo(This,functionId,pStart,pcSize) \ - ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) +#define ICorProfilerInfo13_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) -#define ICorProfilerInfo13_GetEventMask(This,pdwEvents) \ - ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) +#define ICorProfilerInfo13_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) -#define ICorProfilerInfo13_GetFunctionFromIP(This,ip,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) +#define ICorProfilerInfo13_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) -#define ICorProfilerInfo13_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) +#define ICorProfilerInfo13_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) -#define ICorProfilerInfo13_GetHandleFromThread(This,threadId,phThread) \ - ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) +#define ICorProfilerInfo13_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) -#define ICorProfilerInfo13_GetObjectSize(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) +#define ICorProfilerInfo13_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) -#define ICorProfilerInfo13_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ - ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) +#define ICorProfilerInfo13_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) -#define ICorProfilerInfo13_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ - ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) +#define ICorProfilerInfo13_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) -#define ICorProfilerInfo13_GetCurrentThreadID(This,pThreadId) \ - ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) +#define ICorProfilerInfo13_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) -#define ICorProfilerInfo13_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ - ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) +#define ICorProfilerInfo13_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) -#define ICorProfilerInfo13_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ - ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) +#define ICorProfilerInfo13_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) -#define ICorProfilerInfo13_SetEventMask(This,dwEvents) \ - ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) +#define ICorProfilerInfo13_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) -#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo13_SetFunctionIDMapper(This,pFunc) \ - ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) +#define ICorProfilerInfo13_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) -#define ICorProfilerInfo13_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ - ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) +#define ICorProfilerInfo13_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) -#define ICorProfilerInfo13_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ - ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) +#define ICorProfilerInfo13_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) -#define ICorProfilerInfo13_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ - ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) +#define ICorProfilerInfo13_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) -#define ICorProfilerInfo13_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ - ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) +#define ICorProfilerInfo13_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) -#define ICorProfilerInfo13_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ - ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) +#define ICorProfilerInfo13_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) -#define ICorProfilerInfo13_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ - ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) +#define ICorProfilerInfo13_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) -#define ICorProfilerInfo13_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ - ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) +#define ICorProfilerInfo13_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) -#define ICorProfilerInfo13_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ - ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) +#define ICorProfilerInfo13_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) -#define ICorProfilerInfo13_SetFunctionReJIT(This,functionId) \ - ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) +#define ICorProfilerInfo13_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) -#define ICorProfilerInfo13_ForceGC(This) \ - ( (This)->lpVtbl -> ForceGC(This) ) +#define ICorProfilerInfo13_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) -#define ICorProfilerInfo13_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ - ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) +#define ICorProfilerInfo13_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) -#define ICorProfilerInfo13_GetInprocInspectionInterface(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) +#define ICorProfilerInfo13_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) -#define ICorProfilerInfo13_GetInprocInspectionIThisThread(This,ppicd) \ - ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) +#define ICorProfilerInfo13_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) -#define ICorProfilerInfo13_GetThreadContext(This,threadId,pContextId) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) +#define ICorProfilerInfo13_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) -#define ICorProfilerInfo13_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ - ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) +#define ICorProfilerInfo13_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) -#define ICorProfilerInfo13_EndInprocDebugging(This,dwProfilerContext) \ - ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) +#define ICorProfilerInfo13_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) -#define ICorProfilerInfo13_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) +#define ICorProfilerInfo13_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) -#define ICorProfilerInfo13_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ - ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) +#define ICorProfilerInfo13_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) -#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) +#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) -#define ICorProfilerInfo13_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) +#define ICorProfilerInfo13_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) -#define ICorProfilerInfo13_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo13_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo13_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ - ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) +#define ICorProfilerInfo13_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) -#define ICorProfilerInfo13_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ - ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) +#define ICorProfilerInfo13_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) -#define ICorProfilerInfo13_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo13_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo13_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ - ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) +#define ICorProfilerInfo13_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) -#define ICorProfilerInfo13_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ - ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) +#define ICorProfilerInfo13_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) -#define ICorProfilerInfo13_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ - ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) +#define ICorProfilerInfo13_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) -#define ICorProfilerInfo13_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ - ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) +#define ICorProfilerInfo13_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) -#define ICorProfilerInfo13_GetBoxClassLayout(This,classId,pBufferOffset) \ - ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) +#define ICorProfilerInfo13_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) -#define ICorProfilerInfo13_GetThreadAppDomain(This,threadId,pAppDomainId) \ - ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) +#define ICorProfilerInfo13_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) -#define ICorProfilerInfo13_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ - ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) +#define ICorProfilerInfo13_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) -#define ICorProfilerInfo13_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ - ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) +#define ICorProfilerInfo13_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) -#define ICorProfilerInfo13_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) +#define ICorProfilerInfo13_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) -#define ICorProfilerInfo13_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ - ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) +#define ICorProfilerInfo13_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) -#define ICorProfilerInfo13_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ - ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) +#define ICorProfilerInfo13_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) -#define ICorProfilerInfo13_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ - ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) +#define ICorProfilerInfo13_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) -#define ICorProfilerInfo13_GetObjectGeneration(This,objectId,range) \ - ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) +#define ICorProfilerInfo13_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) -#define ICorProfilerInfo13_GetNotifiedExceptionClauseInfo(This,pinfo) \ - ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) +#define ICorProfilerInfo13_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) -#define ICorProfilerInfo13_EnumJITedFunctions(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) +#define ICorProfilerInfo13_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) -#define ICorProfilerInfo13_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ - ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) +#define ICorProfilerInfo13_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) -#define ICorProfilerInfo13_SetFunctionIDMapper2(This,pFunc,clientData) \ - ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) +#define ICorProfilerInfo13_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) -#define ICorProfilerInfo13_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ - ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) +#define ICorProfilerInfo13_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) -#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) +#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) -#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ - ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) +#define ICorProfilerInfo13_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) -#define ICorProfilerInfo13_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ - ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) +#define ICorProfilerInfo13_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) -#define ICorProfilerInfo13_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ - ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) +#define ICorProfilerInfo13_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) -#define ICorProfilerInfo13_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ - ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) +#define ICorProfilerInfo13_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) -#define ICorProfilerInfo13_EnumModules(This,ppEnum) \ - ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) +#define ICorProfilerInfo13_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) -#define ICorProfilerInfo13_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ - ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) +#define ICorProfilerInfo13_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) -#define ICorProfilerInfo13_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ - ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) +#define ICorProfilerInfo13_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) -#define ICorProfilerInfo13_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ - ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) +#define ICorProfilerInfo13_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) -#define ICorProfilerInfo13_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ - ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) +#define ICorProfilerInfo13_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) -#define ICorProfilerInfo13_EnumThreads(This,ppEnum) \ - ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) +#define ICorProfilerInfo13_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) -#define ICorProfilerInfo13_InitializeCurrentThread(This) \ - ( (This)->lpVtbl -> InitializeCurrentThread(This) ) +#define ICorProfilerInfo13_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) -#define ICorProfilerInfo13_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo13_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo13_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ - ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) +#define ICorProfilerInfo13_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) -#define ICorProfilerInfo13_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo13_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo13_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) +#define ICorProfilerInfo13_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) -#define ICorProfilerInfo13_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ - ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) +#define ICorProfilerInfo13_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) -#define ICorProfilerInfo13_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) +#define ICorProfilerInfo13_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) -#define ICorProfilerInfo13_EnumJITedFunctions2(This,ppEnum) \ - ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) +#define ICorProfilerInfo13_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) -#define ICorProfilerInfo13_GetObjectSize2(This,objectId,pcSize) \ - ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) +#define ICorProfilerInfo13_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) -#define ICorProfilerInfo13_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ - ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) +#define ICorProfilerInfo13_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) -#define ICorProfilerInfo13_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ - ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) +#define ICorProfilerInfo13_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) -#define ICorProfilerInfo13_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ - ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) +#define ICorProfilerInfo13_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) -#define ICorProfilerInfo13_ApplyMetaData(This,moduleId) \ - ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo13_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) -#define ICorProfilerInfo13_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ - ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) +#define ICorProfilerInfo13_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerInfo13_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ - ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) +#define ICorProfilerInfo13_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) -#define ICorProfilerInfo13_IsFunctionDynamic(This,functionId,isDynamic) \ - ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) +#define ICorProfilerInfo13_IsFunctionDynamic(This,functionId,isDynamic) \ + ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) -#define ICorProfilerInfo13_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ - ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) +#define ICorProfilerInfo13_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) -#define ICorProfilerInfo13_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ - ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) +#define ICorProfilerInfo13_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ + ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) -#define ICorProfilerInfo13_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ - ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) +#define ICorProfilerInfo13_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ + ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) -#define ICorProfilerInfo13_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) +#define ICorProfilerInfo13_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) -#define ICorProfilerInfo13_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ - ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) +#define ICorProfilerInfo13_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) -#define ICorProfilerInfo13_EnumerateObjectReferences(This,objectId,callback,clientData) \ - ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) +#define ICorProfilerInfo13_EnumerateObjectReferences(This,objectId,callback,clientData) \ + ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) -#define ICorProfilerInfo13_IsFrozenObject(This,objectId,pbFrozen) \ - ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) +#define ICorProfilerInfo13_IsFrozenObject(This,objectId,pbFrozen) \ + ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) -#define ICorProfilerInfo13_GetLOHObjectSizeThreshold(This,pThreshold) \ - ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) +#define ICorProfilerInfo13_GetLOHObjectSizeThreshold(This,pThreshold) \ + ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) -#define ICorProfilerInfo13_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ - ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) +#define ICorProfilerInfo13_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) -#define ICorProfilerInfo13_SuspendRuntime(This) \ - ( (This)->lpVtbl -> SuspendRuntime(This) ) +#define ICorProfilerInfo13_SuspendRuntime(This) \ + ( (This)->lpVtbl -> SuspendRuntime(This) ) -#define ICorProfilerInfo13_ResumeRuntime(This) \ - ( (This)->lpVtbl -> ResumeRuntime(This) ) +#define ICorProfilerInfo13_ResumeRuntime(This) \ + ( (This)->lpVtbl -> ResumeRuntime(This) ) -#define ICorProfilerInfo13_GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) \ - ( (This)->lpVtbl -> GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) ) +#define ICorProfilerInfo13_GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) \ + ( (This)->lpVtbl -> GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) ) -#define ICorProfilerInfo13_SetEnvironmentVariable(This,szName,szValue) \ - ( (This)->lpVtbl -> SetEnvironmentVariable(This,szName,szValue) ) +#define ICorProfilerInfo13_SetEnvironmentVariable(This,szName,szValue) \ + ( (This)->lpVtbl -> SetEnvironmentVariable(This,szName,szValue) ) -#define ICorProfilerInfo13_EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) \ - ( (This)->lpVtbl -> EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) ) +#define ICorProfilerInfo13_EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) \ + ( (This)->lpVtbl -> EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) ) -#define ICorProfilerInfo13_EventPipeAddProviderToSession(This,session,providerConfig) \ - ( (This)->lpVtbl -> EventPipeAddProviderToSession(This,session,providerConfig) ) +#define ICorProfilerInfo13_EventPipeAddProviderToSession(This,session,providerConfig) \ + ( (This)->lpVtbl -> EventPipeAddProviderToSession(This,session,providerConfig) ) -#define ICorProfilerInfo13_EventPipeStopSession(This,session) \ - ( (This)->lpVtbl -> EventPipeStopSession(This,session) ) +#define ICorProfilerInfo13_EventPipeStopSession(This,session) \ + ( (This)->lpVtbl -> EventPipeStopSession(This,session) ) -#define ICorProfilerInfo13_EventPipeCreateProvider(This,providerName,pProvider) \ - ( (This)->lpVtbl -> EventPipeCreateProvider(This,providerName,pProvider) ) +#define ICorProfilerInfo13_EventPipeCreateProvider(This,providerName,pProvider) \ + ( (This)->lpVtbl -> EventPipeCreateProvider(This,providerName,pProvider) ) -#define ICorProfilerInfo13_EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) \ - ( (This)->lpVtbl -> EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) ) +#define ICorProfilerInfo13_EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) \ + ( (This)->lpVtbl -> EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) ) -#define ICorProfilerInfo13_EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) \ - ( (This)->lpVtbl -> EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) ) +#define ICorProfilerInfo13_EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) \ + ( (This)->lpVtbl -> EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) ) -#define ICorProfilerInfo13_EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) \ - ( (This)->lpVtbl -> EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) ) +#define ICorProfilerInfo13_EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) \ + ( (This)->lpVtbl -> EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) ) -#define ICorProfilerInfo13_CreateHandle(This,object,type,pHandle) \ - ( (This)->lpVtbl -> CreateHandle(This,object,type,pHandle) ) -#define ICorProfilerInfo13_DestroyHandle(This,handle) \ - ( (This)->lpVtbl -> DestroyHandle(This,handle) ) - -#define ICorProfilerInfo13_GetObjectIDFromHandle(This,handle,pObject) \ - ( (This)->lpVtbl -> GetObjectIDFromHandle(This,handle,pObject) ) +#define ICorProfilerInfo13_CreateHandle(This,object,type,pHandle) \ + ( (This)->lpVtbl -> CreateHandle(This,object,type,pHandle) ) +#define ICorProfilerInfo13_DestroyHandle(This,handle) \ + ( (This)->lpVtbl -> DestroyHandle(This,handle) ) +#define ICorProfilerInfo13_GetObjectIDFromHandle(This,handle,pObject) \ + ( (This)->lpVtbl -> GetObjectIDFromHandle(This,handle,pObject) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerInfo13_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerInfo13_INTERFACE_DEFINED__ */ -#ifndef __ICorProfilerMethodEnum_INTERFACE_DEFINED__ -#define __ICorProfilerMethodEnum_INTERFACE_DEFINED__ +#ifndef __ICorProfilerInfo14_INTERFACE_DEFINED__ +#define __ICorProfilerInfo14_INTERFACE_DEFINED__ -/* interface ICorProfilerMethodEnum */ -/* [local][unique][uuid][object] */ +/* interface ICorProfilerInfo14 */ +/* [local][unique][uuid][object] */ -EXTERN_C const IID IID_ICorProfilerMethodEnum; +EXTERN_C const IID IID_ICorProfilerInfo14; #if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("FCCEE788-0088-454B-A811-C99F298D1942") - ICorProfilerMethodEnum : public IUnknown + + MIDL_INTERFACE("F460E352-D76D-4FE9-835F-F6AF9D6E862D") + ICorProfilerInfo14 : public ICorProfilerInfo13 { public: - virtual HRESULT STDMETHODCALLTYPE Skip( - /* [in] */ ULONG celt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( - /* [out] */ ICorProfilerMethodEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( - /* [out] */ ULONG *pcelt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Next( - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ COR_PRF_METHOD elements[ ], - /* [out] */ ULONG *pceltFetched) = 0; - + virtual HRESULT STDMETHODCALLTYPE EnumerateNonGCObjects( + /* [out] */ ICorProfilerObjectEnum **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetNonGCHeapBounds( + /* [in] */ ULONG cObjectRanges, + /* [out] */ ULONG *pcObjectRanges, + /* [length_is][size_is][out] */ COR_PRF_NONGC_HEAP_RANGE ranges[ ]) = 0; + }; + + +#else /* C style interface */ - -#else /* C style interface */ - - typedef struct ICorProfilerMethodEnumVtbl + typedef struct ICorProfilerInfo14Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorProfilerMethodEnum * This, + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ICorProfilerInfo14 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( + ICorProfilerInfo14 * This); + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( + ICorProfilerInfo14 * This); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromObject) + HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectID objectId, + /* [out] */ ClassID *pClassId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassFromToken) + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [in] */ mdTypeDef typeDef, + /* [out] */ ClassID *pClassId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCodeInfo) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [out] */ LPCBYTE *pStart, + /* [out] */ ULONG *pcSize); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetEventMask) + HRESULT ( STDMETHODCALLTYPE *GetEventMask )( + ICorProfilerInfo14 * This, + /* [out] */ DWORD *pdwEvents); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromIP) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )( + ICorProfilerInfo14 * This, + /* [in] */ LPCBYTE ip, + /* [out] */ FunctionID *pFunctionId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionFromToken) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [in] */ mdToken token, + /* [out] */ FunctionID *pFunctionId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetHandleFromThread) + HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )( + ICorProfilerInfo14 * This, + /* [in] */ ThreadID threadId, + /* [out] */ HANDLE *phThread); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetObjectSize) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectID objectId, + /* [out] */ ULONG *pcSize); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, IsArrayClass) + HRESULT ( STDMETHODCALLTYPE *IsArrayClass )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [out] */ CorElementType *pBaseElemType, + /* [out] */ ClassID *pBaseClassId, + /* [out] */ ULONG *pcRank); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadInfo) + HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )( + ICorProfilerInfo14 * This, + /* [in] */ ThreadID threadId, + /* [out] */ DWORD *pdwWin32ThreadId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetCurrentThreadID) + HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )( + ICorProfilerInfo14 * This, + /* [out] */ ThreadID *pThreadId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetClassIDInfo) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [out] */ ModuleID *pModuleId, + /* [out] */ mdTypeDef *pTypeDefToken); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [out] */ ClassID *pClassId, + /* [out] */ ModuleID *pModuleId, + /* [out] */ mdToken *pToken); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEventMask) + HRESULT ( STDMETHODCALLTYPE *SetEventMask )( + ICorProfilerInfo14 * This, + /* [in] */ DWORD dwEvents); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetEnterLeaveFunctionHooks) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionEnter *pFuncEnter, + /* [in] */ FunctionLeave *pFuncLeave, + /* [in] */ FunctionTailcall *pFuncTailcall); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionIDMapper) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionIDMapper *pFunc); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetTokenAndMetaDataFromFunction) + HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ REFIID riid, + /* [out] */ IUnknown **ppImport, + /* [out] */ mdToken *pToken); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleInfo) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [out] */ LPCBYTE *ppBaseLoadAddress, + /* [in] */ ULONG cchName, + /* [out] */ ULONG *pcchName, + /* [annotation][out] */ + _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], + /* [out] */ AssemblyID *pAssemblyId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetModuleMetaData) + HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [in] */ DWORD dwOpenFlags, + /* [in] */ REFIID riid, + /* [out] */ IUnknown **ppOut); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [in] */ mdMethodDef methodId, + /* [out] */ LPCBYTE *ppMethodHeader, + /* [out] */ ULONG *pcbMethodSize); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILFunctionBodyAllocator) + HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [out] */ IMethodMalloc **ppMalloc); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILFunctionBody) + HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [in] */ mdMethodDef methodid, + /* [in] */ LPCBYTE pbNewILMethodHeader); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAppDomainInfo) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )( + ICorProfilerInfo14 * This, + /* [in] */ AppDomainID appDomainId, + /* [in] */ ULONG cchName, + /* [out] */ ULONG *pcchName, + /* [annotation][out] */ + _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], + /* [out] */ ProcessID *pProcessId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetAssemblyInfo) + HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )( + ICorProfilerInfo14 * This, + /* [in] */ AssemblyID assemblyId, + /* [in] */ ULONG cchName, + /* [out] */ ULONG *pcchName, + /* [annotation][out] */ + _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], + /* [out] */ AppDomainID *pAppDomainId, + /* [out] */ ModuleID *pModuleId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetFunctionReJIT) + HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, ForceGC) + HRESULT ( STDMETHODCALLTYPE *ForceGC )( + ICorProfilerInfo14 * This); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, SetILInstrumentedCodeMap) + HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ BOOL fStartJit, + /* [in] */ ULONG cILMapEntries, + /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionInterface) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )( + ICorProfilerInfo14 * This, + /* [out] */ IUnknown **ppicd); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetInprocInspectionIThisThread) + HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )( + ICorProfilerInfo14 * This, + /* [out] */ IUnknown **ppicd); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetThreadContext) + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + ICorProfilerInfo14 * This, + /* [in] */ ThreadID threadId, + /* [out] */ ContextID *pContextId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, BeginInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )( + ICorProfilerInfo14 * This, + /* [in] */ BOOL fThisThreadOnly, + /* [out] */ DWORD *pdwProfilerContext); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, EndInprocDebugging) + HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )( + ICorProfilerInfo14 * This, + /* [in] */ DWORD dwProfilerContext); + + DECLSPEC_XFGVIRT(ICorProfilerInfo, GetILToNativeMapping) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ ULONG32 cMap, + /* [out] */ ULONG32 *pcMap, + /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, DoStackSnapshot) + HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )( + ICorProfilerInfo14 * This, + /* [in] */ ThreadID thread, + /* [in] */ StackSnapshotCallback *callback, + /* [in] */ ULONG32 infoFlags, + /* [in] */ void *clientData, + /* [size_is][in] */ BYTE context[ ], + /* [in] */ ULONG32 contextSize); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, SetEnterLeaveFunctionHooks2) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionEnter2 *pFuncEnter, + /* [in] */ FunctionLeave2 *pFuncLeave, + /* [in] */ FunctionTailcall2 *pFuncTailcall); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionInfo2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID funcId, + /* [in] */ COR_PRF_FRAME_INFO frameInfo, + /* [out] */ ClassID *pClassId, + /* [out] */ ModuleID *pModuleId, + /* [out] */ mdToken *pToken, + /* [in] */ ULONG32 cTypeArgs, + /* [out] */ ULONG32 *pcTypeArgs, + /* [out] */ ClassID typeArgs[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStringLayout) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout )( + ICorProfilerInfo14 * This, + /* [out] */ ULONG *pBufferLengthOffset, + /* [out] */ ULONG *pStringLengthOffset, + /* [out] */ ULONG *pBufferOffset); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetClassLayout )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classID, + /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ], + /* [in] */ ULONG cFieldOffset, + /* [out] */ ULONG *pcFieldOffset, + /* [out] */ ULONG *pulClassSize); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassIDInfo2) + HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [out] */ ModuleID *pModuleId, + /* [out] */ mdTypeDef *pTypeDefToken, + /* [out] */ ClassID *pParentClassId, + /* [in] */ ULONG32 cNumTypeArgs, + /* [out] */ ULONG32 *pcNumTypeArgs, + /* [out] */ ClassID typeArgs[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetCodeInfo2) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionID, + /* [in] */ ULONG32 cCodeInfos, + /* [out] */ ULONG32 *pcCodeInfos, + /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetClassFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleID, + /* [in] */ mdTypeDef typeDef, + /* [in] */ ULONG32 cTypeArgs, + /* [size_is][in] */ ClassID typeArgs[ ], + /* [out] */ ClassID *pClassID); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetFunctionFromTokenAndTypeArgs) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleID, + /* [in] */ mdMethodDef funcDef, + /* [in] */ ClassID classId, + /* [in] */ ULONG32 cTypeArgs, + /* [size_is][in] */ ClassID typeArgs[ ], + /* [out] */ FunctionID *pFunctionID); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, EnumModuleFrozenObjects) + HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleID, + /* [out] */ ICorProfilerObjectEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetArrayObjectInfo) + HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectID objectId, + /* [in] */ ULONG32 cDimensions, + /* [size_is][out] */ ULONG32 pDimensionSizes[ ], + /* [size_is][out] */ int pDimensionLowerBounds[ ], + /* [out] */ BYTE **ppData); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetBoxClassLayout) + HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [out] */ ULONG32 *pBufferOffset); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadAppDomain) + HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )( + ICorProfilerInfo14 * This, + /* [in] */ ThreadID threadId, + /* [out] */ AppDomainID *pAppDomainId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetRVAStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [in] */ mdFieldDef fieldToken, + /* [out] */ void **ppAddress); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetAppDomainStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [in] */ mdFieldDef fieldToken, + /* [in] */ AppDomainID appDomainId, + /* [out] */ void **ppAddress); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetThreadStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [in] */ mdFieldDef fieldToken, + /* [in] */ ThreadID threadId, + /* [out] */ void **ppAddress); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetContextStaticAddress) + HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [in] */ mdFieldDef fieldToken, + /* [in] */ ContextID contextId, + /* [out] */ void **ppAddress); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetStaticFieldInfo) + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [in] */ mdFieldDef fieldToken, + /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetGenerationBounds) + HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )( + ICorProfilerInfo14 * This, + /* [in] */ ULONG cObjectRanges, + /* [out] */ ULONG *pcObjectRanges, + /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetObjectGeneration) + HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectID objectId, + /* [out] */ COR_PRF_GC_GENERATION_RANGE *range); + + DECLSPEC_XFGVIRT(ICorProfilerInfo2, GetNotifiedExceptionClauseInfo) + HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )( + ICorProfilerInfo14 * This, + /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumJITedFunctions) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )( + ICorProfilerInfo14 * This, + /* [out] */ ICorProfilerFunctionEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, RequestProfilerDetach) + HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )( + ICorProfilerInfo14 * This, + /* [in] */ DWORD dwExpectedCompletionMilliseconds); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetFunctionIDMapper2) + HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionIDMapper2 *pFunc, + /* [in] */ void *clientData); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetStringLayout2) + HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )( + ICorProfilerInfo14 * This, + /* [out] */ ULONG *pStringLengthOffset, + /* [out] */ ULONG *pBufferOffset); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionEnter3 *pFuncEnter3, + /* [in] */ FunctionLeave3 *pFuncLeave3, + /* [in] */ FunctionTailcall3 *pFuncTailcall3); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, SetEnterLeaveFunctionHooks3WithInfo) + HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, + /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, + /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionEnter3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ COR_PRF_ELT_INFO eltInfo, + /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, + /* [out][in] */ ULONG *pcbArgumentInfo, + /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionLeave3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ COR_PRF_ELT_INFO eltInfo, + /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, + /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetFunctionTailcall3Info) + HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ COR_PRF_ELT_INFO eltInfo, + /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, EnumModules) + HRESULT ( STDMETHODCALLTYPE *EnumModules )( + ICorProfilerInfo14 * This, + /* [out] */ ICorProfilerModuleEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetRuntimeInformation) + HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )( + ICorProfilerInfo14 * This, + /* [out] */ USHORT *pClrInstanceId, + /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType, + /* [out] */ USHORT *pMajorVersion, + /* [out] */ USHORT *pMinorVersion, + /* [out] */ USHORT *pBuildNumber, + /* [out] */ USHORT *pQFEVersion, + /* [in] */ ULONG cchVersionString, + /* [out] */ ULONG *pcchVersionString, + /* [annotation][out] */ + _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetThreadStaticAddress2) + HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )( + ICorProfilerInfo14 * This, + /* [in] */ ClassID classId, + /* [in] */ mdFieldDef fieldToken, + /* [in] */ AppDomainID appDomainId, + /* [in] */ ThreadID threadId, + /* [out] */ void **ppAddress); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetAppDomainsContainingModule) + HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [in] */ ULONG32 cAppDomainIds, + /* [out] */ ULONG32 *pcAppDomainIds, + /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo3, GetModuleInfo2) + HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [out] */ LPCBYTE *ppBaseLoadAddress, + /* [in] */ ULONG cchName, + /* [out] */ ULONG *pcchName, + /* [annotation][out] */ + _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ], + /* [out] */ AssemblyID *pAssemblyId, + /* [out] */ DWORD *pdwModuleFlags); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumThreads) + HRESULT ( STDMETHODCALLTYPE *EnumThreads )( + ICorProfilerInfo14 * This, + /* [out] */ ICorProfilerThreadEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, InitializeCurrentThread) + HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )( + ICorProfilerInfo14 * This); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestReJIT) + HRESULT ( STDMETHODCALLTYPE *RequestReJIT )( + ICorProfilerInfo14 * This, + /* [in] */ ULONG cFunctions, + /* [size_is][in] */ ModuleID moduleIds[ ], + /* [size_is][in] */ mdMethodDef methodIds[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, RequestRevert) + HRESULT ( STDMETHODCALLTYPE *RequestRevert )( + ICorProfilerInfo14 * This, + /* [in] */ ULONG cFunctions, + /* [size_is][in] */ ModuleID moduleIds[ ], + /* [size_is][in] */ mdMethodDef methodIds[ ], + /* [size_is][out] */ HRESULT status[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetCodeInfo3) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionID, + /* [in] */ ReJITID reJitId, + /* [in] */ ULONG32 cCodeInfos, + /* [out] */ ULONG32 *pcCodeInfos, + /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetFunctionFromIP2) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )( + ICorProfilerInfo14 * This, + /* [in] */ LPCBYTE ip, + /* [out] */ FunctionID *pFunctionId, + /* [out] */ ReJITID *pReJitId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetReJITIDs) + HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ ULONG cReJitIds, + /* [out] */ ULONG *pcReJitIds, + /* [length_is][size_is][out] */ ReJITID reJitIds[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetILToNativeMapping2) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [in] */ ReJITID reJitId, + /* [in] */ ULONG32 cMap, + /* [out] */ ULONG32 *pcMap, + /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, EnumJITedFunctions2) + HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )( + ICorProfilerInfo14 * This, + /* [out] */ ICorProfilerFunctionEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerInfo4, GetObjectSize2) + HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectID objectId, + /* [out] */ SIZE_T *pcSize); + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, GetEventMask2) + HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )( + ICorProfilerInfo14 * This, + /* [out] */ DWORD *pdwEventsLow, + /* [out] */ DWORD *pdwEventsHigh); + + DECLSPEC_XFGVIRT(ICorProfilerInfo5, SetEventMask2) + HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )( + ICorProfilerInfo14 * This, + /* [in] */ DWORD dwEventsLow, + /* [in] */ DWORD dwEventsHigh); + + DECLSPEC_XFGVIRT(ICorProfilerInfo6, EnumNgenModuleMethodsInliningThisMethod) + HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID inlinersModuleId, + /* [in] */ ModuleID inlineeModuleId, + /* [in] */ mdMethodDef inlineeMethodId, + /* [out] */ BOOL *incompleteData, + /* [out] */ ICorProfilerMethodEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ApplyMetaData) + HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, GetInMemorySymbolsLength) + HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [out] */ DWORD *pCountSymbolBytes); + + DECLSPEC_XFGVIRT(ICorProfilerInfo7, ReadInMemorySymbols) + HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )( + ICorProfilerInfo14 * This, + /* [in] */ ModuleID moduleId, + /* [in] */ DWORD symbolsReadOffset, + /* [out] */ BYTE *pSymbolBytes, + /* [in] */ DWORD countSymbolBytes, + /* [out] */ DWORD *pCountSymbolBytesRead); + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, IsFunctionDynamic) + HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [out] */ BOOL *isDynamic); + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetFunctionFromIP3) + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )( + ICorProfilerInfo14 * This, + /* [in] */ LPCBYTE ip, + /* [out] */ FunctionID *functionId, + /* [out] */ ReJITID *pReJitId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo8, GetDynamicFunctionInfo) + HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )( + ICorProfilerInfo14 * This, + /* [in] */ FunctionID functionId, + /* [out] */ ModuleID *moduleId, + /* [out] */ PCCOR_SIGNATURE *ppvSig, + /* [out] */ ULONG *pbSig, + /* [in] */ ULONG cchName, + /* [out] */ ULONG *pcchName, + /* [out] */ WCHAR wszName[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetNativeCodeStartAddresses) + HRESULT ( STDMETHODCALLTYPE *GetNativeCodeStartAddresses )( + ICorProfilerInfo14 * This, + FunctionID functionID, + ReJITID reJitId, + ULONG32 cCodeStartAddresses, + ULONG32 *pcCodeStartAddresses, + UINT_PTR codeStartAddresses[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetILToNativeMapping3) + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping3 )( + ICorProfilerInfo14 * This, + UINT_PTR pNativeCodeStartAddress, + ULONG32 cMap, + ULONG32 *pcMap, + COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo9, GetCodeInfo4) + HRESULT ( STDMETHODCALLTYPE *GetCodeInfo4 )( + ICorProfilerInfo14 * This, + UINT_PTR pNativeCodeStartAddress, + ULONG32 cCodeInfos, + ULONG32 *pcCodeInfos, + COR_PRF_CODE_INFO codeInfos[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, EnumerateObjectReferences) + HRESULT ( STDMETHODCALLTYPE *EnumerateObjectReferences )( + ICorProfilerInfo14 * This, + ObjectID objectId, + ObjectReferenceCallback callback, + void *clientData); + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, IsFrozenObject) + HRESULT ( STDMETHODCALLTYPE *IsFrozenObject )( + ICorProfilerInfo14 * This, + ObjectID objectId, + BOOL *pbFrozen); + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, GetLOHObjectSizeThreshold) + HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )( + ICorProfilerInfo14 * This, + DWORD *pThreshold); + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, RequestReJITWithInliners) + HRESULT ( STDMETHODCALLTYPE *RequestReJITWithInliners )( + ICorProfilerInfo14 * This, + /* [in] */ DWORD dwRejitFlags, + /* [in] */ ULONG cFunctions, + /* [size_is][in] */ ModuleID moduleIds[ ], + /* [size_is][in] */ mdMethodDef methodIds[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, SuspendRuntime) + HRESULT ( STDMETHODCALLTYPE *SuspendRuntime )( + ICorProfilerInfo14 * This); + + DECLSPEC_XFGVIRT(ICorProfilerInfo10, ResumeRuntime) + HRESULT ( STDMETHODCALLTYPE *ResumeRuntime )( + ICorProfilerInfo14 * This); + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, GetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *GetEnvironmentVariable )( + ICorProfilerInfo14 * This, + /* [string][in] */ const WCHAR *szName, + /* [in] */ ULONG cchValue, + /* [out] */ ULONG *pcchValue, + /* [annotation][out] */ + _Out_writes_to_(cchValue, *pcchValue) WCHAR szValue[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo11, SetEnvironmentVariable) + HRESULT ( STDMETHODCALLTYPE *SetEnvironmentVariable )( + ICorProfilerInfo14 * This, + /* [string][in] */ const WCHAR *szName, + /* [string][in] */ const WCHAR *szValue); + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeStartSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeStartSession )( + ICorProfilerInfo14 * This, + /* [in] */ UINT32 cProviderConfigs, + /* [size_is][in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG pProviderConfigs[ ], + /* [in] */ BOOL requestRundown, + /* [out] */ EVENTPIPE_SESSION *pSession); + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeAddProviderToSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeAddProviderToSession )( + ICorProfilerInfo14 * This, + /* [in] */ EVENTPIPE_SESSION session, + /* [in] */ COR_PRF_EVENTPIPE_PROVIDER_CONFIG providerConfig); + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeStopSession) + HRESULT ( STDMETHODCALLTYPE *EventPipeStopSession )( + ICorProfilerInfo14 * This, + /* [in] */ EVENTPIPE_SESSION session); + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeCreateProvider) + HRESULT ( STDMETHODCALLTYPE *EventPipeCreateProvider )( + ICorProfilerInfo14 * This, + /* [string][in] */ const WCHAR *providerName, + /* [out] */ EVENTPIPE_PROVIDER *pProvider); + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeGetProviderInfo) + HRESULT ( STDMETHODCALLTYPE *EventPipeGetProviderInfo )( + ICorProfilerInfo14 * This, + /* [in] */ EVENTPIPE_PROVIDER provider, + /* [in] */ ULONG cchName, + /* [out] */ ULONG *pcchName, + /* [annotation][out] */ + _Out_writes_to_(cchName, *pcchName) WCHAR providerName[ ]); + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeDefineEvent) + HRESULT ( STDMETHODCALLTYPE *EventPipeDefineEvent )( + ICorProfilerInfo14 * This, + /* [in] */ EVENTPIPE_PROVIDER provider, + /* [string][in] */ const WCHAR *eventName, + /* [in] */ UINT32 eventID, + /* [in] */ UINT64 keywords, + /* [in] */ UINT32 eventVersion, + /* [in] */ UINT32 level, + /* [in] */ UINT8 opcode, + /* [in] */ BOOL needStack, + /* [in] */ UINT32 cParamDescs, + /* [size_is][in] */ COR_PRF_EVENTPIPE_PARAM_DESC pParamDescs[ ], + /* [out] */ EVENTPIPE_EVENT *pEvent); + + DECLSPEC_XFGVIRT(ICorProfilerInfo12, EventPipeWriteEvent) + HRESULT ( STDMETHODCALLTYPE *EventPipeWriteEvent )( + ICorProfilerInfo14 * This, + /* [in] */ EVENTPIPE_EVENT event, + /* [in] */ UINT32 cData, + /* [size_is][in] */ COR_PRF_EVENT_DATA data[ ], + /* [in] */ LPCGUID pActivityId, + /* [in] */ LPCGUID pRelatedActivityId); + + DECLSPEC_XFGVIRT(ICorProfilerInfo13, CreateHandle) + HRESULT ( STDMETHODCALLTYPE *CreateHandle )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectID object, + /* [in] */ COR_PRF_HANDLE_TYPE type, + /* [out] */ ObjectHandleID *pHandle); + + DECLSPEC_XFGVIRT(ICorProfilerInfo13, DestroyHandle) + HRESULT ( STDMETHODCALLTYPE *DestroyHandle )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectHandleID handle); + + DECLSPEC_XFGVIRT(ICorProfilerInfo13, GetObjectIDFromHandle) + HRESULT ( STDMETHODCALLTYPE *GetObjectIDFromHandle )( + ICorProfilerInfo14 * This, + /* [in] */ ObjectHandleID handle, + /* [out] */ ObjectID *pObject); + + DECLSPEC_XFGVIRT(ICorProfilerInfo14, EnumerateNonGCObjects) + HRESULT ( STDMETHODCALLTYPE *EnumerateNonGCObjects )( + ICorProfilerInfo14 * This, + /* [out] */ ICorProfilerObjectEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerInfo14, GetNonGCHeapBounds) + HRESULT ( STDMETHODCALLTYPE *GetNonGCHeapBounds )( + ICorProfilerInfo14 * This, + /* [in] */ ULONG cObjectRanges, + /* [out] */ ULONG *pcObjectRanges, + /* [length_is][size_is][out] */ COR_PRF_NONGC_HEAP_RANGE ranges[ ]); + + END_INTERFACE + } ICorProfilerInfo14Vtbl; + + interface ICorProfilerInfo14 + { + CONST_VTBL struct ICorProfilerInfo14Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ICorProfilerInfo14_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ICorProfilerInfo14_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ICorProfilerInfo14_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ICorProfilerInfo14_GetClassFromObject(This,objectId,pClassId) \ + ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) ) + +#define ICorProfilerInfo14_GetClassFromToken(This,moduleId,typeDef,pClassId) \ + ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) ) + +#define ICorProfilerInfo14_GetCodeInfo(This,functionId,pStart,pcSize) \ + ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) ) + +#define ICorProfilerInfo14_GetEventMask(This,pdwEvents) \ + ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) ) + +#define ICorProfilerInfo14_GetFunctionFromIP(This,ip,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) ) + +#define ICorProfilerInfo14_GetFunctionFromToken(This,moduleId,token,pFunctionId) \ + ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) ) + +#define ICorProfilerInfo14_GetHandleFromThread(This,threadId,phThread) \ + ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) ) + +#define ICorProfilerInfo14_GetObjectSize(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) ) + +#define ICorProfilerInfo14_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \ + ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) ) + +#define ICorProfilerInfo14_GetThreadInfo(This,threadId,pdwWin32ThreadId) \ + ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) ) + +#define ICorProfilerInfo14_GetCurrentThreadID(This,pThreadId) \ + ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) ) + +#define ICorProfilerInfo14_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \ + ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) ) + +#define ICorProfilerInfo14_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \ + ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) ) + +#define ICorProfilerInfo14_SetEventMask(This,dwEvents) \ + ( (This)->lpVtbl -> SetEventMask(This,dwEvents) ) + +#define ICorProfilerInfo14_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) + +#define ICorProfilerInfo14_SetFunctionIDMapper(This,pFunc) \ + ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) ) + +#define ICorProfilerInfo14_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \ + ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) ) + +#define ICorProfilerInfo14_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \ + ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) ) + +#define ICorProfilerInfo14_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \ + ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) ) + +#define ICorProfilerInfo14_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \ + ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) ) + +#define ICorProfilerInfo14_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \ + ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) ) + +#define ICorProfilerInfo14_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \ + ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) ) + +#define ICorProfilerInfo14_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \ + ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) ) + +#define ICorProfilerInfo14_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \ + ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) ) + +#define ICorProfilerInfo14_SetFunctionReJIT(This,functionId) \ + ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) ) + +#define ICorProfilerInfo14_ForceGC(This) \ + ( (This)->lpVtbl -> ForceGC(This) ) + +#define ICorProfilerInfo14_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \ + ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) ) + +#define ICorProfilerInfo14_GetInprocInspectionInterface(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) ) + +#define ICorProfilerInfo14_GetInprocInspectionIThisThread(This,ppicd) \ + ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) ) + +#define ICorProfilerInfo14_GetThreadContext(This,threadId,pContextId) \ + ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) ) + +#define ICorProfilerInfo14_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \ + ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) ) + +#define ICorProfilerInfo14_EndInprocDebugging(This,dwProfilerContext) \ + ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) ) + +#define ICorProfilerInfo14_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) ) + + +#define ICorProfilerInfo14_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \ + ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) ) + +#define ICorProfilerInfo14_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) ) + +#define ICorProfilerInfo14_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) ) + +#define ICorProfilerInfo14_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) ) + +#define ICorProfilerInfo14_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \ + ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) ) + +#define ICorProfilerInfo14_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \ + ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) ) + +#define ICorProfilerInfo14_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) ) + +#define ICorProfilerInfo14_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \ + ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) ) + +#define ICorProfilerInfo14_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \ + ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) ) + +#define ICorProfilerInfo14_EnumModuleFrozenObjects(This,moduleID,ppEnum) \ + ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) ) + +#define ICorProfilerInfo14_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \ + ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) ) + +#define ICorProfilerInfo14_GetBoxClassLayout(This,classId,pBufferOffset) \ + ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) ) + +#define ICorProfilerInfo14_GetThreadAppDomain(This,threadId,pAppDomainId) \ + ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) ) + +#define ICorProfilerInfo14_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \ + ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) ) + +#define ICorProfilerInfo14_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \ + ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) ) + +#define ICorProfilerInfo14_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) ) + +#define ICorProfilerInfo14_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \ + ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) ) + +#define ICorProfilerInfo14_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \ + ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) ) + +#define ICorProfilerInfo14_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) ) + +#define ICorProfilerInfo14_GetObjectGeneration(This,objectId,range) \ + ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) ) + +#define ICorProfilerInfo14_GetNotifiedExceptionClauseInfo(This,pinfo) \ + ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) ) + + +#define ICorProfilerInfo14_EnumJITedFunctions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) ) + +#define ICorProfilerInfo14_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \ + ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) ) + +#define ICorProfilerInfo14_SetFunctionIDMapper2(This,pFunc,clientData) \ + ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) ) + +#define ICorProfilerInfo14_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \ + ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) ) + +#define ICorProfilerInfo14_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) ) + +#define ICorProfilerInfo14_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \ + ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) ) + +#define ICorProfilerInfo14_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \ + ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) ) + +#define ICorProfilerInfo14_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \ + ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) ) + +#define ICorProfilerInfo14_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \ + ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) ) + +#define ICorProfilerInfo14_EnumModules(This,ppEnum) \ + ( (This)->lpVtbl -> EnumModules(This,ppEnum) ) + +#define ICorProfilerInfo14_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \ + ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) ) + +#define ICorProfilerInfo14_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \ + ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) ) + +#define ICorProfilerInfo14_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \ + ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) ) + +#define ICorProfilerInfo14_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \ + ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) ) + + +#define ICorProfilerInfo14_EnumThreads(This,ppEnum) \ + ( (This)->lpVtbl -> EnumThreads(This,ppEnum) ) + +#define ICorProfilerInfo14_InitializeCurrentThread(This) \ + ( (This)->lpVtbl -> InitializeCurrentThread(This) ) + +#define ICorProfilerInfo14_RequestReJIT(This,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) ) + +#define ICorProfilerInfo14_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \ + ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) ) + +#define ICorProfilerInfo14_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) ) + +#define ICorProfilerInfo14_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) ) + +#define ICorProfilerInfo14_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \ + ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) ) + +#define ICorProfilerInfo14_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) ) + +#define ICorProfilerInfo14_EnumJITedFunctions2(This,ppEnum) \ + ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) ) + +#define ICorProfilerInfo14_GetObjectSize2(This,objectId,pcSize) \ + ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) ) + + +#define ICorProfilerInfo14_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \ + ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) ) + +#define ICorProfilerInfo14_SetEventMask2(This,dwEventsLow,dwEventsHigh) \ + ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) ) + + +#define ICorProfilerInfo14_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \ + ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) ) - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorProfilerMethodEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorProfilerMethodEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - ICorProfilerMethodEnum * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - ICorProfilerMethodEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - ICorProfilerMethodEnum * This, - /* [out] */ ICorProfilerMethodEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - ICorProfilerMethodEnum * This, - /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( - ICorProfilerMethodEnum * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ COR_PRF_METHOD elements[ ], - /* [out] */ ULONG *pceltFetched); - - END_INTERFACE - } ICorProfilerMethodEnumVtbl; - - interface ICorProfilerMethodEnum - { - CONST_VTBL struct ICorProfilerMethodEnumVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorProfilerMethodEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorProfilerMethodEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerMethodEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerInfo14_ApplyMetaData(This,moduleId) \ + ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) ) +#define ICorProfilerInfo14_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \ + ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) ) -#define ICorProfilerMethodEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) +#define ICorProfilerInfo14_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \ + ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) ) -#define ICorProfilerMethodEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) -#define ICorProfilerMethodEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) +#define ICorProfilerInfo14_IsFunctionDynamic(This,functionId,isDynamic) \ + ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) ) -#define ICorProfilerMethodEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) +#define ICorProfilerInfo14_GetFunctionFromIP3(This,ip,functionId,pReJitId) \ + ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) ) -#define ICorProfilerMethodEnum_Next(This,celt,elements,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,elements,pceltFetched) ) +#define ICorProfilerInfo14_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \ + ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) ) + + +#define ICorProfilerInfo14_GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) \ + ( (This)->lpVtbl -> GetNativeCodeStartAddresses(This,functionID,reJitId,cCodeStartAddresses,pcCodeStartAddresses,codeStartAddresses) ) + +#define ICorProfilerInfo14_GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) \ + ( (This)->lpVtbl -> GetILToNativeMapping3(This,pNativeCodeStartAddress,cMap,pcMap,map) ) + +#define ICorProfilerInfo14_GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) \ + ( (This)->lpVtbl -> GetCodeInfo4(This,pNativeCodeStartAddress,cCodeInfos,pcCodeInfos,codeInfos) ) + + +#define ICorProfilerInfo14_EnumerateObjectReferences(This,objectId,callback,clientData) \ + ( (This)->lpVtbl -> EnumerateObjectReferences(This,objectId,callback,clientData) ) + +#define ICorProfilerInfo14_IsFrozenObject(This,objectId,pbFrozen) \ + ( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) ) + +#define ICorProfilerInfo14_GetLOHObjectSizeThreshold(This,pThreshold) \ + ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) ) + +#define ICorProfilerInfo14_RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) \ + ( (This)->lpVtbl -> RequestReJITWithInliners(This,dwRejitFlags,cFunctions,moduleIds,methodIds) ) + +#define ICorProfilerInfo14_SuspendRuntime(This) \ + ( (This)->lpVtbl -> SuspendRuntime(This) ) + +#define ICorProfilerInfo14_ResumeRuntime(This) \ + ( (This)->lpVtbl -> ResumeRuntime(This) ) + + +#define ICorProfilerInfo14_GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) \ + ( (This)->lpVtbl -> GetEnvironmentVariable(This,szName,cchValue,pcchValue,szValue) ) + +#define ICorProfilerInfo14_SetEnvironmentVariable(This,szName,szValue) \ + ( (This)->lpVtbl -> SetEnvironmentVariable(This,szName,szValue) ) + + +#define ICorProfilerInfo14_EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) \ + ( (This)->lpVtbl -> EventPipeStartSession(This,cProviderConfigs,pProviderConfigs,requestRundown,pSession) ) + +#define ICorProfilerInfo14_EventPipeAddProviderToSession(This,session,providerConfig) \ + ( (This)->lpVtbl -> EventPipeAddProviderToSession(This,session,providerConfig) ) + +#define ICorProfilerInfo14_EventPipeStopSession(This,session) \ + ( (This)->lpVtbl -> EventPipeStopSession(This,session) ) + +#define ICorProfilerInfo14_EventPipeCreateProvider(This,providerName,pProvider) \ + ( (This)->lpVtbl -> EventPipeCreateProvider(This,providerName,pProvider) ) + +#define ICorProfilerInfo14_EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) \ + ( (This)->lpVtbl -> EventPipeGetProviderInfo(This,provider,cchName,pcchName,providerName) ) + +#define ICorProfilerInfo14_EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) \ + ( (This)->lpVtbl -> EventPipeDefineEvent(This,provider,eventName,eventID,keywords,eventVersion,level,opcode,needStack,cParamDescs,pParamDescs,pEvent) ) + +#define ICorProfilerInfo14_EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) \ + ( (This)->lpVtbl -> EventPipeWriteEvent(This,event,cData,data,pActivityId,pRelatedActivityId) ) + + +#define ICorProfilerInfo14_CreateHandle(This,object,type,pHandle) \ + ( (This)->lpVtbl -> CreateHandle(This,object,type,pHandle) ) + +#define ICorProfilerInfo14_DestroyHandle(This,handle) \ + ( (This)->lpVtbl -> DestroyHandle(This,handle) ) + +#define ICorProfilerInfo14_GetObjectIDFromHandle(This,handle,pObject) \ + ( (This)->lpVtbl -> GetObjectIDFromHandle(This,handle,pObject) ) + + +#define ICorProfilerInfo14_EnumerateNonGCObjects(This,ppEnum) \ + ( (This)->lpVtbl -> EnumerateNonGCObjects(This,ppEnum) ) + +#define ICorProfilerInfo14_GetNonGCHeapBounds(This,cObjectRanges,pcObjectRanges,ranges) \ + ( (This)->lpVtbl -> GetNonGCHeapBounds(This,cObjectRanges,pcObjectRanges,ranges) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ICorProfilerInfo14_INTERFACE_DEFINED__ */ + + +#ifndef __ICorProfilerMethodEnum_INTERFACE_DEFINED__ +#define __ICorProfilerMethodEnum_INTERFACE_DEFINED__ + +/* interface ICorProfilerMethodEnum */ +/* [local][unique][uuid][object] */ + + +EXTERN_C const IID IID_ICorProfilerMethodEnum; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("FCCEE788-0088-454B-A811-C99F298D1942") + ICorProfilerMethodEnum : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ ICorProfilerMethodEnum **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCount( + /* [out] */ ULONG *pcelt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [length_is][size_is][out] */ COR_PRF_METHOD elements[ ], + /* [out] */ ULONG *pceltFetched) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ICorProfilerMethodEnumVtbl + { + BEGIN_INTERFACE + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ICorProfilerMethodEnum * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( + ICorProfilerMethodEnum * This); + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( + ICorProfilerMethodEnum * This); + + DECLSPEC_XFGVIRT(ICorProfilerMethodEnum, Skip) + HRESULT ( STDMETHODCALLTYPE *Skip )( + ICorProfilerMethodEnum * This, + /* [in] */ ULONG celt); + + DECLSPEC_XFGVIRT(ICorProfilerMethodEnum, Reset) + HRESULT ( STDMETHODCALLTYPE *Reset )( + ICorProfilerMethodEnum * This); + + DECLSPEC_XFGVIRT(ICorProfilerMethodEnum, Clone) + HRESULT ( STDMETHODCALLTYPE *Clone )( + ICorProfilerMethodEnum * This, + /* [out] */ ICorProfilerMethodEnum **ppEnum); + + DECLSPEC_XFGVIRT(ICorProfilerMethodEnum, GetCount) + HRESULT ( STDMETHODCALLTYPE *GetCount )( + ICorProfilerMethodEnum * This, + /* [out] */ ULONG *pcelt); + + DECLSPEC_XFGVIRT(ICorProfilerMethodEnum, Next) + HRESULT ( STDMETHODCALLTYPE *Next )( + ICorProfilerMethodEnum * This, + /* [in] */ ULONG celt, + /* [length_is][size_is][out] */ COR_PRF_METHOD elements[ ], + /* [out] */ ULONG *pceltFetched); + + END_INTERFACE + } ICorProfilerMethodEnumVtbl; + + interface ICorProfilerMethodEnum + { + CONST_VTBL struct ICorProfilerMethodEnumVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ICorProfilerMethodEnum_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ICorProfilerMethodEnum_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ICorProfilerMethodEnum_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ICorProfilerMethodEnum_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define ICorProfilerMethodEnum_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define ICorProfilerMethodEnum_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define ICorProfilerMethodEnum_GetCount(This,pcelt) \ + ( (This)->lpVtbl -> GetCount(This,pcelt) ) + +#define ICorProfilerMethodEnum_Next(This,celt,elements,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,elements,pceltFetched) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerMethodEnum_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerMethodEnum_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerThreadEnum_INTERFACE_DEFINED__ #define __ICorProfilerThreadEnum_INTERFACE_DEFINED__ /* interface ICorProfilerThreadEnum */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerThreadEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("571194f7-25ed-419f-aa8b-7016b3159701") ICorProfilerThreadEnum : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Skip( + virtual HRESULT STDMETHODCALLTYPE Skip( /* [in] */ ULONG celt) = 0; - + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( + + virtual HRESULT STDMETHODCALLTYPE Clone( /* [out] */ ICorProfilerThreadEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( + + virtual HRESULT STDMETHODCALLTYPE GetCount( /* [out] */ ULONG *pcelt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Next( + + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ThreadID ids[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerThreadEnumVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerThreadEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerThreadEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerThreadEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( + + DECLSPEC_XFGVIRT(ICorProfilerThreadEnum, Skip) + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorProfilerThreadEnum * This, /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( + + DECLSPEC_XFGVIRT(ICorProfilerThreadEnum, Reset) + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorProfilerThreadEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( + + DECLSPEC_XFGVIRT(ICorProfilerThreadEnum, Clone) + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorProfilerThreadEnum * This, /* [out] */ ICorProfilerThreadEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( + + DECLSPEC_XFGVIRT(ICorProfilerThreadEnum, GetCount) + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorProfilerThreadEnum * This, /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( + + DECLSPEC_XFGVIRT(ICorProfilerThreadEnum, Next) + HRESULT ( STDMETHODCALLTYPE *Next )( ICorProfilerThreadEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ThreadID ids[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorProfilerThreadEnumVtbl; @@ -21283,90 +24654,94 @@ EXTERN_C const IID IID_ICorProfilerThreadEnum; CONST_VTBL struct ICorProfilerThreadEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerThreadEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerThreadEnum_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerThreadEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerThreadEnum_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerThreadEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerThreadEnum_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerThreadEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) +#define ICorProfilerThreadEnum_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) -#define ICorProfilerThreadEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) +#define ICorProfilerThreadEnum_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) -#define ICorProfilerThreadEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) +#define ICorProfilerThreadEnum_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) -#define ICorProfilerThreadEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) +#define ICorProfilerThreadEnum_GetCount(This,pcelt) \ + ( (This)->lpVtbl -> GetCount(This,pcelt) ) -#define ICorProfilerThreadEnum_Next(This,celt,ids,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,ids,pceltFetched) ) +#define ICorProfilerThreadEnum_Next(This,celt,ids,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,ids,pceltFetched) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerThreadEnum_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerThreadEnum_INTERFACE_DEFINED__ */ #ifndef __ICorProfilerAssemblyReferenceProvider_INTERFACE_DEFINED__ #define __ICorProfilerAssemblyReferenceProvider_INTERFACE_DEFINED__ /* interface ICorProfilerAssemblyReferenceProvider */ -/* [local][unique][uuid][object] */ +/* [local][unique][uuid][object] */ EXTERN_C const IID IID_ICorProfilerAssemblyReferenceProvider; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("66A78C24-2EEF-4F65-B45F-DD1D8038BF3C") ICorProfilerAssemblyReferenceProvider : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE AddAssemblyReference( + virtual HRESULT STDMETHODCALLTYPE AddAssemblyReference( const COR_PRF_ASSEMBLY_REFERENCE_INFO *pAssemblyRefInfo) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorProfilerAssemblyReferenceProviderVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorProfilerAssemblyReferenceProvider * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorProfilerAssemblyReferenceProvider * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( ICorProfilerAssemblyReferenceProvider * This); - - HRESULT ( STDMETHODCALLTYPE *AddAssemblyReference )( + + DECLSPEC_XFGVIRT(ICorProfilerAssemblyReferenceProvider, AddAssemblyReference) + HRESULT ( STDMETHODCALLTYPE *AddAssemblyReference )( ICorProfilerAssemblyReferenceProvider * This, const COR_PRF_ASSEMBLY_REFERENCE_INFO *pAssemblyRefInfo); - + END_INTERFACE } ICorProfilerAssemblyReferenceProviderVtbl; @@ -21375,33 +24750,33 @@ EXTERN_C const IID IID_ICorProfilerAssemblyReferenceProvider; CONST_VTBL struct ICorProfilerAssemblyReferenceProviderVtbl *lpVtbl; }; - + #ifdef COBJMACROS -#define ICorProfilerAssemblyReferenceProvider_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) +#define ICorProfilerAssemblyReferenceProvider_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) -#define ICorProfilerAssemblyReferenceProvider_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) +#define ICorProfilerAssemblyReferenceProvider_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) -#define ICorProfilerAssemblyReferenceProvider_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) +#define ICorProfilerAssemblyReferenceProvider_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) -#define ICorProfilerAssemblyReferenceProvider_AddAssemblyReference(This,pAssemblyRefInfo) \ - ( (This)->lpVtbl -> AddAssemblyReference(This,pAssemblyRefInfo) ) +#define ICorProfilerAssemblyReferenceProvider_AddAssemblyReference(This,pAssemblyRefInfo) \ + ( (This)->lpVtbl -> AddAssemblyReference(This,pAssemblyRefInfo) ) #endif /* COBJMACROS */ -#endif /* C style interface */ +#endif /* C style interface */ -#endif /* __ICorProfilerAssemblyReferenceProvider_INTERFACE_DEFINED__ */ +#endif /* __ICorProfilerAssemblyReferenceProvider_INTERFACE_DEFINED__ */ /* Additional Prototypes for ALL interfaces */ diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index d7744c34333369..8d5410c4eab667 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -2,12 +2,17 @@ ClrFullNativeBuild;ClrRuntimeSubset;ClrJitSubset;ClrPalTestsSubset;ClrAllJitsSubset;ClrILToolsSubset;ClrNativeAotSubset;ClrSpmiSubset;ClrCrossComponentsSubset;HostArchitecture;PgoInstrument;NativeOptimizationDataSupported;CMakeArgs + <_IcuDir Condition="'$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)' != ''">$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)/runtimes/$(TargetOS)-$(TargetArchitecture)$(_RuntimeVariant)/native + + + + <_CoreClrBuildArg Condition="'$(NativeOptimizationDataSupported)' == 'true' and '$(NoPgoOptimize)' != 'true' and '$(PgoInstrument)' != 'true'" Include="-pgodatapath "$(PgoPackagePath)"" /> <_CoreClrBuildArg Condition="'$(HostArchitecture)' != ''" Include="-hostarch $(HostArchitecture)" /> - <_CoreClrBuildArg Include="-outputrid $(OutputRid)" /> + <_CoreClrBuildArg Include="-outputrid $(OutputRID)" /> @@ -52,6 +57,10 @@ <_CoreClrBuildArg Condition="'$(ClrCrossComponentsSubset)' == 'true'" Include="-component crosscomponents" /> + + <_CoreClrBuildArg Include="-cmakeargs -DCMAKE_ICU_DIR="$(_IcuDir)"" /> + + <_CoreClrBuildScript Condition="$([MSBuild]::IsOsPlatform(Windows))">build-runtime.cmd <_CoreClrBuildScript Condition="!$([MSBuild]::IsOsPlatform(Windows))">build-runtime.sh diff --git a/src/coreclr/scripts/superpmi.py b/src/coreclr/scripts/superpmi.py index 213b7de2dbf44c..4fb1c207b064b4 100644 --- a/src/coreclr/scripts/superpmi.py +++ b/src/coreclr/scripts/superpmi.py @@ -3096,7 +3096,7 @@ def process_local_mch_files(coreclr_args, mch_files, mch_cache_dir): for item in mch_files: # On Windows only, see if any of the mch_files are UNC paths (i.e., "\\server\share\..."). # If so, download and cache all the files found there to our usual local cache location, to avoid future network access. - if coreclr_args.host_os == "windows":# and item.startswith("\\\\"): + if coreclr_args.host_os == "windows" and item.startswith("\\\\"): # Special case: if the user specifies a .mch file, we'll also look for and cache a .mch.mct file next to it, if one exists. # This happens naturally if a directory is passed and we search for all .mch and .mct files in that directory. mch_file = os.path.abspath(item) diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/SortableDependencyNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/SortableDependencyNode.cs index a6968ae628e715..9ff3e3135d973a 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/SortableDependencyNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/SortableDependencyNode.cs @@ -77,6 +77,8 @@ protected enum ObjectNodeOrder DelegateMarshallingStubMapNode, StructMarshallingStubMapNode, ArrayMapNode, + PointerMapNode, + ByRefMapNode, FunctionPointerMapNode, ReflectionFieldMapNode, NativeLayoutInfoNode, diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs index 8961c1bc1b452b..981fb442bece98 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs @@ -558,7 +558,7 @@ from primitiveType in PrimitiveTypes select name: "MethodInstantiation", members: new MemberDef[] { new MemberDef("Method", MethodDefOrRef, MemberDefFlags.RecordRef), - new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpec, MemberDefFlags.List | MemberDefFlags.RecordRef), + new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpecOrMod, MemberDefFlags.List | MemberDefFlags.RecordRef), // COMPLETENESS: new MemberDef("CustomAttributes", "CustomAttribute", MemberDefFlags.List | MemberDefFlags.RecordRef | MemberDefFlags.Child), } ), @@ -674,7 +674,7 @@ from primitiveType in PrimitiveTypes select name: "TypeInstantiationSignature", members: new MemberDef[] { new MemberDef("GenericType", TypeDefOrRefOrSpec, MemberDefFlags.RecordRef), - new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpec, MemberDefFlags.List | MemberDefFlags.RecordRef), + new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpecOrMod, MemberDefFlags.List | MemberDefFlags.RecordRef), } ), new RecordDef( @@ -686,7 +686,7 @@ from primitiveType in PrimitiveTypes select new RecordDef( name: "ArraySignature", members: new MemberDef[] { - new MemberDef("ElementType", TypeDefOrRefOrSpec, MemberDefFlags.RecordRef), + new MemberDef("ElementType", TypeDefOrRefOrSpecOrMod, MemberDefFlags.RecordRef), new MemberDef("Rank", "int"), new MemberDef("Sizes", "Int32", MemberDefFlags.Array), new MemberDef("LowerBounds", "Int32", MemberDefFlags.Array), @@ -695,7 +695,7 @@ from primitiveType in PrimitiveTypes select new RecordDef( name: "ByReferenceSignature", members: new MemberDef[] { - new MemberDef("Type", TypeDefOrRefOrSpec, MemberDefFlags.RecordRef), + new MemberDef("Type", TypeDefOrRefOrSpecOrMod, MemberDefFlags.RecordRef), } ), new RecordDef( diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs index dd88c6f2b1d3a3..d21f809903d5c3 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs @@ -37,7 +37,7 @@ public ArraySignatureHandle Handle return _handle; } } // Handle - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public Handle ElementType { @@ -182,7 +182,7 @@ public ByReferenceSignatureHandle Handle return _handle; } } // Handle - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public Handle Type { @@ -4901,7 +4901,7 @@ public Handle Method } // Method internal Handle _method; - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public HandleCollection GenericTypeArguments { @@ -7756,7 +7756,7 @@ public Handle GenericType } // GenericType internal Handle _genericType; - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public HandleCollection GenericTypeArguments { diff --git a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs index a5645f39f0ade6..19a75854b9bbb2 100644 --- a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs +++ b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs @@ -55,7 +55,7 @@ enum BagElementKind : uint // unused = 0x4d, ClassConstructorPointer = 0x4e, // unused = 0x4f, - GenericVarianceInfo = 0x50, + // unused = 0x50, // unused = 0x51, // Add new custom bag elements that don't match to something you'd find in the ECMA metadata here. @@ -203,6 +203,7 @@ enum MethodCallingConvention : uint { Generic = 0x1, Static = 0x2, + Unmanaged = 0x4, }; #if NATIVEFORMAT_PUBLICWRITER diff --git a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatWriter.cs b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatWriter.cs index 2ab3363791b16b..9c6f9a94012132 100644 --- a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatWriter.cs +++ b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatWriter.cs @@ -518,6 +518,12 @@ public Vertex GetMDArrayTypeSignature(Vertex elementType, uint rank, uint[] boun MDArrayTypeSignature sig = new MDArrayTypeSignature(elementType, rank, bounds, lowerBounds); return Unify(sig); } + + public Vertex GetFunctionPointerTypeSignature(Vertex methodSignature) + { + FunctionPointerTypeSignature sig = new FunctionPointerTypeSignature(methodSignature); + return Unify(sig); + } } internal sealed class PlacedVertex : Vertex @@ -1462,6 +1468,37 @@ public override bool Equals(object obj) } } +#if NATIVEFORMAT_PUBLICWRITER + public +#else + internal +#endif + class FunctionPointerTypeSignature : Vertex + { + private Vertex _methodSignature; + + public FunctionPointerTypeSignature(Vertex methodSignature) + { + _methodSignature = methodSignature; + } + + internal override void Save(NativeWriter writer) + { + writer.WriteUnsigned((uint)TypeSignatureKind.FunctionPointer); + _methodSignature.Save(writer); + } + + public override int GetHashCode() + { + return _methodSignature.GetHashCode(); + } + + public override bool Equals(object obj) + { + return obj is FunctionPointerTypeSignature fnptrSig && _methodSignature.Equals(fnptrSig._methodSignature); + } + } + #if NATIVEFORMAT_PUBLICWRITER public #else diff --git a/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs b/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs index 914b44d7df76c6..d61d2d41d427ef 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs @@ -123,6 +123,11 @@ mdType.Name is "WeakReference" or "WeakReference`1" && flagsEx |= (ushort)EETypeFlagsEx.IsTrackedReferenceWithFinalizerFlag; } + if (type.IsIDynamicInterfaceCastable) + { + flagsEx |= (ushort)EETypeFlagsEx.IDynamicInterfaceCastableFlag; + } + return flagsEx; } diff --git a/src/coreclr/tools/Common/Internal/Runtime/MappingTableFlags.cs b/src/coreclr/tools/Common/Internal/Runtime/MappingTableFlags.cs index 2cfd5d2d17c3bb..189be63698bcd1 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/MappingTableFlags.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/MappingTableFlags.cs @@ -17,12 +17,6 @@ internal struct VirtualInvokeTableEntry public const int FlagsMask = 1; } - internal struct FunctionPointerMapEntry - { - public const uint IsUnmanagedFlag = 1; - public const int ParameterCountShift = 1; - } - [Flags] public enum InvokeTableFlags : uint { diff --git a/src/coreclr/tools/Common/Internal/Runtime/MetadataBlob.cs b/src/coreclr/tools/Common/Internal/Runtime/MetadataBlob.cs index 4be504228030c8..f1d1ea20790a4b 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/MetadataBlob.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/MetadataBlob.cs @@ -7,7 +7,7 @@ internal enum ReflectionMapBlob { TypeMap = 1, ArrayMap = 2, - // unused = 3, + PointerTypeMap = 3, FunctionPointerTypeMap = 4, BlockReflectionTypeMap = 5, InvokeMap = 6, @@ -15,7 +15,7 @@ internal enum ReflectionMapBlob CommonFixupsTable = 8, FieldAccessMap = 9, CCtorContextMap = 10, - // unused = 11, + ByRefTypeMap = 11, // unused = 12, EmbeddedMetadata = 13, DefaultConstructorMap = 14, diff --git a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs index e787c50daea3fd..98b77ccfd9bb10 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs @@ -17,14 +17,9 @@ internal enum EETypeFlags : uint EETypeKindMask = 0x00030000, /// - /// This flag is set when m_RelatedType is in a different module. In that case, _pRelatedType - /// actually points to an IAT slot in this module, which then points to the desired MethodTable in the - /// other module. In other words, there is an extra indirection through m_RelatedType to get to - /// the related type in the other module. When this flag is set, it is expected that you use the - /// "_ppXxxxViaIAT" member of the RelatedTypeUnion for the particular related type you're - /// accessing. + /// Type has an associated dispatch map. /// - RelatedTypeViaIATFlag = 0x00040000, + HasDispatchMap = 0x00040000, /// /// This type was dynamically allocated at runtime. @@ -42,9 +37,9 @@ internal enum EETypeFlags : uint HasPointersFlag = 0x00200000, /// - /// This type implements IDynamicInterfaceCastable to allow dynamic resolution of interface casts. + /// This MethodTable has sealed vtable entries /// - IDynamicInterfaceCastableFlag = 0x00400000, + HasSealedVTableEntriesFlag = 0x00400000, /// /// This type is generic and one or more of its type parameters is co- or contra-variant. This @@ -71,7 +66,7 @@ internal enum EETypeFlags : uint /// /// Single mark to check TypeKind and two flags. When non-zero, casting is more complicated. /// - ComplexCastingMask = EETypeKindMask | RelatedTypeViaIATFlag | GenericVarianceFlag, + ComplexCastingMask = EETypeKindMask | GenericVarianceFlag, /// /// The _usComponentSize is a number (not holding FlagsEx). @@ -89,6 +84,11 @@ internal enum EETypeFlagsEx : ushort HasEagerFinalizerFlag = 0x0001, HasCriticalFinalizerFlag = 0x0002, IsTrackedReferenceWithFinalizerFlag = 0x0004, + + /// + /// This type implements IDynamicInterfaceCastable to allow dynamic resolution of interface casts. + /// + IDynamicInterfaceCastableFlag = 0x0008, } internal enum EETypeKind : uint @@ -148,10 +148,7 @@ internal enum EETypeRareFlags : int /// IsHFAFlag = 0x00000100, - /// - /// This MethodTable has sealed vtable entries - /// - HasSealedVTableEntriesFlag = 0x00000200, + // Unused = 0x00000200, /// /// This dynamically created types has gc statics @@ -170,10 +167,7 @@ internal enum EETypeRareFlags : int // UNUSED = 0x00002000, - /// - /// This MethodTable is an abstract class (but not an interface). - /// - IsAbstractClassFlag = 0x00004000, + // UNUSED = 0x00004000, /// /// This MethodTable is for a Byref-like class (TypedReference, Span<T>,...) @@ -186,12 +180,14 @@ internal enum EETypeField ETF_InterfaceMap, ETF_TypeManagerIndirection, ETF_WritableData, + ETF_DispatchMap, ETF_Finalizer, ETF_OptionalFieldsPtr, ETF_SealedVirtualSlots, ETF_DynamicTemplateType, ETF_GenericDefinition, ETF_GenericComposition, + ETF_FunctionPointerParameters, ETF_DynamicGcStatics, ETF_DynamicNonGcStatics, ETF_DynamicThreadStaticOffset, @@ -244,11 +240,6 @@ internal enum EETypeOptionalFieldTag : byte /// RareFlags, - /// - /// Index of the dispatch map pointer in the DispatchMap table - /// - DispatchMap, - /// /// Padding added to a value type when allocated on the GC heap /// @@ -283,6 +274,12 @@ internal static class ParameterizedTypeShapeConstants public const int ByRef = 1; } + internal static class FunctionPointerFlags + { + public const uint IsUnmanaged = 0x80000000; + public const uint FlagsMask = IsUnmanaged; + } + internal static class StringComponentSize { public const int Value = sizeof(char); diff --git a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs index f1985389496664..54f9001dc33e08 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs @@ -16,7 +16,7 @@ internal struct ReadyToRunHeaderConstants public const uint Signature = 0x00525452; // 'RTR' public const ushort CurrentMajorVersion = 9; - public const ushort CurrentMinorVersion = 0; + public const ushort CurrentMinorVersion = 1; } #if READYTORUN #pragma warning disable 0169 @@ -78,7 +78,7 @@ public enum ReadyToRunSectionType StringTable = 200, // Unused GCStaticRegion = 201, ThreadStaticRegion = 202, - InterfaceDispatchTable = 203, + // Unused = 203, TypeManagerIndirection = 204, EagerCctor = 205, FrozenObjectRegion = 206, diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index 36e50e01857368..f46904cab3e095 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -256,6 +256,8 @@ public enum ReadyToRunHelper GenericNonGcTlsBase = 0x67, VirtualFuncPtr = 0x68, IsInstanceOfException = 0x69, + NewMaybeFrozenArray = 0x6A, + NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops LMul = 0xC0, @@ -340,8 +342,6 @@ public enum ReadyToRunHelper GetRuntimeType, - AreTypesEquivalent, - CheckCastClass, CheckInstanceClass, CheckCastArray, diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs index 183c307c12bcea..0068f0be007764 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs @@ -48,6 +48,8 @@ public enum ReadyToRunInstructionSet Avx512CD_VL=34, Avx512DQ=35, Avx512DQ_VL=36, + Avx512Vbmi=37, + Avx512Vbmi_VL=38, } } diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs index 4b82e02d647a15..b387eedd89f2b7 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs @@ -110,6 +110,10 @@ public static class ReadyToRunInstructionSetHelper case InstructionSet.X64_AVX512DQ_X64: return ReadyToRunInstructionSet.Avx512DQ; case InstructionSet.X64_AVX512DQ_VL: return ReadyToRunInstructionSet.Avx512DQ_VL; case InstructionSet.X64_AVX512DQ_VL_X64: return ReadyToRunInstructionSet.Avx512DQ_VL; + case InstructionSet.X64_AVX512VBMI: return ReadyToRunInstructionSet.Avx512Vbmi; + case InstructionSet.X64_AVX512VBMI_X64: return ReadyToRunInstructionSet.Avx512Vbmi; + case InstructionSet.X64_AVX512VBMI_VL: return ReadyToRunInstructionSet.Avx512Vbmi_VL; + case InstructionSet.X64_AVX512VBMI_VL_X64: return ReadyToRunInstructionSet.Avx512Vbmi_VL; default: throw new Exception("Unknown instruction set"); } @@ -176,6 +180,10 @@ public static class ReadyToRunInstructionSetHelper case InstructionSet.X86_AVX512DQ_X64: return null; case InstructionSet.X86_AVX512DQ_VL: return ReadyToRunInstructionSet.Avx512DQ_VL; case InstructionSet.X86_AVX512DQ_VL_X64: return null; + case InstructionSet.X86_AVX512VBMI: return ReadyToRunInstructionSet.Avx512Vbmi; + case InstructionSet.X86_AVX512VBMI_X64: return null; + case InstructionSet.X86_AVX512VBMI_VL: return ReadyToRunInstructionSet.Avx512Vbmi_VL; + case InstructionSet.X86_AVX512VBMI_VL_X64: return null; default: throw new Exception("Unknown instruction set"); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index e4cc6a13c3e174..06bc0f6363a09a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -47,6 +47,7 @@ public enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, + CORINFO_HELP_NEWFAST_MAYBEFROZEN, // allocator for objects that *might* allocate them on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned @@ -55,6 +56,7 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEW_MDARR, // multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE, // rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation + CORINFO_HELP_NEWARR_1_MAYBEFROZEN, // allocator for arrays that *might* allocate them on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start @@ -161,7 +163,7 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_SETFIELDDOUBLE, CORINFO_HELP_GETFIELDADDR, - + CORINFO_HELP_GETSTATICFIELDADDR, CORINFO_HELP_GETSTATICFIELDADDR_TLS, // Helper for PE TLS fields // There are a variety of specialized helpers for accessing static fields. The JIT should use @@ -225,8 +227,6 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type - CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent - CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time // Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper. diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 9ad3bd7156dd7d..6d3806f2987682 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2571,8 +2571,6 @@ private CorInfoType getTypeForPrimitiveNumericClass(CORINFO_CLASS_STRUCT_* cls) private bool canCast(CORINFO_CLASS_STRUCT_* child, CORINFO_CLASS_STRUCT_* parent) { throw new NotImplementedException("canCast"); } - private bool areTypesEquivalent(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { throw new NotImplementedException("areTypesEquivalent"); } private TypeCompareState compareTypesForCast(CORINFO_CLASS_STRUCT_* fromClass, CORINFO_CLASS_STRUCT_* toClass) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 26b637ef6357d0..3c7f632ef8e7b0 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1195,21 +1195,6 @@ private static byte _canCast(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLA } } - [UnmanagedCallersOnly] - private static byte _areTypesEquivalent(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { - var _this = GetThis(thisHandle); - try - { - return _this.areTypesEquivalent(cls1, cls2) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static TypeCompareState _compareTypesForCast(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* fromClass, CORINFO_CLASS_STRUCT_* toClass) { @@ -2303,12 +2288,27 @@ private static uint _getClassDomainID(IntPtr thisHandle, IntPtr* ppException, CO } [UnmanagedCallersOnly] - private static byte _getReadonlyStaticFieldValue(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, byte* buffer, int bufferSize, int valueOffset, byte ignoreMovableObjects) + private static byte _getStaticFieldContent(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, byte* buffer, int bufferSize, int valueOffset, byte ignoreMovableObjects) + { + var _this = GetThis(thisHandle); + try + { + return _this.getStaticFieldContent(field, buffer, bufferSize, valueOffset, ignoreMovableObjects != 0) ? (byte)1 : (byte)0; + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + + [UnmanagedCallersOnly] + private static byte _getObjectContent(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* obj, byte* buffer, int bufferSize, int valueOffset) { var _this = GetThis(thisHandle); try { - return _this.getReadonlyStaticFieldValue(field, buffer, bufferSize, valueOffset, ignoreMovableObjects != 0) ? (byte)1 : (byte)0; + return _this.getObjectContent(obj, buffer, bufferSize, valueOffset) ? (byte)1 : (byte)0; } catch (Exception ex) { @@ -2812,82 +2812,82 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[77] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; callbacks[78] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; callbacks[79] = (delegate* unmanaged)&_canCast; - callbacks[80] = (delegate* unmanaged)&_areTypesEquivalent; - callbacks[81] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[82] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[83] = (delegate* unmanaged)&_mergeClasses; - callbacks[84] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[85] = (delegate* unmanaged)&_isEnum; - callbacks[86] = (delegate* unmanaged)&_getParentType; - callbacks[87] = (delegate* unmanaged)&_getChildType; - callbacks[88] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[89] = (delegate* unmanaged)&_isSDArray; - callbacks[90] = (delegate* unmanaged)&_getArrayRank; - callbacks[91] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[92] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[93] = (delegate* unmanaged)&_canAccessClass; - callbacks[94] = (delegate* unmanaged)&_printFieldName; - callbacks[95] = (delegate* unmanaged)&_getFieldClass; - callbacks[96] = (delegate* unmanaged)&_getFieldType; - callbacks[97] = (delegate* unmanaged)&_getFieldOffset; - callbacks[98] = (delegate* unmanaged)&_getFieldInfo; - callbacks[99] = (delegate* unmanaged)&_getThreadLocalFieldInfo; - callbacks[100] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; - callbacks[101] = (delegate* unmanaged)&_isFieldStatic; - callbacks[102] = (delegate* unmanaged)&_getArrayOrStringLength; - callbacks[103] = (delegate* unmanaged)&_getBoundaries; - callbacks[104] = (delegate* unmanaged)&_setBoundaries; - callbacks[105] = (delegate* unmanaged)&_getVars; - callbacks[106] = (delegate* unmanaged)&_setVars; - callbacks[107] = (delegate* unmanaged)&_reportRichMappings; - callbacks[108] = (delegate* unmanaged)&_allocateArray; - callbacks[109] = (delegate* unmanaged)&_freeArray; - callbacks[110] = (delegate* unmanaged)&_getArgNext; - callbacks[111] = (delegate* unmanaged)&_getArgType; - callbacks[112] = (delegate* unmanaged)&_getExactClasses; - callbacks[113] = (delegate* unmanaged)&_getArgClass; - callbacks[114] = (delegate* unmanaged)&_getHFAType; - callbacks[115] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[116] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[117] = (delegate* unmanaged)&_FilterException; - callbacks[118] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[119] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[120] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[121] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[122] = (delegate* unmanaged)&_getEEInfo; - callbacks[123] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[124] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[125] = (delegate* unmanaged)&_printMethodName; - callbacks[126] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[127] = (delegate* unmanaged)&_getMethodHash; - callbacks[128] = (delegate* unmanaged)&_findNameOfToken; - callbacks[129] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[130] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[131] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; - callbacks[132] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[133] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[134] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[135] = (delegate* unmanaged)&_getHelperFtn; - callbacks[136] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[137] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[138] = (delegate* unmanaged)&_getMethodSync; - callbacks[139] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[140] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[141] = (delegate* unmanaged)&_embedClassHandle; - callbacks[142] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[143] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[144] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[145] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[146] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[147] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[148] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[149] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[150] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[151] = (delegate* unmanaged)&_getCallInfo; - callbacks[152] = (delegate* unmanaged)&_canAccessFamily; - callbacks[153] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[154] = (delegate* unmanaged)&_getClassDomainID; - callbacks[155] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; + callbacks[80] = (delegate* unmanaged)&_compareTypesForCast; + callbacks[81] = (delegate* unmanaged)&_compareTypesForEquality; + callbacks[82] = (delegate* unmanaged)&_mergeClasses; + callbacks[83] = (delegate* unmanaged)&_isMoreSpecificType; + callbacks[84] = (delegate* unmanaged)&_isEnum; + callbacks[85] = (delegate* unmanaged)&_getParentType; + callbacks[86] = (delegate* unmanaged)&_getChildType; + callbacks[87] = (delegate* unmanaged)&_satisfiesClassConstraints; + callbacks[88] = (delegate* unmanaged)&_isSDArray; + callbacks[89] = (delegate* unmanaged)&_getArrayRank; + callbacks[90] = (delegate* unmanaged)&_getArrayIntrinsicID; + callbacks[91] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[92] = (delegate* unmanaged)&_canAccessClass; + callbacks[93] = (delegate* unmanaged)&_printFieldName; + callbacks[94] = (delegate* unmanaged)&_getFieldClass; + callbacks[95] = (delegate* unmanaged)&_getFieldType; + callbacks[96] = (delegate* unmanaged)&_getFieldOffset; + callbacks[97] = (delegate* unmanaged)&_getFieldInfo; + callbacks[98] = (delegate* unmanaged)&_getThreadLocalFieldInfo; + callbacks[99] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; + callbacks[100] = (delegate* unmanaged)&_isFieldStatic; + callbacks[101] = (delegate* unmanaged)&_getArrayOrStringLength; + callbacks[102] = (delegate* unmanaged)&_getBoundaries; + callbacks[103] = (delegate* unmanaged)&_setBoundaries; + callbacks[104] = (delegate* unmanaged)&_getVars; + callbacks[105] = (delegate* unmanaged)&_setVars; + callbacks[106] = (delegate* unmanaged)&_reportRichMappings; + callbacks[107] = (delegate* unmanaged)&_allocateArray; + callbacks[108] = (delegate* unmanaged)&_freeArray; + callbacks[109] = (delegate* unmanaged)&_getArgNext; + callbacks[110] = (delegate* unmanaged)&_getArgType; + callbacks[111] = (delegate* unmanaged)&_getExactClasses; + callbacks[112] = (delegate* unmanaged)&_getArgClass; + callbacks[113] = (delegate* unmanaged)&_getHFAType; + callbacks[114] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[115] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[116] = (delegate* unmanaged)&_FilterException; + callbacks[117] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[118] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[119] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[120] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[121] = (delegate* unmanaged)&_getEEInfo; + callbacks[122] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[123] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[124] = (delegate* unmanaged)&_printMethodName; + callbacks[125] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[126] = (delegate* unmanaged)&_getMethodHash; + callbacks[127] = (delegate* unmanaged)&_findNameOfToken; + callbacks[128] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[129] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[130] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; + callbacks[131] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[132] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[133] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[134] = (delegate* unmanaged)&_getHelperFtn; + callbacks[135] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[136] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[137] = (delegate* unmanaged)&_getMethodSync; + callbacks[138] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[139] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[140] = (delegate* unmanaged)&_embedClassHandle; + callbacks[141] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[142] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[143] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[144] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[145] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[146] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[147] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[148] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[149] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[150] = (delegate* unmanaged)&_getCallInfo; + callbacks[151] = (delegate* unmanaged)&_canAccessFamily; + callbacks[152] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[153] = (delegate* unmanaged)&_getClassDomainID; + callbacks[154] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[155] = (delegate* unmanaged)&_getObjectContent; callbacks[156] = (delegate* unmanaged)&_getStaticFieldCurrentClass; callbacks[157] = (delegate* unmanaged)&_getVarArgsHandle; callbacks[158] = (delegate* unmanaged)&_canGetVarArgsHandle; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs index 69104df677ee2f..73538c68172891 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs @@ -67,6 +67,8 @@ public enum InstructionSet X64_AVX512CD_VL = InstructionSet_X64.AVX512CD_VL, X64_AVX512DQ = InstructionSet_X64.AVX512DQ, X64_AVX512DQ_VL = InstructionSet_X64.AVX512DQ_VL, + X64_AVX512VBMI = InstructionSet_X64.AVX512VBMI, + X64_AVX512VBMI_VL = InstructionSet_X64.AVX512VBMI_VL, X64_X86Base_X64 = InstructionSet_X64.X86Base_X64, X64_SSE_X64 = InstructionSet_X64.SSE_X64, X64_SSE2_X64 = InstructionSet_X64.SSE2_X64, @@ -94,6 +96,8 @@ public enum InstructionSet X64_AVX512CD_VL_X64 = InstructionSet_X64.AVX512CD_VL_X64, X64_AVX512DQ_X64 = InstructionSet_X64.AVX512DQ_X64, X64_AVX512DQ_VL_X64 = InstructionSet_X64.AVX512DQ_VL_X64, + X64_AVX512VBMI_X64 = InstructionSet_X64.AVX512VBMI_X64, + X64_AVX512VBMI_VL_X64 = InstructionSet_X64.AVX512VBMI_VL_X64, X86_X86Base = InstructionSet_X86.X86Base, X86_SSE = InstructionSet_X86.SSE, X86_SSE2 = InstructionSet_X86.SSE2, @@ -124,6 +128,8 @@ public enum InstructionSet X86_AVX512CD_VL = InstructionSet_X86.AVX512CD_VL, X86_AVX512DQ = InstructionSet_X86.AVX512DQ, X86_AVX512DQ_VL = InstructionSet_X86.AVX512DQ_VL, + X86_AVX512VBMI = InstructionSet_X86.AVX512VBMI, + X86_AVX512VBMI_VL = InstructionSet_X86.AVX512VBMI_VL, X86_X86Base_X64 = InstructionSet_X86.X86Base_X64, X86_SSE_X64 = InstructionSet_X86.SSE_X64, X86_SSE2_X64 = InstructionSet_X86.SSE2_X64, @@ -151,6 +157,8 @@ public enum InstructionSet X86_AVX512CD_VL_X64 = InstructionSet_X86.AVX512CD_VL_X64, X86_AVX512DQ_X64 = InstructionSet_X86.AVX512DQ_X64, X86_AVX512DQ_VL_X64 = InstructionSet_X86.AVX512DQ_VL_X64, + X86_AVX512VBMI_X64 = InstructionSet_X86.AVX512VBMI_X64, + X86_AVX512VBMI_VL_X64 = InstructionSet_X86.AVX512VBMI_VL_X64, } public enum InstructionSet_ARM64 { @@ -213,33 +221,37 @@ public enum InstructionSet_X64 AVX512CD_VL = 28, AVX512DQ = 29, AVX512DQ_VL = 30, - X86Base_X64 = 31, - SSE_X64 = 32, - SSE2_X64 = 33, - SSE3_X64 = 34, - SSSE3_X64 = 35, - SSE41_X64 = 36, - SSE42_X64 = 37, - AVX_X64 = 38, - AVX2_X64 = 39, - AES_X64 = 40, - BMI1_X64 = 41, - BMI2_X64 = 42, - FMA_X64 = 43, - LZCNT_X64 = 44, - PCLMULQDQ_X64 = 45, - POPCNT_X64 = 46, - AVXVNNI_X64 = 47, - MOVBE_X64 = 48, - X86Serialize_X64 = 49, - AVX512F_X64 = 50, - AVX512F_VL_X64 = 51, - AVX512BW_X64 = 52, - AVX512BW_VL_X64 = 53, - AVX512CD_X64 = 54, - AVX512CD_VL_X64 = 55, - AVX512DQ_X64 = 56, - AVX512DQ_VL_X64 = 57, + AVX512VBMI = 31, + AVX512VBMI_VL = 32, + X86Base_X64 = 33, + SSE_X64 = 34, + SSE2_X64 = 35, + SSE3_X64 = 36, + SSSE3_X64 = 37, + SSE41_X64 = 38, + SSE42_X64 = 39, + AVX_X64 = 40, + AVX2_X64 = 41, + AES_X64 = 42, + BMI1_X64 = 43, + BMI2_X64 = 44, + FMA_X64 = 45, + LZCNT_X64 = 46, + PCLMULQDQ_X64 = 47, + POPCNT_X64 = 48, + AVXVNNI_X64 = 49, + MOVBE_X64 = 50, + X86Serialize_X64 = 51, + AVX512F_X64 = 52, + AVX512F_VL_X64 = 53, + AVX512BW_X64 = 54, + AVX512BW_VL_X64 = 55, + AVX512CD_X64 = 56, + AVX512CD_VL_X64 = 57, + AVX512DQ_X64 = 58, + AVX512DQ_VL_X64 = 59, + AVX512VBMI_X64 = 60, + AVX512VBMI_VL_X64 = 61, } public enum InstructionSet_X86 @@ -276,33 +288,37 @@ public enum InstructionSet_X86 AVX512CD_VL = 28, AVX512DQ = 29, AVX512DQ_VL = 30, - X86Base_X64 = 31, - SSE_X64 = 32, - SSE2_X64 = 33, - SSE3_X64 = 34, - SSSE3_X64 = 35, - SSE41_X64 = 36, - SSE42_X64 = 37, - AVX_X64 = 38, - AVX2_X64 = 39, - AES_X64 = 40, - BMI1_X64 = 41, - BMI2_X64 = 42, - FMA_X64 = 43, - LZCNT_X64 = 44, - PCLMULQDQ_X64 = 45, - POPCNT_X64 = 46, - AVXVNNI_X64 = 47, - MOVBE_X64 = 48, - X86Serialize_X64 = 49, - AVX512F_X64 = 50, - AVX512F_VL_X64 = 51, - AVX512BW_X64 = 52, - AVX512BW_VL_X64 = 53, - AVX512CD_X64 = 54, - AVX512CD_VL_X64 = 55, - AVX512DQ_X64 = 56, - AVX512DQ_VL_X64 = 57, + AVX512VBMI = 31, + AVX512VBMI_VL = 32, + X86Base_X64 = 33, + SSE_X64 = 34, + SSE2_X64 = 35, + SSE3_X64 = 36, + SSSE3_X64 = 37, + SSE41_X64 = 38, + SSE42_X64 = 39, + AVX_X64 = 40, + AVX2_X64 = 41, + AES_X64 = 42, + BMI1_X64 = 43, + BMI2_X64 = 44, + FMA_X64 = 45, + LZCNT_X64 = 46, + PCLMULQDQ_X64 = 47, + POPCNT_X64 = 48, + AVXVNNI_X64 = 49, + MOVBE_X64 = 50, + X86Serialize_X64 = 51, + AVX512F_X64 = 52, + AVX512F_VL_X64 = 53, + AVX512BW_X64 = 54, + AVX512BW_VL_X64 = 55, + AVX512CD_X64 = 56, + AVX512CD_VL_X64 = 57, + AVX512DQ_X64 = 58, + AVX512DQ_VL_X64 = 59, + AVX512VBMI_X64 = 60, + AVX512VBMI_VL_X64 = 61, } public unsafe struct InstructionSetFlags : IEnumerable @@ -622,6 +638,14 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X64_AVX512DQ_VL_X64); if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512DQ_VL_X64)) resultflags.AddInstructionSet(InstructionSet.X64_AVX512DQ_VL); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI_X64); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI_X64)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI_VL)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI_VL_X64); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI_VL_X64)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI_VL); if (resultflags.HasInstructionSet(InstructionSet.X64_SSE)) resultflags.AddInstructionSet(InstructionSet.X64_X86Base); if (resultflags.HasInstructionSet(InstructionSet.X64_SSE2)) @@ -680,6 +704,10 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X64_AVX512F); if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512DQ_VL)) resultflags.AddInstructionSet(InstructionSet.X64_AVX512F_VL); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512BW); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI_VL)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512BW_VL); break; case TargetArchitecture.X86: @@ -741,6 +769,10 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X86_AVX512F); if (resultflags.HasInstructionSet(InstructionSet.X86_AVX512DQ_VL)) resultflags.AddInstructionSet(InstructionSet.X86_AVX512F_VL); + if (resultflags.HasInstructionSet(InstructionSet.X86_AVX512VBMI)) + resultflags.AddInstructionSet(InstructionSet.X86_AVX512BW); + if (resultflags.HasInstructionSet(InstructionSet.X86_AVX512VBMI_VL)) + resultflags.AddInstructionSet(InstructionSet.X86_AVX512BW_VL); break; } } while (!oldflags.Equals(resultflags)); @@ -855,6 +887,10 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X64_AVX512DQ); if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512DQ_VL_X64)) resultflags.AddInstructionSet(InstructionSet.X64_AVX512DQ_VL); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI_X64)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512VBMI_VL_X64)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI_VL); if (resultflags.HasInstructionSet(InstructionSet.X64_X86Base)) resultflags.AddInstructionSet(InstructionSet.X64_SSE); if (resultflags.HasInstructionSet(InstructionSet.X64_SSE)) @@ -913,6 +949,10 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X64_AVX512DQ); if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512F_VL)) resultflags.AddInstructionSet(InstructionSet.X64_AVX512DQ_VL); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512BW)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX512BW_VL)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX512VBMI_VL); break; case TargetArchitecture.X86: @@ -974,6 +1014,10 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X86_AVX512DQ); if (resultflags.HasInstructionSet(InstructionSet.X86_AVX512F_VL)) resultflags.AddInstructionSet(InstructionSet.X86_AVX512DQ_VL); + if (resultflags.HasInstructionSet(InstructionSet.X86_AVX512BW)) + resultflags.AddInstructionSet(InstructionSet.X86_AVX512VBMI); + if (resultflags.HasInstructionSet(InstructionSet.X86_AVX512BW_VL)) + resultflags.AddInstructionSet(InstructionSet.X86_AVX512VBMI_VL); break; } } while (!oldflags.Equals(resultflags)); @@ -1077,6 +1121,8 @@ public static IEnumerable ArchitectureToValidInstructionSets yield return new InstructionSetInfo("avx512cd_vl", "Avx512CD_VL", InstructionSet.X64_AVX512CD_VL, true); yield return new InstructionSetInfo("avx512dq", "Avx512DQ", InstructionSet.X64_AVX512DQ, true); yield return new InstructionSetInfo("avx512dq_vl", "Avx512DQ_VL", InstructionSet.X64_AVX512DQ_VL, true); + yield return new InstructionSetInfo("avx512vbmi", "Avx512Vbmi", InstructionSet.X64_AVX512VBMI, true); + yield return new InstructionSetInfo("avx512vbmi_vl", "Avx512Vbmi_VL", InstructionSet.X64_AVX512VBMI_VL, true); break; case TargetArchitecture.X86: @@ -1110,6 +1156,8 @@ public static IEnumerable ArchitectureToValidInstructionSets yield return new InstructionSetInfo("avx512cd_vl", "Avx512CD_VL", InstructionSet.X86_AVX512CD_VL, true); yield return new InstructionSetInfo("avx512dq", "Avx512DQ", InstructionSet.X86_AVX512DQ, true); yield return new InstructionSetInfo("avx512dq_vl", "Avx512DQ_VL", InstructionSet.X86_AVX512DQ_VL, true); + yield return new InstructionSetInfo("avx512vbmi", "Avx512Vbmi", InstructionSet.X86_AVX512VBMI, true); + yield return new InstructionSetInfo("avx512vbmi_vl", "Avx512Vbmi_VL", InstructionSet.X86_AVX512VBMI_VL, true); break; } } @@ -1193,6 +1241,10 @@ public void Set64BitInstructionSetVariants(TargetArchitecture architecture) AddInstructionSet(InstructionSet.X64_AVX512DQ_X64); if (HasInstructionSet(InstructionSet.X64_AVX512DQ_VL)) AddInstructionSet(InstructionSet.X64_AVX512DQ_VL_X64); + if (HasInstructionSet(InstructionSet.X64_AVX512VBMI)) + AddInstructionSet(InstructionSet.X64_AVX512VBMI_X64); + if (HasInstructionSet(InstructionSet.X64_AVX512VBMI_VL)) + AddInstructionSet(InstructionSet.X64_AVX512VBMI_VL_X64); break; case TargetArchitecture.X86: @@ -1244,6 +1296,8 @@ public void Set64BitInstructionSetVariantsUnconditionally(TargetArchitecture arc AddInstructionSet(InstructionSet.X64_AVX512CD_VL_X64); AddInstructionSet(InstructionSet.X64_AVX512DQ_X64); AddInstructionSet(InstructionSet.X64_AVX512DQ_VL_X64); + AddInstructionSet(InstructionSet.X64_AVX512VBMI_X64); + AddInstructionSet(InstructionSet.X64_AVX512VBMI_VL_X64); break; case TargetArchitecture.X86: @@ -1274,6 +1328,8 @@ public void Set64BitInstructionSetVariantsUnconditionally(TargetArchitecture arc AddInstructionSet(InstructionSet.X86_AVX512CD_VL_X64); AddInstructionSet(InstructionSet.X86_AVX512DQ_X64); AddInstructionSet(InstructionSet.X86_AVX512DQ_VL_X64); + AddInstructionSet(InstructionSet.X86_AVX512VBMI_X64); + AddInstructionSet(InstructionSet.X86_AVX512VBMI_VL_X64); break; } } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index b45184a5b68037..cedbbda36b7046 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -116,7 +116,8 @@ public unsafe struct CORINFO_SIG_INFO private CorInfoCallConv getCallConv() { return (CorInfoCallConv)((callConv & CorInfoCallConv.CORINFO_CALLCONV_MASK)); } private bool hasThis() { return ((callConv & CorInfoCallConv.CORINFO_CALLCONV_HASTHIS) != 0); } private bool hasExplicitThis() { return ((callConv & CorInfoCallConv.CORINFO_CALLCONV_EXPLICITTHIS) != 0); } - private uint totalILArgs() { return (uint)(numArgs + (hasThis() ? 1 : 0)); } + private bool hasImplicitThis() { return ((callConv & (CorInfoCallConv.CORINFO_CALLCONV_HASTHIS | CorInfoCallConv.CORINFO_CALLCONV_EXPLICITTHIS)) == CorInfoCallConv.CORINFO_CALLCONV_HASTHIS); } + private uint totalILArgs() { return (uint)(numArgs + (hasImplicitThis() ? 1 : 0)); } private bool isVarArg() { return ((getCallConv() == CorInfoCallConv.CORINFO_CALLCONV_VARARG) || (getCallConv() == CorInfoCallConv.CORINFO_CALLCONV_NATIVEVARARG)); } internal bool hasTypeArg() { return ((callConv & CorInfoCallConv.CORINFO_CALLCONV_PARAMTYPE) != 0); } }; @@ -1410,6 +1411,7 @@ public enum CorJitFlag : uint CORJIT_FLAG_UNUSED6 = 12, CORJIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT + CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators CORJIT_FLAG_UNUSED10 = 17, CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter. CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt index 3841be35e5226b..fa4107640b494a 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt @@ -23,38 +23,41 @@ ; DO NOT CHANGE R2R NUMERIC VALUES OF THE EXISTING SETS. Changing R2R numeric values definitions would be R2R format breaking change. ; Definition of X86 instruction sets -definearch ,X86 ,32Bit ,X64 - -instructionset ,X86 ,X86Base , ,22 ,X86Base ,base -instructionset ,X86 ,Sse , ,1 ,SSE ,sse -instructionset ,X86 ,Sse2 , ,2 ,SSE2 ,sse2 -instructionset ,X86 ,Sse3 , ,3 ,SSE3 ,sse3 -instructionset ,X86 ,Ssse3 , ,4 ,SSSE3 ,ssse3 -instructionset ,X86 ,Sse41 , ,5 ,SSE41 ,sse4.1 -instructionset ,X86 ,Sse42 , ,6 ,SSE42 ,sse4.2 -instructionset ,X86 ,Avx , ,7 ,AVX ,avx -instructionset ,X86 ,Avx2 , ,8 ,AVX2 ,avx2 -instructionset ,X86 ,Aes , ,9 ,AES ,aes -instructionset ,X86 ,Bmi1 , ,10 ,BMI1 ,bmi -instructionset ,X86 ,Bmi2 , ,11 ,BMI2 ,bmi2 -instructionset ,X86 ,Fma , ,12 ,FMA ,fma -instructionset ,X86 ,Lzcnt , ,13 ,LZCNT ,lzcnt -instructionset ,X86 ,Pclmulqdq , ,14 ,PCLMULQDQ,pclmul -instructionset ,X86 ,Popcnt , ,15 ,POPCNT ,popcnt -instructionset ,X86 , , , ,Vector128, -instructionset ,X86 , , , ,Vector256, -instructionset ,X86 , , , ,Vector512, -instructionset ,X86 ,AvxVnni , ,25 ,AVXVNNI ,avxvnni -instructionset ,X86 ,Movbe , ,27 ,MOVBE ,movbe -instructionset ,X86 ,X86Serialize , ,28 ,X86Serialize ,serialize -instructionset ,X86 ,Avx512F , ,29 ,AVX512F ,avx512f -instructionset ,X86 ,Avx512F_VL, ,30 ,AVX512F_VL ,avx512f_vl -instructionset ,X86 ,Avx512BW , ,31 ,AVX512BW ,avx512bw -instructionset ,X86 ,Avx512BW_VL, ,32 ,AVX512BW_VL ,avx512bw_vl -instructionset ,X86 ,Avx512CD , ,33 ,AVX512CD ,avx512cd -instructionset ,X86 ,Avx512CD_VL, ,34 ,AVX512CD_VL ,avx512cd_vl -instructionset ,X86 ,Avx512DQ , ,35 ,AVX512DQ ,avx512dq -instructionset ,X86 ,Avx512DQ_VL, ,36 ,AVX512DQ_VL ,avx512dq_vl +definearch ,X86 ,32Bit ,X64 + +instructionset ,X86 ,X86Base , ,22 ,X86Base ,base +instructionset ,X86 ,Sse , ,1 ,SSE ,sse +instructionset ,X86 ,Sse2 , ,2 ,SSE2 ,sse2 +instructionset ,X86 ,Sse3 , ,3 ,SSE3 ,sse3 +instructionset ,X86 ,Ssse3 , ,4 ,SSSE3 ,ssse3 +instructionset ,X86 ,Sse41 , ,5 ,SSE41 ,sse4.1 +instructionset ,X86 ,Sse42 , ,6 ,SSE42 ,sse4.2 +instructionset ,X86 ,Avx , ,7 ,AVX ,avx +instructionset ,X86 ,Avx2 , ,8 ,AVX2 ,avx2 +instructionset ,X86 ,Aes , ,9 ,AES ,aes +instructionset ,X86 ,Bmi1 , ,10 ,BMI1 ,bmi +instructionset ,X86 ,Bmi2 , ,11 ,BMI2 ,bmi2 +instructionset ,X86 ,Fma , ,12 ,FMA ,fma +instructionset ,X86 ,Lzcnt , ,13 ,LZCNT ,lzcnt +instructionset ,X86 ,Pclmulqdq , ,14 ,PCLMULQDQ ,pclmul +instructionset ,X86 ,Popcnt , ,15 ,POPCNT ,popcnt +instructionset ,X86 , , , ,Vector128 , +instructionset ,X86 , , , ,Vector256 , +instructionset ,X86 , , , ,Vector512 , +instructionset ,X86 ,AvxVnni , ,25 ,AVXVNNI ,avxvnni +instructionset ,X86 ,Movbe , ,27 ,MOVBE ,movbe +instructionset ,X86 ,X86Serialize , ,28 ,X86Serialize ,serialize +instructionset ,X86 ,Avx512F , ,29 ,AVX512F ,avx512f +instructionset ,X86 ,Avx512F_VL , ,30 ,AVX512F_VL ,avx512f_vl +instructionset ,X86 ,Avx512BW , ,31 ,AVX512BW ,avx512bw +instructionset ,X86 ,Avx512BW_VL , ,32 ,AVX512BW_VL ,avx512bw_vl +instructionset ,X86 ,Avx512CD , ,33 ,AVX512CD ,avx512cd +instructionset ,X86 ,Avx512CD_VL , ,34 ,AVX512CD_VL ,avx512cd_vl +instructionset ,X86 ,Avx512DQ , ,35 ,AVX512DQ ,avx512dq +instructionset ,X86 ,Avx512DQ_VL , ,36 ,AVX512DQ_VL ,avx512dq_vl +instructionset ,X86 ,Avx512Vbmi , ,37 ,AVX512VBMI ,avx512vbmi +instructionset ,X86 ,Avx512Vbmi_VL , ,38 ,AVX512VBMI_VL ,avx512vbmi_vl + instructionset64bit,X86 ,X86Base instructionset64bit,X86 ,SSE @@ -83,41 +86,44 @@ instructionset64bit,X86 ,AVX512CD instructionset64bit,X86 ,AVX512CD_VL instructionset64bit,X86 ,AVX512DQ instructionset64bit,X86 ,AVX512DQ_VL +instructionset64bit,X86 ,AVX512VBMI +instructionset64bit,X86 ,AVX512VBMI_VL vectorinstructionset,X86 ,Vector128 vectorinstructionset,X86 ,Vector256 vectorinstructionset,X86 ,Vector512 -implication ,X86 ,SSE ,X86Base -implication ,X86 ,SSE2 ,SSE -implication ,X86 ,SSE3 ,SSE2 -implication ,X86 ,SSSE3 ,SSE3 -implication ,X86 ,SSE41 ,SSSE3 -implication ,X86 ,SSE42 ,SSE41 -implication ,X86 ,AVX ,SSE42 -implication ,X86 ,AVX2 ,AVX -implication ,X86 ,AES ,SSE2 -implication ,X86 ,BMI1 ,AVX -implication ,X86 ,BMI2 ,AVX -implication ,X86 ,FMA ,AVX -implication ,X86 ,LZCNT ,X86Base -implication ,X86 ,PCLMULQDQ ,SSE2 -implication ,X86 ,POPCNT ,SSE42 -implication ,X86 ,Vector128 ,SSE -implication ,X86 ,Vector256 ,AVX -implication ,X86 ,Vector512 ,AVX512F -implication ,X86 ,AVXVNNI ,AVX2 -implication ,X86 ,MOVBE ,SSE42 -implication ,X86 ,X86Serialize, X86Base - -implication ,X86 ,AVX512F, AVX2 -implication ,X86 ,AVX512F_VL,AVX512F -implication ,X86 ,AVX512CD, AVX512F -implication ,X86 ,AVX512CD_VL, AVX512F_VL -implication ,X86 ,AVX512BW, AVX512F -implication ,X86 ,AVX512BW_VL, AVX512F_VL -implication ,X86 ,AVX512DQ, AVX512F -implication ,X86 ,AVX512DQ_VL, AVX512F_VL +implication ,X86 ,SSE ,X86Base +implication ,X86 ,SSE2 ,SSE +implication ,X86 ,SSE3 ,SSE2 +implication ,X86 ,SSSE3 ,SSE3 +implication ,X86 ,SSE41 ,SSSE3 +implication ,X86 ,SSE42 ,SSE41 +implication ,X86 ,AVX ,SSE42 +implication ,X86 ,AVX2 ,AVX +implication ,X86 ,AES ,SSE2 +implication ,X86 ,BMI1 ,AVX +implication ,X86 ,BMI2 ,AVX +implication ,X86 ,FMA ,AVX +implication ,X86 ,LZCNT ,X86Base +implication ,X86 ,PCLMULQDQ ,SSE2 +implication ,X86 ,POPCNT ,SSE42 +implication ,X86 ,Vector128 ,SSE +implication ,X86 ,Vector256 ,AVX +implication ,X86 ,Vector512 ,AVX512F +implication ,X86 ,AVXVNNI ,AVX2 +implication ,X86 ,MOVBE ,SSE42 +implication ,X86 ,X86Serialize ,X86Base +implication ,X86 ,AVX512F ,AVX2 +implication ,X86 ,AVX512F_VL ,AVX512F +implication ,X86 ,AVX512CD ,AVX512F +implication ,X86 ,AVX512CD_VL ,AVX512F_VL +implication ,X86 ,AVX512BW ,AVX512F +implication ,X86 ,AVX512BW_VL ,AVX512F_VL +implication ,X86 ,AVX512DQ ,AVX512F +implication ,X86 ,AVX512DQ_VL ,AVX512F_VL +implication ,X86 ,AVX512VBMI ,AVX512BW +implication ,X86 ,AVX512VBMI_VL ,AVX512BW_VL ; Definition of X64 instruction sets definearch ,X64 ,64Bit ,X64 diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 5c4d8ad0b94b13..b9f8aa66f259eb 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -239,7 +239,6 @@ FUNCTIONS CorInfoType getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls) CorInfoType getTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls) bool canCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent) - bool areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) TypeCompareState compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) @@ -314,7 +313,8 @@ FUNCTIONS bool canAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType); bool isRIDClassDomainID(CORINFO_CLASS_HANDLE cls); unsigned getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirection); - bool getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t *buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); + bool getStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t *buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); + bool getObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t *buffer, int bufferSize, int valueOffset); CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, BoolStar pIsSpeculative); CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *pSig, void **ppIndirection); bool canGetVarArgsHandle(CORINFO_SIG_INFO *pSig); diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs index 13b22edc3609aa..1047c075c2f623 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs @@ -47,6 +47,8 @@ public abstract TypeDesc FieldType // Get the embedded signature data used to hold custom modifiers and such within a field signature public abstract EmbeddedSignatureData[] GetEmbeddedSignatureData(); + public abstract bool HasEmbeddedSignatureData { get; } + public abstract bool IsStatic { get; diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs index 692e4db2a0aa9b..04e403356ba472 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs @@ -54,6 +54,14 @@ public override EmbeddedSignatureData[] GetEmbeddedSignatureData() return _fieldDef.GetEmbeddedSignatureData(); } + public override bool HasEmbeddedSignatureData + { + get + { + return _fieldDef.HasEmbeddedSignatureData; + } + } + public override bool IsStatic { get diff --git a/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs b/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs index 8a99786b4a49c6..3e130eb2d3f77e 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs @@ -11,6 +11,8 @@ public struct PropertySignature public readonly TypeDesc ReturnType; + private readonly EmbeddedSignatureData[] _embeddedSignatureData; + [System.Runtime.CompilerServices.IndexerName("Parameter")] public TypeDesc this[int index] { @@ -28,11 +30,20 @@ public int Length } } - public PropertySignature(bool isStatic, TypeDesc[] parameters, TypeDesc returnType) + public bool HasEmbeddedSignatureData + { + get + { + return _embeddedSignatureData != null; + } + } + + public PropertySignature(bool isStatic, TypeDesc[] parameters, TypeDesc returnType, EmbeddedSignatureData[] embeddedSignatureData) { IsStatic = isStatic; _parameters = parameters; ReturnType = returnType; + _embeddedSignatureData = embeddedSignatureData; } } } diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs index c7128495897b9f..01356a7200052d 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs @@ -22,6 +22,9 @@ private static class FieldFlags public const int AttributeMetadataCache = 0x0100; public const int ThreadStatic = 0x0200; public const int Intrinsic = 0x0400; + + // Computed when field type is computed + public const int HasEmbeddedSignatureData = 0x0800; }; private EcmaType _type; @@ -98,7 +101,11 @@ private TypeDesc InitializeFieldType() BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetFieldDefinition(_handle).Signature); EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader, NotFoundBehavior.Throw); - var fieldType = parser.ParseFieldSignature(); + var fieldType = parser.ParseFieldSignature(out EmbeddedSignatureData[] data); + + if (data != null) + _fieldFlags.AddFlags(FieldFlags.HasEmbeddedSignatureData); + return (_fieldType = fieldType); } @@ -112,6 +119,17 @@ public override TypeDesc FieldType } } + public override bool HasEmbeddedSignatureData + { + get + { + if (_fieldType == null) + InitializeFieldType(); + + return _fieldFlags.HasFlags(FieldFlags.HasEmbeddedSignatureData); + } + } + // This is extremely rarely needed. Don't cache it at all. public override EmbeddedSignatureData[] GetEmbeddedSignatureData() { diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs index 318ca38f800214..be72b3d71accf0 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs @@ -327,19 +327,10 @@ public bool IsFieldSignature public MethodSignature ParseMethodSignature() { - try - { - _indexStack = new Stack(); - _indexStack.Push(0); - _embeddedSignatureDataList = new List(); - return ParseMethodSignatureInternal(skipEmbeddedSignatureData: false); - } - finally - { - _indexStack = null; - _embeddedSignatureDataList = null; - } - + _indexStack = new Stack(); + _indexStack.Push(0); + _embeddedSignatureDataList = new List(); + return ParseMethodSignatureInternal(skipEmbeddedSignatureData: false); } private MethodSignature ParseMethodSignatureInternal(bool skipEmbeddedSignatureData) @@ -420,6 +411,14 @@ private MethodSignature ParseMethodSignatureImpl(bool skipEmbeddedSignatureData) } public PropertySignature ParsePropertySignature() + { + _indexStack = new Stack(); + _indexStack.Push(0); + _embeddedSignatureDataList = new List(); + return ParsePropertySignatureInternal(); + } + + private PropertySignature ParsePropertySignatureInternal() { // As PropertySignature is a struct, we cannot return null if (_notFoundBehavior != NotFoundBehavior.Throw) @@ -450,7 +449,9 @@ public PropertySignature ParsePropertySignature() parameters = TypeDesc.EmptyTypes; } - return new PropertySignature(isStatic, parameters, returnType); + EmbeddedSignatureData[] embeddedSignatureDataArray = (_embeddedSignatureDataList == null || _embeddedSignatureDataList.Count == 0) ? null : _embeddedSignatureDataList.ToArray(); + + return new PropertySignature(isStatic, parameters, returnType, embeddedSignatureDataArray); } public TypeDesc ParseFieldSignature() @@ -463,21 +464,13 @@ public TypeDesc ParseFieldSignature() public TypeDesc ParseFieldSignature(out EmbeddedSignatureData[] embeddedSigData) { - try - { - _indexStack = new Stack(); - _indexStack.Push(1); - _indexStack.Push(0); - _embeddedSignatureDataList = new List(); - TypeDesc parsedType = ParseFieldSignature(); - embeddedSigData = _embeddedSignatureDataList.Count == 0 ? null : _embeddedSignatureDataList.ToArray(); - return parsedType; - } - finally - { - _indexStack = null; - _embeddedSignatureDataList = null; - } + _indexStack = new Stack(); + _indexStack.Push(1); + _indexStack.Push(0); + _embeddedSignatureDataList = new List(); + TypeDesc parsedType = ParseFieldSignature(); + embeddedSigData = _embeddedSignatureDataList.Count == 0 ? null : _embeddedSignatureDataList.ToArray(); + return parsedType; } public LocalVariableDefinition[] ParseLocalsSignature() diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ArrayMethodILEmitter.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ArrayMethodILEmitter.cs index 0c81ec32862007..b90abeeb79ab9b 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ArrayMethodILEmitter.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ArrayMethodILEmitter.cs @@ -126,11 +126,9 @@ private void EmitILForAccessor() codeStream.Emit(ILOpcode.call, _emitter.NewToken(eetypeType.GetKnownMethod("get_RelatedParameterType", null))); - // if (TypeCast.AreTypesEquivalent(expectedElementType, actualElementType)) + // if (expectedElementType != actualElementType) // ThrowHelpers.ThrowArrayTypeMismatchException(); - codeStream.Emit(ILOpcode.call, _emitter.NewToken( - context.SystemModule.GetKnownType("System.Runtime", "TypeCast").GetKnownMethod("AreTypesEquivalent", null))); - codeStream.Emit(ILOpcode.brfalse, typeMismatchExceptionLabel); + codeStream.Emit(ILOpcode.bne_un, typeMismatchExceptionLabel); codeStream.EmitLabel(typeCheckPassedLabel); } diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs index 5b49bfdb50faaa..b74dc75b46dee7 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs @@ -58,6 +58,8 @@ public override TypeDesc FieldType public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs index 78fd7bc25a4d2c..c0b52d45c99686 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs @@ -446,6 +446,8 @@ public override TypeDesc FieldType } public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs index fcfee2dbab9981..adc127cd953258 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs @@ -372,6 +372,8 @@ public override TypeDesc FieldType public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs index 7f465939fc3fc7..62b86c968c6070 100644 --- a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs +++ b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs @@ -206,11 +206,6 @@ public EntityHandle GetTypeRef(TypeDesc type) return handle; } - if (type.IsFunctionPointer) - { - throw new ArgumentException("type"); - } - EntityHandle typeHandle; if (type.IsTypeDefinition && type is MetadataType metadataType) @@ -269,11 +264,10 @@ private BlobHandle GetMethodSignatureBlobHandle(MethodSignature sig) private BlobHandle GetFieldSignatureBlobHandle(FieldDesc field) { - var embeddedSigData = field.GetEmbeddedSignatureData(); EmbeddedSignatureDataEmitter signatureDataEmitter; - if (embeddedSigData != null && embeddedSigData.Length != 0) + if (field.HasEmbeddedSignatureData) { - signatureDataEmitter = new EmbeddedSignatureDataEmitter(embeddedSigData, this); + signatureDataEmitter = new EmbeddedSignatureDataEmitter(field.GetEmbeddedSignatureData(), this); } else { diff --git a/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs b/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs index 09b1890d91ea4e..18c9736aeb3f51 100644 --- a/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs +++ b/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs @@ -611,7 +611,8 @@ bool IsAssignable(StackValue src, StackValue dst) return FALSE; // Structures are compatible if they are equivalent - return jitInfo->areTypesEquivalent(child.m_cls, parent.m_cls); + // return jitInfo->areTypesEquivalent(child.m_cls, parent.m_cls); + return child.m_cls == parent.m_cls; } else if (parent.IsByRef()) { diff --git a/src/coreclr/tools/SuperFileCheck/SuperFileCheck.csproj b/src/coreclr/tools/SuperFileCheck/SuperFileCheck.csproj index 793d6690074e43..7c76b9fa817b42 100644 --- a/src/coreclr/tools/SuperFileCheck/SuperFileCheck.csproj +++ b/src/coreclr/tools/SuperFileCheck/SuperFileCheck.csproj @@ -15,10 +15,10 @@ - - <_jitToolsRidPlatformIndex>$(OutputRid.LastIndexOf('-')) - $(OutputRid.Substring(0, $(_jitToolsRidPlatformIndex))) - $(OutputRid.Substring($(_jitToolsRidPlatformIndex)).TrimStart('-')) + + <_jitToolsRidPlatformIndex>$(OutputRID.LastIndexOf('-')) + $(OutputRID.Substring(0, $(_jitToolsRidPlatformIndex))) + $(OutputRID.Substring($(_jitToolsRidPlatformIndex)).TrimStart('-')) linux diff --git a/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs b/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs index e2bcf5a4547c42..3e6d0773061e95 100644 --- a/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs +++ b/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs @@ -67,21 +67,5 @@ private void infoButton_LinkClicked(object sender, EventArgs e) string dMessage = "Dependent nodes depend on the current node. The current node depends on the dependees."; MessageBox.Show(dMessage); } - } - public class BoxDisplay - { - public Node node; - public List reason; - - public BoxDisplay(Node node, List reason) - { - this.node = node; - this.reason = reason; - } - - public override string ToString() - { - return $"Index: {node.Index}, Name: {node.Name}, {reason.Count} Reason(s): {string.Join(", ", reason.ToArray())}"; - } - } + } } diff --git a/src/coreclr/tools/aot/DependencyGraphViewer/Program.cs b/src/coreclr/tools/aot/DependencyGraphViewer/Program.cs index 4cdf3f096f30d0..a9ebf7c5404e1c 100644 --- a/src/coreclr/tools/aot/DependencyGraphViewer/Program.cs +++ b/src/coreclr/tools/aot/DependencyGraphViewer/Program.cs @@ -17,6 +17,22 @@ namespace DependencyLogViewer { + public class BoxDisplay + { + public Node node; + public List reason; + + public BoxDisplay(Node node, List reason) + { + this.node = node; + this.reason = reason; + } + + public override string ToString() + { + return $"Index: {node.Index}, Name: {node.Name}, {reason.Count} Reason(s): {string.Join(", ", reason.ToArray())}"; + } + } public class Node { public readonly int Index; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs index 48c1c0b7cc3436..b6a0997701b732 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs @@ -626,8 +626,8 @@ public IEnumerable CompiledMethodBodies { foreach (var node in MarkedNodes) { - if (node is IMethodBodyNode) - yield return ((IMethodBodyNode)node).Method; + if (node is IMethodBodyNode methodBodyNode) + yield return methodBodyNode.Method; } } } @@ -639,9 +639,7 @@ public IEnumerable ConstructedEETypes foreach (var node in MarkedNodes) { if (node is ConstructedEETypeNode || node is CanonicalEETypeNode) - { yield return ((IEETypeNode)node).Type; - } } } } @@ -652,10 +650,20 @@ public IEnumerable AllEETypes { foreach (var node in MarkedNodes) { - if (node is IEETypeNode) - { - yield return ((IEETypeNode)node).Type; - } + if (node is IEETypeNode typeNode) + yield return typeNode.Type; + } + } + } + + public IEnumerable ReflectedMethods + { + get + { + foreach (var node in MarkedNodes) + { + if (node is ReflectedMethodNode reflectedMethod) + yield return reflectedMethod.Method; } } } 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 b9312b0e10969f..e489edce4ad806 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs @@ -1025,6 +1025,10 @@ internal SingleValue GetTypeValueFromGenericArgument(TypeDesc genericArgument) // All values except for Nullable, including Nullable<> (with no type arguments) return new SystemTypeValue(genericArgumentType); } + else if (genericArgument is ArrayType arrayType) + { + return new SystemTypeValue(arrayType); + } else { return UnknownValue.Instance; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs index d6d4526e5c771a..deb9474117f478 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs @@ -476,7 +476,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp { if (methodBody.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) { - HandleMethodReflectionAccess(methodBody, offset, methodOperand); + HandleMethodTokenAccess(methodBody, offset, methodOperand); TrackNestedFunctionReference(methodOperand, ref interproceduralState); } @@ -537,7 +537,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp { if (methodBody.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) { - HandleMethodReflectionAccess(methodBody, offset, methodOperand); + HandleMethodTokenAccess(methodBody, offset, methodOperand); } PopUnknown(currentStack, 1, methodBody, offset); @@ -963,14 +963,14 @@ private void ScanLdtoken(MethodIL methodBody, int offset, object operand, Stack< } } - HandleTypeReflectionAccess(methodBody, offset, type); + HandleTypeTokenAccess(methodBody, offset, type); } else if (operand is MethodDesc method) { StackSlot slot = new StackSlot(new RuntimeMethodHandleValue(method)); currentStack.Push(slot); - HandleMethodReflectionAccess(methodBody, offset, method); + HandleMethodTokenAccess(methodBody, offset, method); } else { @@ -978,7 +978,7 @@ private void ScanLdtoken(MethodIL methodBody, int offset, object operand, Stack< PushUnknown(currentStack); - HandleFieldReflectionAccess(methodBody, offset, (FieldDesc)operand); + HandleFieldTokenAccess(methodBody, offset, (FieldDesc)operand); } } @@ -1248,19 +1248,19 @@ protected void AssignRefAndOutParameters( } /// - /// Called when type is accessed directly (basically only ldtoken) + /// Called when type is accessed directly by its token (so creating a RuntimeHandle) /// - protected abstract void HandleTypeReflectionAccess(MethodIL methodBody, int offset, TypeDesc accessedType); + protected abstract void HandleTypeTokenAccess(MethodIL methodBody, int offset, TypeDesc accessedType); /// - /// Called to handle reflection access to a method without any other specifics (ldtoken or ldftn for example) + /// Called to handle access to a method by its token (so creating a RuntimeHandle) /// - protected abstract void HandleMethodReflectionAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod); + protected abstract void HandleMethodTokenAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod); /// - /// Called to handle reflection access to a field without any other specifics (ldtoken for example) + /// Called to handle access to a field by its token (so creating a RuntimeHandle) /// - protected abstract void HandleFieldReflectionAccess(MethodIL methodBody, int offset, FieldDesc accessedField); + protected abstract void HandleFieldTokenAccess(MethodIL methodBody, int offset, FieldDesc accessedField); private void HandleCall( MethodIL callingMethodBody, diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs index 4ecabf6aad6d64..d32757d162d80b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs @@ -31,6 +31,13 @@ public class ReflectionMarker public FlowAnnotations Annotations { get; } public DependencyList Dependencies { get => _dependencies; } + internal enum AccessKind + { + Unspecified, + DynamicallyAccessedMembersMark, + TokenAccess + } + public ReflectionMarker(Logger logger, NodeFactory factory, FlowAnnotations annotations, MetadataType? typeHierarchyDataFlowOrigin, bool enabled) { _logger = logger; @@ -47,28 +54,28 @@ internal void MarkTypeForDynamicallyAccessedMembers(in MessageOrigin origin, Typ foreach (var member in typeDefinition.GetDynamicallyAccessedMembers(requiredMemberTypes, declaredOnly)) { - MarkTypeSystemEntity(origin, member, reason); + MarkTypeSystemEntity(origin, member, reason, AccessKind.DynamicallyAccessedMembersMark); } } - internal void MarkTypeSystemEntity(in MessageOrigin origin, TypeSystemEntity entity, string reason) + internal void MarkTypeSystemEntity(in MessageOrigin origin, TypeSystemEntity entity, string reason, AccessKind accessKind = AccessKind.Unspecified) { switch (entity) { case MethodDesc method: - MarkMethod(origin, method, reason); + MarkMethod(origin, method, reason, accessKind); break; case FieldDesc field: - MarkField(origin, field, reason); + MarkField(origin, field, reason, accessKind); break; case MetadataType nestedType: - MarkType(origin, nestedType, reason); + MarkType(origin, nestedType, reason, accessKind); break; case PropertyPseudoDesc property: - MarkProperty(origin, property, reason); + MarkProperty(origin, property, reason, accessKind); break; case EventPseudoDesc @event: - MarkEvent(origin, @event, reason); + MarkEvent(origin, @event, reason, accessKind); break; // case InterfaceImplementation // Nothing to do currently as Native AOT will preserve all interfaces on a preserved type @@ -107,7 +114,7 @@ internal bool TryResolveTypeNameAndMark(string typeName, in DiagnosticContext di return true; } - internal void MarkType(in MessageOrigin origin, TypeDesc type, string reason) + internal void MarkType(in MessageOrigin origin, TypeDesc type, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; @@ -115,27 +122,27 @@ internal void MarkType(in MessageOrigin origin, TypeDesc type, string reason) RootingHelpers.TryGetDependenciesForReflectedType(ref _dependencies, Factory, type, reason); } - internal void MarkMethod(in MessageOrigin origin, MethodDesc method, string reason) + internal void MarkMethod(in MessageOrigin origin, MethodDesc method, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; - CheckAndWarnOnReflectionAccess(origin, method); + CheckAndWarnOnReflectionAccess(origin, method, accessKind); RootingHelpers.TryGetDependenciesForReflectedMethod(ref _dependencies, Factory, method, reason); } - internal void MarkField(in MessageOrigin origin, FieldDesc field, string reason) + internal void MarkField(in MessageOrigin origin, FieldDesc field, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; - CheckAndWarnOnReflectionAccess(origin, field); + CheckAndWarnOnReflectionAccess(origin, field, accessKind); RootingHelpers.TryGetDependenciesForReflectedField(ref _dependencies, Factory, field, reason); } - internal void MarkProperty(in MessageOrigin origin, PropertyPseudoDesc property, string reason) + internal void MarkProperty(in MessageOrigin origin, PropertyPseudoDesc property, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; @@ -146,7 +153,7 @@ internal void MarkProperty(in MessageOrigin origin, PropertyPseudoDesc property, MarkMethod(origin, property.SetMethod, reason); } - private void MarkEvent(in MessageOrigin origin, EventPseudoDesc @event, string reason) + private void MarkEvent(in MessageOrigin origin, EventPseudoDesc @event, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; @@ -209,86 +216,137 @@ internal void MarkStaticConstructor(in MessageOrigin origin, TypeDesc type, stri } } - internal void CheckAndWarnOnReflectionAccess(in MessageOrigin origin, TypeSystemEntity entity) + internal void CheckAndWarnOnReflectionAccess(in MessageOrigin origin, TypeSystemEntity entity, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; + if (_typeHierarchyDataFlowOrigin is not null) + { + ReportWarningsForTypeHierarchyReflectionAccess(origin, entity); + } + else + { + ReportWarningsForReflectionAccess(origin, entity, accessKind); + } + } + + private void ReportWarningsForReflectionAccess(in MessageOrigin origin, TypeSystemEntity entity, AccessKind accessKind) + { + Debug.Assert(entity is MethodDesc or FieldDesc); + // Note that we're using `ShouldSuppressAnalysisWarningsForRequires` instead of `DoesMemberRequire`. // This is because reflection access is actually problematic on all members which are in a "requires" scope // so for example even instance methods. See for example https://github.com/dotnet/linker/issues/3140 - it's possible // to call a method on a "null" instance via reflection. if (_logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out CustomAttributeValue? requiresAttribute)) { - if (_typeHierarchyDataFlowOrigin is not null) - { - _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithRequiresUnreferencedCode, - _typeHierarchyDataFlowOrigin.GetDisplayName(), - entity.GetDisplayName(), - MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(requiresAttribute.Value)), - MessageFormat.FormatRequiresAttributeUrlArg(DiagnosticUtilities.GetRequiresAttributeUrl(requiresAttribute.Value))); - } - else - { + if (!ShouldSkipWarningsForOverride(entity, accessKind)) ReportRequires(origin, entity, DiagnosticUtilities.RequiresUnreferencedCodeAttribute, requiresAttribute.Value); - } } if (_logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresAssemblyFilesAttribute, out requiresAttribute)) { - if (_typeHierarchyDataFlowOrigin is not null) - { - // For now we decided to not report single-file warnings due to type hierarchy marking. - // It is considered too complex to figure out for the user and the likelihood of this - // causing problems is pretty low. - } - else - { + if (!ShouldSkipWarningsForOverride(entity, accessKind)) ReportRequires(origin, entity, DiagnosticUtilities.RequiresAssemblyFilesAttribute, requiresAttribute.Value); - } } if (_logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresDynamicCodeAttribute, out requiresAttribute)) { - if (_typeHierarchyDataFlowOrigin is not null) - { - // For now we decided to not report dynamic code warnings due to type hierarchy marking. - // It is considered too complex to figure out for the user and the likelihood of this - // causing problems is pretty low. - } - else - { + if (!ShouldSkipWarningsForOverride(entity, accessKind)) ReportRequires(origin, entity, DiagnosticUtilities.RequiresDynamicCodeAttribute, requiresAttribute.Value); - } } - if (!Annotations.ShouldWarnWhenAccessedForReflection(entity)) + // Below is about accessing DAM annotated members, so only RUC is applicable as a suppression scope + if (_logger.ShouldSuppressAnalysisWarningsForRequires(origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute)) return; - if (_typeHierarchyDataFlowOrigin is not null) + bool isReflectionAccessCoveredByDAM = Annotations.ShouldWarnWhenAccessedForReflection(entity); + if (isReflectionAccessCoveredByDAM && !ShouldSkipWarningsForOverride(entity, accessKind)) { - // Don't check whether the current scope is a RUC type or RUC method because these warnings - // 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(origin, DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithDynamicallyAccessedMembers, - _typeHierarchyDataFlowOrigin.GetDisplayName(), entity.GetDisplayName()); + if (entity is MethodDesc) + _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, entity.GetDisplayName()); + else + _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, entity.GetDisplayName()); } - else + + // We decided to not warn on reflection access to compiler-generated methods: + // https://github.com/dotnet/runtime/issues/85042 + + // All override methods should have the same annotations as their base methods + // (else we will produce warning IL2046 or IL2092 or some other warning). + // When marking override methods via DynamicallyAccessedMembers, we should only issue a warning for the base method. + // PERF: Avoid precomputing this as this method is relatively expensive. Only call it once we're about to produce a warning. + static bool ShouldSkipWarningsForOverride(TypeSystemEntity entity, AccessKind accessKind) + { + if (accessKind != AccessKind.DynamicallyAccessedMembersMark || entity is not MethodDesc method || !method.IsVirtual) + return false; + + return MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method) != method; + } + } + + private void ReportWarningsForTypeHierarchyReflectionAccess(MessageOrigin origin, TypeSystemEntity entity) + { + Debug.Assert(entity is MethodDesc or FieldDesc); + + // Don't check whether the current scope is a RUC type or RUC method because these warnings + // 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. + + Debug.Assert(_typeHierarchyDataFlowOrigin != null); + + static bool IsDeclaredWithinType(TypeSystemEntity member, TypeDesc type) { - if (!_logger.ShouldSuppressAnalysisWarningsForRequires(origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute)) + TypeDesc owningType = member.GetOwningType(); + while (owningType != null) { - if (entity is FieldDesc) - { - _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, entity.GetDisplayName()); - } - else - { - Debug.Assert(entity is MethodDesc); - - _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, entity.GetDisplayName()); - } + if (owningType == type) + return true; + + owningType = owningType.GetOwningType(); } + return false; + } + + var reportOnMember = IsDeclaredWithinType(entity, _typeHierarchyDataFlowOrigin); + if (reportOnMember) + origin = new MessageOrigin(entity); + + // For now we decided to not report single-file or dynamic-code warnings due to type hierarchy marking. + // It is considered too complex to figure out for the user and the likelihood of this + // causing problems is pretty low. + + bool isReflectionAccessCoveredByRUC = _logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out CustomAttributeValue? requiresUnreferencedCodeAttribute); + if (isReflectionAccessCoveredByRUC && !ShouldSkipWarningsForOverride(entity)) + { + var id = reportOnMember ? DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberWithRequiresUnreferencedCode : DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithRequiresUnreferencedCode; + _logger.LogWarning(origin, id, _typeHierarchyDataFlowOrigin.GetDisplayName(), + entity.GetDisplayName(), + MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(requiresUnreferencedCodeAttribute!.Value)), + MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeUrl(requiresUnreferencedCodeAttribute!.Value))); + } + + bool isReflectionAccessCoveredByDAM = Annotations.ShouldWarnWhenAccessedForReflection(entity); + if (isReflectionAccessCoveredByDAM && !ShouldSkipWarningsForOverride(entity)) + { + var id = reportOnMember ? DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberWithDynamicallyAccessedMembers : DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithDynamicallyAccessedMembers; + _logger.LogWarning(origin, id, _typeHierarchyDataFlowOrigin.GetDisplayName(), entity.GetDisplayName()); + } + + // We decided to not warn on reflection access to compiler-generated methods: + // https://github.com/dotnet/runtime/issues/85042 + + // All override methods should have the same annotations as their base methods + // (else we will produce warning IL2046 or IL2092 or some other warning). + // When marking override methods via DynamicallyAccessedMembers, we should only issue a warning for the base method. + static bool ShouldSkipWarningsForOverride(TypeSystemEntity entity) + { + if (entity is not MethodDesc method || !method.IsVirtual) + return false; + + return MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method) != method; } } 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 b0979861ef166a..79c0cf011bf9ba 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -135,7 +135,42 @@ public static DependencyList ProcessTypeGetTypeDataflow(NodeFactory factory, Flo DynamicallyAccessedMemberTypes annotation = flowAnnotations.GetTypeAnnotation(type); Debug.Assert(annotation != DynamicallyAccessedMemberTypes.None); var reflectionMarker = new ReflectionMarker(logger, factory, flowAnnotations, typeHierarchyDataFlowOrigin: type, enabled: true); - reflectionMarker.MarkTypeForDynamicallyAccessedMembers(new MessageOrigin(type), type, annotation, type.GetDisplayName()); + + // We need to apply annotations to this type, and its base/interface types (recursively) + // But the annotations on base/interfaces may already be applied so we don't need to apply those + // again (and should avoid doing so as it would produce extra warnings). + MessageOrigin origin = new MessageOrigin(type); + if (type.HasBaseType) + { + var baseAnnotation = flowAnnotations.GetTypeAnnotation(type.BaseType); + var annotationToApplyToBase = Annotations.GetMissingMemberTypes(annotation, baseAnnotation); + + // Apply any annotations that didn't exist on the base type to the base type. + // This may produce redundant warnings when the annotation is DAMT.All or DAMT.PublicConstructors and the base already has a + // subset of those annotations. + reflectionMarker.MarkTypeForDynamicallyAccessedMembers(origin, type.BaseType, annotationToApplyToBase, type.GetDisplayName(), declaredOnly: false); + } + + // Most of the DynamicallyAccessedMemberTypes don't select members on interfaces. We only need to apply + // annotations to interfaces separately if dealing with DAMT.All or DAMT.Interfaces. + if (annotation.HasFlag(DynamicallyAccessedMemberTypes.Interfaces)) + { + var annotationToApplyToInterfaces = annotation == DynamicallyAccessedMemberTypes.All ? annotation : DynamicallyAccessedMemberTypes.Interfaces; + foreach (var iface in type.RuntimeInterfaces) + { + if (flowAnnotations.GetTypeAnnotation(iface).HasFlag(annotationToApplyToInterfaces)) + continue; + + // Apply All or Interfaces to the interface type. + // DAMT.All may produce redundant warnings from implementing types, when the interface type already had some annotations. + reflectionMarker.MarkTypeForDynamicallyAccessedMembers(origin, iface, annotationToApplyToInterfaces, type.GetDisplayName(), declaredOnly: false); + } + } + + // The annotations this type inherited from its base types or interfaces should not produce + // warnings on the respective base/interface members, since those are already covered by applying + // the annotations to those types. So we only need to handle the members directly declared on this type. + reflectionMarker.MarkTypeForDynamicallyAccessedMembers(new MessageOrigin(type), type, annotation, type.GetDisplayName(), declaredOnly: true); return reflectionMarker.Dependencies; } @@ -193,7 +228,7 @@ protected override void HandleStoreParameter(MethodIL methodBody, int offset, Me protected override void HandleStoreMethodReturnValue(MethodIL methodBody, int offset, MethodReturnValue returnValue, MultiValue valueToStore) => HandleStoreValueWithDynamicallyAccessedMembers(methodBody, offset, returnValue, valueToStore, returnValue.Method.GetDisplayName()); - protected override void HandleTypeReflectionAccess(MethodIL methodBody, int offset, TypeDesc accessedType) + protected override void HandleTypeTokenAccess(MethodIL methodBody, int offset, TypeDesc accessedType) { // Note that ldtoken alone is technically a reflection access to the type // it doesn't lead to full reflection marking of the type @@ -204,20 +239,20 @@ protected override void HandleTypeReflectionAccess(MethodIL methodBody, int offs ProcessGenericArgumentDataFlow(accessedType); } - protected override void HandleMethodReflectionAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod) + protected override void HandleMethodTokenAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod) { _origin = _origin.WithInstructionOffset(methodBody, offset); - TrimAnalysisPatterns.Add(new TrimAnalysisReflectionAccessPattern(accessedMethod, _origin)); + TrimAnalysisPatterns.Add(new TrimAnalysisTokenAccessPattern(accessedMethod, _origin)); ProcessGenericArgumentDataFlow(accessedMethod); } - protected override void HandleFieldReflectionAccess(MethodIL methodBody, int offset, FieldDesc accessedField) + protected override void HandleFieldTokenAccess(MethodIL methodBody, int offset, FieldDesc accessedField) { _origin = _origin.WithInstructionOffset(methodBody, offset); - TrimAnalysisPatterns.Add(new TrimAnalysisReflectionAccessPattern(accessedField, _origin)); + TrimAnalysisPatterns.Add(new TrimAnalysisTokenAccessPattern(accessedField, _origin)); ProcessGenericArgumentDataFlow(accessedField); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs index 64c539b0346d30..258f2bcfef26cc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs @@ -15,7 +15,7 @@ public readonly struct TrimAnalysisPatternStore { private readonly Dictionary<(MessageOrigin, bool), TrimAnalysisAssignmentPattern> AssignmentPatterns; private readonly Dictionary MethodCallPatterns; - private readonly Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisReflectionAccessPattern> ReflectionAccessPatterns; + private readonly Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisTokenAccessPattern> TokenAccessPatterns; private readonly Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisGenericInstantiationAccessPattern> GenericInstantiations; private readonly Dictionary<(MessageOrigin, FieldDesc), TrimAnalysisFieldAccessPattern> FieldAccessPatterns; private readonly ValueSetLattice Lattice; @@ -25,7 +25,7 @@ public TrimAnalysisPatternStore(ValueSetLattice lattice, Logger log { AssignmentPatterns = new Dictionary<(MessageOrigin, bool), TrimAnalysisAssignmentPattern>(); MethodCallPatterns = new Dictionary(); - ReflectionAccessPatterns = new Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisReflectionAccessPattern>(); + TokenAccessPatterns = new Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisTokenAccessPattern>(); GenericInstantiations = new Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisGenericInstantiationAccessPattern>(); FieldAccessPatterns = new Dictionary<(MessageOrigin, FieldDesc), TrimAnalysisFieldAccessPattern>(); Lattice = lattice; @@ -60,9 +60,9 @@ public void Add(TrimAnalysisMethodCallPattern pattern) MethodCallPatterns[pattern.Origin] = pattern.Merge(Lattice, existingPattern); } - public void Add(TrimAnalysisReflectionAccessPattern pattern) + public void Add(TrimAnalysisTokenAccessPattern pattern) { - ReflectionAccessPatterns.TryAdd((pattern.Origin, pattern.Entity), pattern); + TokenAccessPatterns.TryAdd((pattern.Origin, pattern.Entity), pattern); // No Merge - there's nothing to merge since this pattern is uniquely identified by both the origin and the entity // and there's only one way to "access" a generic instantiation. @@ -92,7 +92,7 @@ public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker) foreach (var pattern in MethodCallPatterns.Values) pattern.MarkAndProduceDiagnostics(reflectionMarker, _logger); - foreach (var pattern in ReflectionAccessPatterns.Values) + foreach (var pattern in TokenAccessPatterns.Values) pattern.MarkAndProduceDiagnostics(reflectionMarker, _logger); foreach (var pattern in GenericInstantiations.Values) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisReflectionAccessPattern.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisTokenAccessPattern.cs similarity index 76% rename from src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisReflectionAccessPattern.cs rename to src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisTokenAccessPattern.cs index 8f40b94c02d811..6d7308235cfbf1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisReflectionAccessPattern.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisTokenAccessPattern.cs @@ -9,30 +9,30 @@ namespace ILCompiler.Dataflow { - public readonly record struct TrimAnalysisReflectionAccessPattern + public readonly record struct TrimAnalysisTokenAccessPattern { public TypeSystemEntity Entity { init; get; } public MessageOrigin Origin { init; get; } - internal TrimAnalysisReflectionAccessPattern(TypeSystemEntity entity, MessageOrigin origin) + internal TrimAnalysisTokenAccessPattern(TypeSystemEntity entity, MessageOrigin origin) { Entity = entity; Origin = origin; } // No Merge - there's nothing to merge since this pattern is uniquely identified by both the origin and the entity - // and there's only one way to "reflection access" an entity. + // and there's only one way to access entity by its handle. public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker, Logger logger) { switch (Entity) { case MethodDesc method: - reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, method); + reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, method, ReflectionMarker.AccessKind.TokenAccess); break; case FieldDesc field: - reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, field); + reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, field, ReflectionMarker.AccessKind.TokenAccess); break; default: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayMapNode.cs index 2fff19939fc62f..6bf674b28296a4 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayMapNode.cs @@ -52,21 +52,11 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes()) { - if (!type.IsSzArray) + if (!type.IsArray) continue; var arrayType = (ArrayType)type; - // This optimization is not compatible with canInlineTypeCheck on JIT/EE interface returning - // CORINFO_INLINE_TYPECHECK_PASS unconditionally. - // - // If we're generating a template for this type, we can skip generating the hashtable entry - // since the type loader can just create this type at runtime if something needs it. It's - // okay to have multiple EETypes for the same array type. - // var canonArrayType = arrayType.ConvertToCanonForm(CanonicalFormKind.Specific); - // if (arrayType != canonArrayType && factory.NativeLayout.TemplateTypeLayout(canonArrayType).Marked) - // continue; - // Look at the constructed type symbol. If a constructed type wasn't emitted, then the array map entry isn't valid for use IEETypeNode arrayTypeSymbol = factory.ConstructedTypeSymbol(arrayType); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ByRefTypeMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ByRefTypeMapNode.cs new file mode 100644 index 00000000000000..8adf1643302b73 --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ByRefTypeMapNode.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +using Internal.NativeFormat; +using Internal.Text; + +namespace ILCompiler.DependencyAnalysis +{ + /// + /// Represents a hash table of ByRef types generated into the image. + /// + internal sealed class ByRefTypeMapNode : ObjectNode, ISymbolDefinitionNode + { + private readonly ObjectAndOffsetSymbolNode _endSymbol; + private readonly ExternalReferencesTableNode _externalReferences; + + public ByRefTypeMapNode(ExternalReferencesTableNode externalReferences) + { + _endSymbol = new ObjectAndOffsetSymbolNode(this, 0, "__byref_type_map_End", true); + _externalReferences = externalReferences; + } + + public ISymbolDefinitionNode EndSymbol => _endSymbol; + + public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append(nameMangler.CompilationUnitPrefix).Append("__byref_type_map"); + } + public int Offset => 0; + public override bool IsShareable => false; + + public override ObjectNodeSection GetSection(NodeFactory factory) => _externalReferences.GetSection(factory); + + public override bool StaticDependenciesAreComputed => true; + + protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler); + + public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) + { + // This node does not trigger generation of other nodes. + if (relocsOnly) + return new ObjectData(Array.Empty(), Array.Empty(), 1, new ISymbolDefinitionNode[] { this }); + + var writer = new NativeWriter(); + var typeMapHashTable = new VertexHashtable(); + + Section hashTableSection = writer.NewSection(); + hashTableSection.Place(typeMapHashTable); + + foreach (var type in factory.MetadataManager.GetTypesWithEETypes()) + { + if (!type.IsByRef) + continue; + + Vertex vertex = writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))); + + int hashCode = type.GetHashCode(); + typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex)); + } + + byte[] hashTableBytes = writer.Save(); + + _endSymbol.SetSymbolOffset(hashTableBytes.Length); + + return new ObjectData(hashTableBytes, Array.Empty(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }); + } + + protected internal override int Phase => (int)ObjectNodePhase.Ordered; + public override int ClassCode => (int)ObjectNodeOrder.ByRefMapNode; + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs index 500192714f719e..7a6467a96e9e85 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs @@ -42,9 +42,6 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact DefType closestDefType = _type.GetClosestDefType(); - if (MightHaveInterfaceDispatchMap(factory)) - dependencyList.Add(factory.InterfaceDispatchMap(_type), "Canonical interface dispatch map"); - dependencyList.Add(factory.VTable(closestDefType), "VTable"); if (_type.IsCanonicalSubtype(CanonicalFormKind.Universal)) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 1e9e3144d2be0d..716c2047b237f9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -36,12 +36,6 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact DefType closestDefType = _type.GetClosestDefType(); - if (MightHaveInterfaceDispatchMap(factory)) - { - TypeDesc canonType = _type.ConvertToCanonForm(CanonicalFormKind.Specific); - dependencyList.Add(factory.InterfaceDispatchMap(canonType), "Interface dispatch map"); - } - if (_type.IsArray) { // Array MethodTable depends on System.Array's virtuals. Array EETypes don't point to diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicDependencyAttributesOnEntityNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicDependencyAttributesOnEntityNode.cs index 95fcd878315f7f..7c07dfd53eb60d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicDependencyAttributesOnEntityNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicDependencyAttributesOnEntityNode.cs @@ -55,21 +55,22 @@ public static void AddDependenciesDueToDynamicDependencyAttribute(ref Dependency public override IEnumerable GetStaticDependencies(NodeFactory factory) { DependencyList dependencies = null; - switch (_entity) + try { - case EcmaMethod method: - foreach (var attribute in method.GetDecodedCustomAttributes("System.Diagnostics.CodeAnalysis", "DynamicDependencyAttribute")) - { - AddDependenciesDueToDynamicDependencyAttribute(ref dependencies, factory, method, method.OwningType, attribute); - } - break; + (TypeDesc owningType, IEnumerable> attributes) = _entity switch + { + EcmaMethod method => (method.OwningType, method.GetDecodedCustomAttributes("System.Diagnostics.CodeAnalysis", "DynamicDependencyAttribute")), + _ => (((EcmaField)_entity).OwningType, ((EcmaField)_entity).GetDecodedCustomAttributes("System.Diagnostics.CodeAnalysis", "DynamicDependencyAttribute")), + }; - case EcmaField field: - foreach (var attribute in field.GetDecodedCustomAttributes("System.Diagnostics.CodeAnalysis", "DynamicDependencyAttribute")) - { - AddDependenciesDueToDynamicDependencyAttribute(ref dependencies, factory, field, field.OwningType, attribute); - } - break; + foreach (CustomAttributeValue attribute in attributes) + { + AddDependenciesDueToDynamicDependencyAttribute(ref dependencies, factory, _entity, owningType, attribute); + } + } + catch (TypeSystemException) + { + // Ignore entities with custom attributes that don't work. } return dependencies; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index 2ddcb140183c07..6498c340e5cc53 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -648,7 +648,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo ComputeOptionalEETypeFields(factory, relocsOnly); OutputGCDesc(ref objData); - OutputFlags(factory, ref objData); + OutputFlags(factory, ref objData, relocsOnly); objData.EmitInt(BaseSize); OutputRelatedType(factory, ref objData); @@ -689,10 +689,12 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo OutputTypeManagerIndirection(factory, ref objData); OutputWritableData(factory, ref objData); + OutputDispatchMap(factory, ref objData); OutputFinalizerMethod(factory, ref objData); OutputOptionalFields(factory, ref objData); OutputSealedVTable(factory, relocsOnly, ref objData); OutputGenericInstantiationDetails(factory, ref objData); + OutputFunctionPointerParameters(factory, ref objData); return objData.ToObjectData(); } @@ -714,7 +716,7 @@ protected virtual void OutputGCDesc(ref ObjectDataBuilder builder) Debug.Assert(GCDescSize == 0); } - private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData) + private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData, bool relocsOnly) { uint flags = EETypeBuilderHelpers.ComputeFlags(_type); @@ -732,19 +734,16 @@ private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData) flags |= (uint)EETypeFlags.GenericVarianceFlag; } - if (_type.IsIDynamicInterfaceCastable) + if (EmitVirtualSlotsAndInterfaces && !_type.IsArrayTypeWithoutGenericInterfaces()) { - flags |= (uint)EETypeFlags.IDynamicInterfaceCastableFlag; + SealedVTableNode sealedVTable = factory.SealedVTable(_type.ConvertToCanonForm(CanonicalFormKind.Specific)); + if (sealedVTable.BuildSealedVTableSlots(factory, relocsOnly) && sealedVTable.NumSealedVTableEntries > 0) + flags |= (uint)EETypeFlags.HasSealedVTableEntriesFlag; } - ISymbolNode relatedTypeNode = GetRelatedTypeNode(factory); - - // If the related type (base type / array element type / pointee type) is not part of this compilation group, and - // the output binaries will be multi-file (not multiple object files linked together), indicate to the runtime - // that it should indirect through the import address table - if (relatedTypeNode != null && relatedTypeNode.RepresentsIndirectionCell) + if (MightHaveInterfaceDispatchMap(factory)) { - flags |= (uint)EETypeFlags.RelatedTypeViaIATFlag; + flags |= (uint)EETypeFlags.HasDispatchMap; } if (HasOptionalFields) @@ -834,8 +833,13 @@ protected virtual int BaseSize } else if (_type.IsFunctionPointer) { - // These never get boxed and don't have a base size. - return 0; + // These never get boxed and don't have a base size. We store the 'unmanaged' flag and number of parameters. + MethodSignature sig = ((FunctionPointerType)_type).Signature; + return (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) switch + { + 0 => sig.Length, + _ => sig.Length | unchecked((int)FunctionPointerFlags.IsUnmanaged), + }; } else throw new NotImplementedException(); @@ -885,6 +889,10 @@ private ISymbolNode GetRelatedTypeNode(NodeFactory factory) relatedTypeNode = factory.NecessaryTypeSymbol(parameterType); } } + else if (_type.IsFunctionPointer) + { + relatedTypeNode = factory.NecessaryTypeSymbol(((FunctionPointerType)_type).Signature.ReturnType); + } else { TypeDesc baseType = _type.BaseType; @@ -1064,7 +1072,7 @@ protected virtual void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBui foreach (var itf in _type.RuntimeInterfaces) { - objData.EmitPointerRelocOrIndirectionReference(GetInterfaceTypeNode(factory, itf)); + objData.EmitPointerReloc(GetInterfaceTypeNode(factory, itf)); } } @@ -1136,29 +1144,77 @@ protected void OutputGenericInstantiationDetails(NodeFactory factory, ref Object objData.EmitRelativeRelocOrIndirectionReference(typeDefNode); else objData.EmitPointerRelocOrIndirectionReference(typeDefNode); - } - GenericCompositionDetails details; - if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType) + ISymbolNode compositionNode = _type.Instantiation.Length > 1 + ? factory.GenericComposition(_type.Instantiation) + : factory.NecessaryTypeSymbol(_type.Instantiation[0]); + + if (factory.Target.SupportsRelativePointers) + objData.EmitReloc(compositionNode, RelocType.IMAGE_REL_BASED_RELPTR32); + else + objData.EmitPointerReloc(compositionNode); + } + else { - // Generic array enumerators use special variance rules recognized by the runtime - details = new GenericCompositionDetails(_type.Instantiation, new[] { GenericVariance.ArrayCovariant }); + GenericVarianceDetails details; + if (_type == factory.ArrayOfTEnumeratorType) + { + // Generic array enumerators use special variance rules recognized by the runtime + details = new GenericVarianceDetails(new[] { GenericVariance.ArrayCovariant }); + } + else if (factory.TypeSystemContext.IsGenericArrayInterfaceType(_type)) + { + // Runtime casting logic relies on all interface types implemented on arrays + // to have the variant flag set (even if all the arguments are non-variant). + // This supports e.g. casting uint[] to ICollection + details = new GenericVarianceDetails(_type); + } + else if (_type.HasVariance) + { + details = new GenericVarianceDetails(_type); + } + else + { + details = default; + } + + if (!details.IsNull) + { + ISymbolNode varianceInfoNode = factory.GenericVariance(details); + if (factory.Target.SupportsRelativePointers) + objData.EmitReloc(varianceInfoNode, RelocType.IMAGE_REL_BASED_RELPTR32); + else + objData.EmitPointerReloc(varianceInfoNode); + } } - else if (factory.TypeSystemContext.IsGenericArrayInterfaceType(_type)) + } + } + + private void OutputFunctionPointerParameters(NodeFactory factory, ref ObjectDataBuilder objData) + { + if (_type.IsFunctionPointer) + { + MethodSignature sig = ((FunctionPointerType)_type).Signature; + foreach (TypeDesc paramType in sig) { - // Runtime casting logic relies on all interface types implemented on arrays - // to have the variant flag set (even if all the arguments are non-variant). - // This supports e.g. casting uint[] to ICollection - details = new GenericCompositionDetails(_type, forceVarianceInfo: true); + ISymbolNode paramTypeNode = factory.NecessaryTypeSymbol(paramType); + if (factory.Target.SupportsRelativePointers) + objData.EmitReloc(paramTypeNode, RelocType.IMAGE_REL_BASED_RELPTR32); + else + objData.EmitPointerReloc(paramTypeNode); } - else - details = new GenericCompositionDetails(_type); + } + } - ISymbolNode compositionNode = factory.GenericComposition(details); + private void OutputDispatchMap(NodeFactory factory, ref ObjectDataBuilder objData) + { + if (MightHaveInterfaceDispatchMap(factory)) + { + ISymbolNode dispatchMap = factory.InterfaceDispatchMap(_type.ConvertToCanonForm(CanonicalFormKind.Specific)); if (factory.Target.SupportsRelativePointers) - objData.EmitReloc(compositionNode, RelocType.IMAGE_REL_BASED_RELPTR32); + objData.EmitReloc(dispatchMap, RelocType.IMAGE_REL_BASED_RELPTR32); else - objData.EmitPointerReloc(compositionNode); + objData.EmitPointerReloc(dispatchMap); } } @@ -1167,18 +1223,12 @@ protected void OutputGenericInstantiationDetails(NodeFactory factory, ref Object /// protected internal virtual void ComputeOptionalEETypeFields(NodeFactory factory, bool relocsOnly) { - if (!relocsOnly && MightHaveInterfaceDispatchMap(factory)) - { - TypeDesc canonType = _type.ConvertToCanonForm(CanonicalFormKind.Specific); - _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.DispatchMap, checked((uint)factory.InterfaceDispatchMapIndirection(canonType).IndexFromBeginningOfArray)); - } - - ComputeRareFlags(factory, relocsOnly); + ComputeRareFlags(factory); ComputeNullableValueOffset(); ComputeValueTypeFieldPadding(); } - private void ComputeRareFlags(NodeFactory factory, bool relocsOnly) + private void ComputeRareFlags(NodeFactory factory) { uint flags = 0; @@ -1203,23 +1253,11 @@ private void ComputeRareFlags(NodeFactory factory, bool relocsOnly) flags |= (uint)EETypeRareFlags.IsHFAFlag; } - if (metadataType != null && !_type.IsInterface && metadataType.IsAbstract) - { - flags |= (uint)EETypeRareFlags.IsAbstractClassFlag; - } - if (_type.IsByRefLike) { flags |= (uint)EETypeRareFlags.IsByRefLikeFlag; } - if (EmitVirtualSlotsAndInterfaces && !_type.IsArrayTypeWithoutGenericInterfaces()) - { - SealedVTableNode sealedVTable = factory.SealedVTable(_type.ConvertToCanonForm(CanonicalFormKind.Specific)); - if (sealedVTable.BuildSealedVTableSlots(factory, relocsOnly) && sealedVTable.NumSealedVTableEntries > 0) - flags |= (uint)EETypeRareFlags.HasSealedVTableEntriesFlag; - } - if (flags != 0) { _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, flags); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs index 325a7bb7946276..5c49cfddb1c2cf 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs @@ -51,6 +51,13 @@ public override IEnumerable GetStaticDependencies(NodeFacto GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(ref dependencies, factory, new MessageOrigin(_field), ecmaField.FieldType, ecmaField.OwningType); } + if (_field.HasEmbeddedSignatureData) + { + foreach (var sigData in _field.GetEmbeddedSignatureData()) + if (sigData.type != null) + TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, sigData.type, "Modifier in a field signature"); + } + return dependencies; } protected override string GetName(NodeFactory factory) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs index 764bffd9603c1b..0af151dddc520f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs @@ -83,6 +83,8 @@ public override IEnumerable GetStaticDependencies(NodeFacto } } + _data.GetNonRelocationDependencies(ref dependencies, factory); + return dependencies; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FunctionPointerMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FunctionPointerMapNode.cs index 05e2e911482ad9..f2651f9069f1bf 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FunctionPointerMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FunctionPointerMapNode.cs @@ -4,12 +4,9 @@ using System; using Internal.NativeFormat; -using Internal.Runtime; using Internal.Text; using Internal.TypeSystem; -using MethodSignature = Internal.TypeSystem.MethodSignature; - namespace ILCompiler.DependencyAnalysis { /// @@ -66,22 +63,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) if (!type.IsFunctionPointer) continue; - MethodSignature sig = ((FunctionPointerType)type).Signature; - - Vertex sigPart = writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(sig.ReturnType))); - foreach (TypeDesc p in sig) - sigPart = writer.GetTuple(sigPart, writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(p)))); - - uint flags = (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) != 0 - ? FunctionPointerMapEntry.IsUnmanagedFlag : 0; - - flags |= (uint)sig.Length << FunctionPointerMapEntry.ParameterCountShift; - - Vertex vertex = - writer.GetTuple( - writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))), - writer.GetUnsignedConstant(flags), - sigPart); + Vertex vertex = writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))); int hashCode = type.GetHashCode(); typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex)); 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 3f26e1f1c19cb8..447bbfa7b392a6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericCompositionNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericCompositionNode.cs @@ -1,25 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; - using Internal.Text; using Internal.TypeSystem; -using Debug = System.Diagnostics.Debug; -using GenericVariance = Internal.Runtime.GenericVariance; - namespace ILCompiler.DependencyAnalysis { /// - /// Describes how a generic type instance is composed - the number of generic arguments, their types, - /// and variance information. + /// Describes types of arguments of generic type instances. /// - public class GenericCompositionNode : DehydratableObjectNode, ISymbolDefinitionNode + public class GenericCompositionNode : ObjectNode, ISymbolDefinitionNode { - private GenericCompositionDetails _details; + private Instantiation _details; - internal GenericCompositionNode(GenericCompositionDetails details) + internal GenericCompositionNode(Instantiation details) { _details = details; } @@ -28,24 +22,10 @@ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append("__GenericInstance"); - Debug.Assert(_details.Instantiation[0] != null || _details.Variance != null); - if (_details.Instantiation[0] != null) - { - for (int i = 0; i < _details.Instantiation.Length; i++) - { - sb.Append('_'); - sb.Append(nameMangler.GetMangledTypeName(_details.Instantiation[i])); - } - } - - if (_details.Variance != null) + foreach (TypeDesc instArg in _details) { - sb.Append("__Variance__"); - for (int i = 0; i < _details.Variance.Length; i++) - { - sb.Append('_'); - sb.Append((checked((byte)_details.Variance[i])).ToStringInvariant()); - } + sb.Append('_'); + sb.Append(nameMangler.GetMangledTypeName(instArg)); } } @@ -57,7 +37,7 @@ public int Offset } } - protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory) + public override ObjectNodeSection GetSection(NodeFactory factory) { if (factory.Target.IsWindows) return ObjectNodeSection.FoldableReadOnlyDataSection; @@ -69,36 +49,23 @@ protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory) public override bool StaticDependenciesAreComputed => true; - protected override ObjectData GetDehydratableData(NodeFactory factory, bool relocsOnly = false) + public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { - bool hasVariance = _details.Variance != null; - var builder = new ObjectDataBuilder(factory, relocsOnly); builder.AddSymbol(this); - builder.RequireInitialPointerAlignment(); - - builder.EmitShort((short)checked((ushort)_details.Instantiation.Length)); - - builder.EmitByte((byte)(hasVariance ? 1 : 0)); - - // TODO: general purpose padding - builder.EmitByte(0); - if (factory.Target.PointerSize == 8) - builder.EmitInt(0); + bool useRelativePointers = factory.Target.SupportsRelativePointers; + if (useRelativePointers) + builder.RequireInitialAlignment(4); + else + builder.RequireInitialPointerAlignment(); - foreach (var typeArg in _details.Instantiation) + foreach (var typeArg in _details) { - if (typeArg == null) - builder.EmitZeroPointer(); + if (useRelativePointers) + builder.EmitReloc(factory.NecessaryTypeSymbol(typeArg), RelocType.IMAGE_REL_BASED_RELPTR32); else - builder.EmitPointerRelocOrIndirectionReference(factory.NecessaryTypeSymbol(typeArg)); - } - - if (hasVariance) - { - foreach (var argVariance in _details.Variance) - builder.EmitByte(checked((byte)argVariance)); + builder.EmitPointerReloc(factory.NecessaryTypeSymbol(typeArg)); } return builder.ToObjectData(); @@ -109,136 +76,19 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo public override int ClassCode => -762680703; public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { - return _details.CompareToImpl(((GenericCompositionNode)other)._details, comparer); - } - } - - internal struct GenericCompositionDetails : IEquatable - { - public readonly Instantiation Instantiation; - - public readonly GenericVariance[] Variance; - - public GenericCompositionDetails(TypeDesc genericTypeInstance, bool forceVarianceInfo = false) - { - if (genericTypeInstance.IsTypeDefinition) - Instantiation = new Instantiation(new TypeDesc[genericTypeInstance.Instantiation.Length]); - else - Instantiation = genericTypeInstance.Instantiation; - - bool emitVarianceInfo = forceVarianceInfo; - if (!emitVarianceInfo) - { - foreach (GenericParameterDesc param in genericTypeInstance.GetTypeDefinition().Instantiation) - { - if (param.Variance != Internal.TypeSystem.GenericVariance.None) - { - emitVarianceInfo = true; - break; - } - } - } - - if (emitVarianceInfo) - { - Debug.Assert((byte)Internal.TypeSystem.GenericVariance.Contravariant == (byte)GenericVariance.Contravariant); - Debug.Assert((byte)Internal.TypeSystem.GenericVariance.Covariant == (byte)GenericVariance.Covariant); - - Variance = new GenericVariance[Instantiation.Length]; - int i = 0; - foreach (GenericParameterDesc param in genericTypeInstance.GetTypeDefinition().Instantiation) - { - Variance[i++] = (GenericVariance)param.Variance; - } - } - else - { - Variance = null; - } - } - - public GenericCompositionDetails(Instantiation instantiation, GenericVariance[] variance) - { - Debug.Assert(variance == null || instantiation.Length == variance.Length); - Instantiation = instantiation; - Variance = variance; - } - - public bool Equals(GenericCompositionDetails other) - { - if (Instantiation.Length != other.Instantiation.Length) - return false; - - if ((Variance == null) != (other.Variance == null)) - return false; - - for (int i = 0; i < Instantiation.Length; i++) - { - if (Instantiation[i] != other.Instantiation[i]) - return false; - - if (Variance != null) - { - if (Variance[i] != other.Variance[i]) - return false; - } - } - - return true; - } - - public int CompareToImpl(GenericCompositionDetails other, TypeSystemComparer comparer) - { - var compare = Instantiation.Length.CompareTo(other.Instantiation.Length); + var otherComposition = (GenericCompositionNode)other; + var compare = _details.Length.CompareTo(otherComposition._details.Length); if (compare != 0) return compare; - if (Variance == null && other.Variance != null) - return -1; - - if (Variance != null && other.Variance == null) - return 1; - - for (int i = 0; i < Instantiation.Length; i++) + for (int i = 0; i < _details.Length; i++) { - compare = comparer.Compare(Instantiation[i], other.Instantiation[i]); + compare = comparer.Compare(_details[i], otherComposition._details[i]); if (compare != 0) return compare; - - if (Variance != null) - { - compare = Variance[i].CompareTo(other.Variance[i]); - if (compare != 0) - return compare; - } } - Debug.Assert(Equals(other)); return 0; } - - public override bool Equals(object obj) - { - return obj is GenericCompositionDetails && Equals((GenericCompositionDetails)obj); - } - - public override int GetHashCode() - { - int hashCode = 13; - - if (Variance != null) - { - foreach (var element in Variance) - { - int value = (int)element * 0x5498341 + 0x832424; - hashCode = hashCode * 31 + value; - } - } - - // If the element is null, this is a variance-only composition info - // for generic definitions. - Debug.Assert(Instantiation[0] != null || Variance != null); - return Instantiation[0] == null ? hashCode : Instantiation.ComputeGenericInstanceHashCode(hashCode); - } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs index 904475d484c88d..b42d93273e4686 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs @@ -43,6 +43,13 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo EETypeRareFlags rareFlags = 0; uint flags = EETypeBuilderHelpers.ComputeFlags(_type); + + // Generic array enumerators use special variance rules recognized by the runtime + // Runtime casting logic relies on all interface types implemented on arrays + // to have the variant flag set. + if (_type == factory.ArrayOfTEnumeratorType || factory.TypeSystemContext.IsGenericArrayInterfaceType(_type)) + flags |= (uint)EETypeFlags.GenericVarianceFlag; + if (_type.IsByRefLike) rareFlags |= EETypeRareFlags.IsByRefLikeFlag; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVarianceNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVarianceNode.cs new file mode 100644 index 00000000000000..7fedd00acc87ef --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVarianceNode.cs @@ -0,0 +1,147 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +using Internal.Text; +using Internal.TypeSystem; + +using Debug = System.Diagnostics.Debug; +using GenericVariance = Internal.Runtime.GenericVariance; + +namespace ILCompiler.DependencyAnalysis +{ + /// + /// Describes variance of a generic type definition. + /// + public class GenericVarianceNode : ObjectNode, ISymbolDefinitionNode + { + private GenericVarianceDetails _details; + + internal GenericVarianceNode(GenericVarianceDetails details) + { + _details = details; + } + + public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append("__GenericVariance"); + + for (int i = 0; i < _details.Variance.Length; i++) + { + sb.Append('_'); + sb.Append((checked((byte)_details.Variance[i])).ToStringInvariant()); + } + } + + public int Offset => 0; + + public override ObjectNodeSection GetSection(NodeFactory factory) + { + if (factory.Target.IsWindows) + return ObjectNodeSection.FoldableReadOnlyDataSection; + else + return ObjectNodeSection.DataSection; + } + + public override bool IsShareable => true; + + public override bool StaticDependenciesAreComputed => true; + + public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) + { + var builder = new ObjectDataBuilder(factory, relocsOnly); + builder.AddSymbol(this); + + foreach (var argVariance in _details.Variance) + builder.EmitByte(checked((byte)argVariance)); + + return builder.ToObjectData(); + } + + protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler); + + public override int ClassCode => -4687913; + public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) + { + return _details.CompareToImpl(((GenericVarianceNode)other)._details); + } + } + + internal struct GenericVarianceDetails : IEquatable + { + public readonly GenericVariance[] Variance; + + public bool IsNull => Variance == null; + + public GenericVarianceDetails(TypeDesc typeDefinition) + { + Debug.Assert(typeDefinition.IsTypeDefinition); + Debug.Assert(typeDefinition.HasInstantiation); + + Debug.Assert((byte)Internal.TypeSystem.GenericVariance.Contravariant == (byte)GenericVariance.Contravariant); + Debug.Assert((byte)Internal.TypeSystem.GenericVariance.Covariant == (byte)GenericVariance.Covariant); + + Variance = new GenericVariance[typeDefinition.Instantiation.Length]; + int i = 0; + foreach (GenericParameterDesc param in typeDefinition.Instantiation) + { + Variance[i++] = (GenericVariance)param.Variance; + } + } + + public GenericVarianceDetails(GenericVariance[] variance) + { + Variance = variance; + } + + public bool Equals(GenericVarianceDetails other) + { + if (Variance.Length != other.Variance.Length) + return false; + + for (int i = 0; i < Variance.Length; i++) + { + if (Variance[i] != other.Variance[i]) + return false; + } + + return true; + } + + public int CompareToImpl(GenericVarianceDetails other) + { + var compare = Variance.Length.CompareTo(other.Variance.Length); + if (compare != 0) + return compare; + + for (int i = 0; i < Variance.Length; i++) + { + compare = Variance[i].CompareTo(other.Variance[i]); + if (compare != 0) + return compare; + } + + Debug.Assert(Equals(other)); + return 0; + } + + public override bool Equals(object obj) + { + return obj is GenericVarianceDetails && Equals((GenericVarianceDetails)obj); + } + + public override int GetHashCode() + { + int hashCode = 13; + + foreach (byte element in Variance) + { + int value = element * 0x5498341 + 0x832424; + hashCode = hashCode * 31 + value; + } + + return hashCode; + } + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs index 14011621e4cf5f..38104d7ab015c9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs @@ -50,7 +50,6 @@ public override ObjectNodeSection GetSection(NodeFactory factory) protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { var result = new DependencyList(); - result.Add(factory.InterfaceDispatchMapIndirection(_type), "Interface dispatch map indirection node"); // VTable slots of implemented interfaces are consulted during emission foreach (TypeDesc runtimeInterface in _type.RuntimeInterfaces) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs index d29fefdccafaa0..7f44064c450894 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs @@ -50,6 +50,13 @@ public override IEnumerable GetStaticDependencies(NodeFacto TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, paramType, reason); } + if (sig.HasEmbeddedSignatureData) + { + foreach (var sigData in sig.GetEmbeddedSignatureData()) + if (sigData.type != null) + TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, sigData.type, "Modifier in a method signature"); + } + if (_method is EcmaMethod ecmaMethod) { DynamicDependencyAttributesOnEntityNode.AddDependenciesDueToDynamicDependencyAttribute(ref dependencies, factory, ecmaMethod); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs index a9aad5606a5a61..d0e19c37a8b572 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs @@ -344,6 +344,8 @@ public override Vertex WriteVertex(NodeFactory factory) methodCallingConvention |= MethodCallingConvention.Generic; if (_signature.IsStatic) methodCallingConvention |= MethodCallingConvention.Static; + if ((_signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) != 0) + methodCallingConvention |= MethodCallingConvention.Unmanaged; Debug.Assert(_signature.Length == _parametersSig.Length); @@ -407,9 +409,8 @@ public static NativeLayoutTypeSignatureVertexNode NewTypeSignatureVertexNode(Nod case Internal.TypeSystem.TypeFlags.SignatureMethodVariable: return new NativeLayoutGenericVarSignatureVertexNode(type); - // TODO Internal.TypeSystem.TypeFlags.FunctionPointer (Runtime parsing also not yet implemented) case Internal.TypeSystem.TypeFlags.FunctionPointer: - throw new NotImplementedException("FunctionPointer signature"); + return new NativeLayoutFunctionPointerTypeSignatureVertexNode(factory, type); default: { @@ -467,6 +468,26 @@ public override Vertex WriteVertex(NodeFactory factory) } } + private sealed class NativeLayoutFunctionPointerTypeSignatureVertexNode : NativeLayoutTypeSignatureVertexNode + { + private readonly NativeLayoutMethodSignatureVertexNode _sig; + + public NativeLayoutFunctionPointerTypeSignatureVertexNode(NodeFactory factory, TypeDesc type) : base(type) + { + _sig = factory.NativeLayout.MethodSignatureVertex(((FunctionPointerType)type).Signature); + } + public override IEnumerable GetStaticDependencies(NodeFactory context) + { + return new DependencyListEntry[] { new DependencyListEntry(_sig, "Method signature") }; + } + public override Vertex WriteVertex(NodeFactory factory) + { + Debug.Assert(Marked, "WriteVertex should only happen for marked vertices"); + + return GetNativeWriter(factory).GetFunctionPointerTypeSignature(_sig.WriteVertex(factory)); + } + } + private sealed class NativeLayoutGenericVarSignatureVertexNode : NativeLayoutTypeSignatureVertexNode { public NativeLayoutGenericVarSignatureVertexNode(TypeDesc type) : base(type) @@ -1240,27 +1261,6 @@ public override Vertex WriteVertex(NodeFactory factory) layoutInfo.Append(BagElementKind.BaseType, factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.TypeSignatureVertex(_type.BaseType)).WriteVertex(factory)); } - if (_type.GetTypeDefinition().HasVariance || factory.TypeSystemContext.IsGenericArrayInterfaceType(_type)) - { - // Runtime casting logic relies on all interface types implemented on arrays - // to have the variant flag set (even if all the arguments are non-variant). - // This supports e.g. casting uint[] to ICollection - List varianceFlags = new List(); - foreach (GenericParameterDesc param in _type.GetTypeDefinition().Instantiation) - { - varianceFlags.Add((uint)param.Variance); - } - - layoutInfo.Append(BagElementKind.GenericVarianceInfo, factory.NativeLayout.PlacedUIntVertexSequence(varianceFlags).WriteVertex(factory)); - } - else if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType) - { - // Generic array enumerators use special variance rules recognized by the runtime - List varianceFlag = new List(); - varianceFlag.Add((uint)Internal.Runtime.GenericVariance.ArrayCovariant); - layoutInfo.Append(BagElementKind.GenericVarianceInfo, factory.NativeLayout.PlacedUIntVertexSequence(varianceFlag).WriteVertex(factory)); - } - if (_isUniversalCanon) { // For universal canonical template types, we need to write out field layout information so that we diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs index f87f1332b3a819..e98c243b2b7261 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs @@ -185,6 +185,20 @@ public IEnumerable TemplateConstructableTypes(TypeDesc type) type = ((ParameterizedType)type).ParameterType; } + if (type.IsFunctionPointer) + { + MethodSignature sig = ((FunctionPointerType)type).Signature; + foreach (var dependency in TemplateConstructableTypes(sig.ReturnType)) + yield return dependency; + + foreach (var param in sig) + foreach (var dependency in TemplateConstructableTypes(param)) + yield return dependency; + + // Nothing else to do for function pointers + yield break; + } + TypeDesc canonicalType = type.ConvertToCanonForm(CanonicalFormKind.Specific); yield return _factory.MaximallyConstructableType(canonicalType); @@ -238,12 +252,6 @@ internal NativeLayoutTypeSignatureVertexNode TypeSignatureVertex(TypeDesc type) type = _factory.TypeSystemContext.GetSignatureVariable(genericParameter.Index, method: (genericParameter.Kind == GenericParameterKind.Method)); } - if (type.Category == TypeFlags.FunctionPointer) - { - // Pretend for now it's an IntPtr, may need to be revisited depending on https://github.com/dotnet/runtime/issues/11354 - type = _factory.TypeSystemContext.GetWellKnownType(WellKnownType.IntPtr); - } - return _typeSignatures.GetOrAdd(type); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs index ef75211e76d60d..c726a9dc0a66d5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -391,14 +391,14 @@ private void CreateNodeCaches() return new EmbeddedTrimmingDescriptorNode(module); }); - _interfaceDispatchMapIndirectionNodes = new NodeCache((TypeDesc type) => + _genericCompositions = new NodeCache((Instantiation details) => { - return DispatchMapTable.NewNodeWithSymbol(InterfaceDispatchMap(type)); + return new GenericCompositionNode(details); }); - _genericCompositions = new NodeCache((GenericCompositionDetails details) => + _genericVariances = new NodeCache((GenericVarianceDetails details) => { - return new GenericCompositionNode(details); + return new GenericVarianceNode(details); }); _eagerCctorIndirectionNodes = new NodeCache((MethodDesc method) => @@ -754,18 +754,18 @@ internal InterfaceDispatchMapNode InterfaceDispatchMap(TypeDesc type) return _interfaceDispatchMaps.GetOrAdd(type); } - private NodeCache _interfaceDispatchMapIndirectionNodes; + private NodeCache _genericCompositions; - public EmbeddedObjectNode InterfaceDispatchMapIndirection(TypeDesc type) + internal ISymbolNode GenericComposition(Instantiation details) { - return _interfaceDispatchMapIndirectionNodes.GetOrAdd(type); + return _genericCompositions.GetOrAdd(details); } - private NodeCache _genericCompositions; + private NodeCache _genericVariances; - internal ISymbolNode GenericComposition(GenericCompositionDetails details) + internal ISymbolNode GenericVariance(GenericVarianceDetails details) { - return _genericCompositions.GetOrAdd(details); + return _genericVariances.GetOrAdd(details); } private NodeCache _externSymbols; @@ -1236,11 +1236,6 @@ public string GetSymbolAlternateName(ISymbolNode node) "__EagerCctorEnd", null); - public ArrayOfEmbeddedPointersNode DispatchMapTable = new ArrayOfEmbeddedPointersNode( - "__DispatchMapTableStart", - "__DispatchMapTableEnd", - new SortableDependencyNode.ObjectNodeComparer(CompilerComparer.Instance)); - public ArrayOfFrozenObjectsNode FrozenSegmentRegion = new ArrayOfFrozenObjectsNode(); internal ModuleInitializerListNode ModuleInitializerList = new ModuleInitializerListNode(); @@ -1264,7 +1259,6 @@ public virtual void AttachToDependencyGraph(DependencyAnalyzerBase graph.AddRoot(ThreadStaticsRegion, "ThreadStaticsRegion is always generated"); graph.AddRoot(EagerCctorTable, "EagerCctorTable is always generated"); graph.AddRoot(TypeManagerIndirection, "TypeManagerIndirection is always generated"); - graph.AddRoot(DispatchMapTable, "DispatchMapTable is always generated"); graph.AddRoot(FrozenSegmentRegion, "FrozenSegmentRegion is always generated"); graph.AddRoot(InterfaceDispatchCellSection, "Interface dispatch cell section is always generated"); graph.AddRoot(ModuleInitializerList, "Module initializer list is always generated"); @@ -1273,7 +1267,6 @@ public virtual void AttachToDependencyGraph(DependencyAnalyzerBase ReadyToRunHeader.Add(ReadyToRunSectionType.ThreadStaticRegion, ThreadStaticsRegion, ThreadStaticsRegion.StartSymbol, ThreadStaticsRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.EagerCctor, EagerCctorTable, EagerCctorTable.StartSymbol, EagerCctorTable.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.TypeManagerIndirection, TypeManagerIndirection, TypeManagerIndirection); - ReadyToRunHeader.Add(ReadyToRunSectionType.InterfaceDispatchTable, DispatchMapTable, DispatchMapTable.StartSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.FrozenObjectRegion, FrozenSegmentRegion, FrozenSegmentRegion, FrozenSegmentRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.ModuleInitializerList, ModuleInitializerList, ModuleInitializerList, ModuleInitializerList.EndSymbol); 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 3ded29612dadc8..7b491fad1dc274 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs @@ -535,9 +535,7 @@ public void PublishUnwindInfo(ObjectNode node) byte[] blobSymbolName = _sb.Append(_currentNodeZeroTerminatedName).ToUtf8String().UnderlyingArray; - ObjectNodeSection section = ObjectNodeSection.XDataSection; - if (ShouldShareSymbol(node)) - section = GetSharedSection(section, _sb.ToString()); + ObjectNodeSection section = GetSharedSection(ObjectNodeSection.XDataSection, _sb.ToString()); SwitchSection(_nativeObjectWriter, section.Name, GetCustomSectionAttributes(section), section.ComdatName); EmitAlignment(4); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/PointerTypeMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/PointerTypeMapNode.cs new file mode 100644 index 00000000000000..497c1f58092cb0 --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/PointerTypeMapNode.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +using Internal.NativeFormat; +using Internal.Text; + +namespace ILCompiler.DependencyAnalysis +{ + /// + /// Represents a hash table of pointer types generated into the image. + /// + internal sealed class PointerTypeMapNode : ObjectNode, ISymbolDefinitionNode + { + private readonly ObjectAndOffsetSymbolNode _endSymbol; + private readonly ExternalReferencesTableNode _externalReferences; + + public PointerTypeMapNode(ExternalReferencesTableNode externalReferences) + { + _endSymbol = new ObjectAndOffsetSymbolNode(this, 0, "__ptr_type_map_End", true); + _externalReferences = externalReferences; + } + + public ISymbolDefinitionNode EndSymbol => _endSymbol; + + public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append(nameMangler.CompilationUnitPrefix).Append("__ptr_type_map"); + } + public int Offset => 0; + public override bool IsShareable => false; + + public override ObjectNodeSection GetSection(NodeFactory factory) => _externalReferences.GetSection(factory); + + public override bool StaticDependenciesAreComputed => true; + + protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler); + + public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) + { + // This node does not trigger generation of other nodes. + if (relocsOnly) + return new ObjectData(Array.Empty(), Array.Empty(), 1, new ISymbolDefinitionNode[] { this }); + + var writer = new NativeWriter(); + var typeMapHashTable = new VertexHashtable(); + + Section hashTableSection = writer.NewSection(); + hashTableSection.Place(typeMapHashTable); + + foreach (var type in factory.MetadataManager.GetTypesWithEETypes()) + { + if (!type.IsPointer) + continue; + + Vertex vertex = writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))); + + int hashCode = type.GetHashCode(); + typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex)); + } + + byte[] hashTableBytes = writer.Save(); + + _endSymbol.SetSymbolOffset(hashTableBytes.Length); + + return new ObjectData(hashTableBytes, Array.Empty(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }); + } + + protected internal override int Phase => (int)ObjectNodePhase.Ordered; + public override int ClassCode => (int)ObjectNodeOrder.PointerMapNode; + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs index 8a4bce713efe4a..18d655748937cd 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs @@ -27,6 +27,7 @@ public ExternSymbolMappedField(TypeDesc fieldType, string symbolName) public override TypeDesc FieldType => _fieldType; public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; public override bool IsStatic => true; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs index 0bfcca959c2453..1411ca7b6c7941 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs @@ -109,6 +109,8 @@ private static class XArchIntrinsicConstants public const int Avx512cd_vl = 0x100000; public const int Avx512dq = 0x200000; public const int Avx512dq_vl = 0x400000; + public const int Avx512Vbmi = 0x800000; + public const int Avx512Vbmi_vl = 0x1000000; public static int FromInstructionSet(InstructionSet instructionSet) { @@ -164,6 +166,10 @@ public static int FromInstructionSet(InstructionSet instructionSet) InstructionSet.X64_AVX512DQ_X64 => Avx512dq, InstructionSet.X64_AVX512DQ_VL => Avx512dq_vl, InstructionSet.X64_AVX512DQ_VL_X64 => Avx512dq_vl, + InstructionSet.X64_AVX512VBMI => Avx512Vbmi, + InstructionSet.X64_AVX512VBMI_X64 => Avx512Vbmi, + InstructionSet.X64_AVX512VBMI_VL => Avx512Vbmi_vl, + InstructionSet.X64_AVX512VBMI_VL_X64 => Avx512Vbmi_vl, // SSE and SSE2 are baseline ISAs - they're always available InstructionSet.X64_SSE => 0, diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 123166e3ec7fad..b126d06da83714 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -135,10 +135,6 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeFieldHandle"); break; - case ReadyToRunHelper.AreTypesEquivalent: - mangledName = "RhTypeCast_AreTypesEquivalent"; - break; - case ReadyToRunHelper.Lng2Dbl: mangledName = "RhpLng2Dbl"; break; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs index 13942b8d45c40f..aa7a3ccad51f1b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs @@ -149,11 +149,6 @@ public void LogError(TypeSystemEntity origin, DiagnosticId id, params string[] a internal bool IsWarningSuppressed(int code, MessageOrigin origin) { - // This is causing too much noise - // https://github.com/dotnet/runtime/issues/81156 - if (code == 2110 || code == 2111 || code == 2113 || code == 2115) - return true; - if (_suppressedWarnings.Contains(code)) return true; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs index 8717aec1688eba..ed5591bd3c84ba 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs @@ -146,6 +146,12 @@ public virtual void AddToReadyToRunHeader(ReadyToRunHeaderNode header, NodeFacto var arrayMapNode = new ArrayMapNode(commonFixupsTableNode); header.Add(BlobIdToReadyToRunSection(ReflectionMapBlob.ArrayMap), arrayMapNode, arrayMapNode, arrayMapNode.EndSymbol); + var byRefMapNode = new ByRefTypeMapNode(commonFixupsTableNode); + header.Add(BlobIdToReadyToRunSection(ReflectionMapBlob.ByRefTypeMap), byRefMapNode, byRefMapNode, byRefMapNode.EndSymbol); + + var pointerMapNode = new PointerTypeMapNode(commonFixupsTableNode); + header.Add(BlobIdToReadyToRunSection(ReflectionMapBlob.PointerTypeMap), pointerMapNode, pointerMapNode, pointerMapNode.EndSymbol); + var functionPointerMapNode = new FunctionPointerMapNode(commonFixupsTableNode); header.Add(BlobIdToReadyToRunSection(ReflectionMapBlob.FunctionPointerTypeMap), functionPointerMapNode, functionPointerMapNode, functionPointerMapNode.EndSymbol); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs index 2d8a7d9e8f355c..989d4782402ac8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs @@ -11,6 +11,8 @@ using Internal.IL; using Internal.TypeSystem; +using DependencyList = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.DependencyList; + namespace ILCompiler { // Class that computes the initial state of static fields on a type by interpreting the static constructor. @@ -1812,6 +1814,7 @@ public interface ISerializableReference : ISerializableValue { TypeDesc Type { get; } void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory); + void GetNonRelocationDependencies(ref DependencyList dependencies, NodeFactory factory); bool IsKnownImmutable { get; } int ArrayLength { get; } } @@ -2261,11 +2264,13 @@ public override bool GetRawData(NodeFactory factory, out object data) data = null; return false; } + + public virtual void GetNonRelocationDependencies(ref DependencyList dependencies, NodeFactory factory) + { + } } -#pragma warning disable CA1852 - private class DelegateInstance : AllocatedReferenceTypeValue, ISerializableReference -#pragma warning restore CA1852 + private sealed class DelegateInstance : AllocatedReferenceTypeValue, ISerializableReference { private readonly MethodDesc _methodPointed; private readonly ReferenceTypeValue _firstParameter; @@ -2277,17 +2282,28 @@ public DelegateInstance(TypeDesc delegateType, MethodDesc methodPointed, Referen _firstParameter = firstParameter; } - public virtual void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory) - { - Debug.Assert(_methodPointed.Signature.IsStatic == (_firstParameter == null)); - - var creationInfo = DelegateCreationInfo.Create( + private DelegateCreationInfo GetDelegateCreationInfo(NodeFactory factory) + => DelegateCreationInfo.Create( Type.ConvertToCanonForm(CanonicalFormKind.Specific), _methodPointed, constrainedType: null, factory, followVirtualDispatch: false); + public override void GetNonRelocationDependencies(ref DependencyList dependencies, NodeFactory factory) + { + DelegateCreationInfo creationInfo = GetDelegateCreationInfo(factory); + + MethodDesc targetMethod = creationInfo.PossiblyUnresolvedTargetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); + factory.MetadataManager.GetDependenciesDueToDelegateCreation(ref dependencies, factory, targetMethod); + } + + public void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory) + { + Debug.Assert(_methodPointed.Signature.IsStatic == (_firstParameter == null)); + + DelegateCreationInfo creationInfo = GetDelegateCreationInfo(factory); + Debug.Assert(!creationInfo.TargetNeedsVTableLookup); // MethodTable @@ -2340,9 +2356,7 @@ public override void WriteFieldData(ref ObjectDataBuilder builder, NodeFactory f public int ArrayLength => throw new NotSupportedException(); } -#pragma warning disable CA1852 - private class ArrayInstance : AllocatedReferenceTypeValue, ISerializableReference -#pragma warning restore CA1852 + private sealed class ArrayInstance : AllocatedReferenceTypeValue, ISerializableReference { private readonly int _elementCount; private readonly int _elementSize; @@ -2405,7 +2419,7 @@ public override void WriteFieldData(ref ObjectDataBuilder builder, NodeFactory f builder.EmitPointerReloc(factory.SerializedFrozenObject(AllocationSite.OwningType, AllocationSite.InstructionCounter, this)); } - public virtual void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory) + public void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory) { // MethodTable var node = factory.ConstructedTypeSymbol(Type); @@ -2518,9 +2532,7 @@ public override bool GetRawData(NodeFactory factory, out object data) ByRefValue IHasInstanceFields.GetFieldAddress(FieldDesc field) => new FieldAccessor(_value).GetFieldAddress(field); } -#pragma warning disable CA1852 - private class ObjectInstance : AllocatedReferenceTypeValue, IHasInstanceFields, ISerializableReference -#pragma warning restore CA1852 + private sealed class ObjectInstance : AllocatedReferenceTypeValue, IHasInstanceFields, ISerializableReference { private readonly byte[] _data; @@ -2574,7 +2586,7 @@ public override void WriteFieldData(ref ObjectDataBuilder builder, NodeFactory f builder.EmitPointerReloc(factory.SerializedFrozenObject(AllocationSite.OwningType, AllocationSite.InstructionCounter, this)); } - public virtual void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory) + public void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory) { // MethodTable var node = factory.ConstructedTypeSymbol(Type); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj index 3e71f63059fcbf..fc41ba97ec0f0d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj @@ -335,6 +335,7 @@ + @@ -383,7 +384,7 @@ - + Compiler\Dataflow\TypeNameParser.cs @@ -404,6 +405,7 @@ + @@ -411,6 +413,7 @@ + diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs index c7b400a8400a87..9c04f3ca3c2144 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs @@ -47,11 +47,6 @@ private Field HandleFieldDefinition(Cts.FieldDesc field) private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) { record.Name = HandleString(entity.Name); - record.Signature = new FieldSignature - { - Type = HandleType(entity.FieldType), - // TODO: CustomModifiers - }; record.Flags = GetFieldAttributes(entity); var ecmaField = entity as Cts.Ecma.EcmaField; @@ -59,6 +54,14 @@ private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) { Ecma.MetadataReader reader = ecmaField.MetadataReader; Ecma.FieldDefinition fieldDef = reader.GetFieldDefinition(ecmaField.Handle); + + record.Signature = new FieldSignature + { + Type = entity.HasEmbeddedSignatureData + ? HandleFieldSignature(ecmaField.Module, fieldDef.Signature) + : HandleType(entity.FieldType), + }; + Ecma.ConstantHandle defaultValueHandle = fieldDef.GetDefaultValue(); if (!defaultValueHandle.IsNil) { @@ -75,6 +78,18 @@ private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) if (offset >= 0) record.Offset = (uint)offset; } + else + { + throw new NotImplementedException(); + } + } + + private MetadataRecord HandleFieldSignature(Cts.Ecma.EcmaModule module, Ecma.BlobHandle sigBlob) + { + Ecma.BlobReader reader = module.MetadataReader.GetBlobReader(sigBlob); + Ecma.SignatureHeader header = reader.ReadSignatureHeader(); + Debug.Assert(header.Kind == Ecma.SignatureKind.Field); + return HandleType(module, ref reader); } private MemberReference HandleFieldReference(Cts.FieldDesc field) diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs index ac044cb45cc504..354b7913d533ed 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs @@ -61,7 +61,6 @@ private Method HandleMethodDefinition(Cts.MethodDesc method) private void InitializeMethodDefinition(Cts.MethodDesc entity, Method record) { record.Name = HandleString(entity.Name); - record.Signature = HandleMethodSignature(entity.Signature); if (entity.HasInstantiation) { @@ -77,6 +76,11 @@ private void InitializeMethodDefinition(Cts.MethodDesc entity, Method record) Ecma.MethodDefinition methodDef = reader.GetMethodDefinition(ecmaEntity.Handle); Ecma.ParameterHandleCollection paramHandles = methodDef.GetParameters(); + Cts.MethodSignature sig = entity.Signature; + record.Signature = sig.HasEmbeddedSignatureData + ? HandleMethodSignature(ecmaEntity.Module, methodDef.Signature) + : HandleMethodSignature(entity.Signature); + record.Parameters.Capacity = paramHandles.Count; foreach (var paramHandle in paramHandles) { @@ -170,6 +174,37 @@ public override MethodSignature HandleMethodSignature(Cts.MethodSignature signat return result; } + private MethodSignature HandleMethodSignature(Cts.Ecma.EcmaModule module, Ecma.BlobHandle sigBlobHandle) + { + Ecma.BlobReader blobReader = module.MetadataReader.GetBlobReader(sigBlobHandle); + return HandleMethodSignature(module, ref blobReader); + } + + private MethodSignature HandleMethodSignature(Cts.Ecma.EcmaModule module, ref Ecma.BlobReader blobReader) + { + Ecma.SignatureHeader header = blobReader.ReadSignatureHeader(); + + int arity = header.IsGeneric ? blobReader.ReadCompressedInteger() : 0; + + int count = blobReader.ReadCompressedInteger(); + + var result = new MethodSignature + { + CallingConvention = GetSignatureCallingConvention(header), + GenericParameterCount = arity, + ReturnType = HandleType(module, ref blobReader), + // TODO-NICE: VarArgParameters + }; + + result.Parameters.Capacity = count; + for (int i = 0; i < count; i++) + { + result.Parameters.Add(HandleType(module, ref blobReader)); + } + + return result; + } + private static MethodAttributes GetMethodAttributes(Cts.MethodDesc method) { var ecmaMethod = method as Cts.Ecma.EcmaMethod; @@ -208,5 +243,18 @@ private static SignatureCallingConvention GetSignatureCallingConvention(Cts.Meth } return callingConvention; } + + private static SignatureCallingConvention GetSignatureCallingConvention(Ecma.SignatureHeader signature) + { + Debug.Assert((int)Ecma.SignatureCallingConvention.CDecl == (int)SignatureCallingConvention.Cdecl); + Debug.Assert((int)Ecma.SignatureCallingConvention.ThisCall == (int)SignatureCallingConvention.ThisCall); + Debug.Assert((int)Ecma.SignatureCallingConvention.Unmanaged == (int)SignatureCallingConvention.Unmanaged); + SignatureCallingConvention callingConvention = (SignatureCallingConvention)(signature.CallingConvention); + if (signature.IsInstance) + { + callingConvention |= SignatureCallingConvention.HasThis; + } + return callingConvention; + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs index 342709536b4ade..786d694be1dd6a 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs @@ -40,13 +40,24 @@ private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinit Signature = new PropertySignature { CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis, - Type = HandleType(sig.ReturnType) }, }; result.Signature.Parameters.Capacity = sig.Length; - for (int i = 0; i < sig.Length; i++) - result.Signature.Parameters.Add(HandleType(sig[i])); + if (!sig.HasEmbeddedSignatureData) + { + result.Signature.Type = HandleType(sig.ReturnType); + for (int i = 0; i < sig.Length; i++) + result.Signature.Parameters.Add(HandleType(sig[i])); + } + else + { + sigBlobReader.ReadSignatureHeader(); + int count = sigBlobReader.ReadCompressedInteger(); + result.Signature.Type = HandleType(module, ref sigBlobReader); + for (int i = 0; i < count; i++) + result.Signature.Parameters.Add(HandleType(module, ref sigBlobReader)); + } if (getterHasMetadata) { diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs index 226e8ea0f9c7ff..632118848a6140 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs @@ -376,6 +376,142 @@ static bool HasNestedTypes(Cts.MetadataType entity) => entity.GetNestedTypes().GetEnumerator().MoveNext(); } + private MetadataRecord HandleType(Cts.Ecma.EcmaModule module, ref Ecma.BlobReader reader) + { + switch (reader.ReadSignatureTypeCode()) + { + case Ecma.SignatureTypeCode.Void: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Void)); + case Ecma.SignatureTypeCode.Boolean: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Boolean)); + case Ecma.SignatureTypeCode.SByte: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.SByte)); + case Ecma.SignatureTypeCode.Byte: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Byte)); + case Ecma.SignatureTypeCode.Int16: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Int16)); + case Ecma.SignatureTypeCode.UInt16: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UInt16)); + case Ecma.SignatureTypeCode.Int32: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Int32)); + case Ecma.SignatureTypeCode.UInt32: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UInt32)); + case Ecma.SignatureTypeCode.Int64: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Int64)); + case Ecma.SignatureTypeCode.UInt64: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UInt64)); + case Ecma.SignatureTypeCode.Single: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Single)); + case Ecma.SignatureTypeCode.Double: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Double)); + case Ecma.SignatureTypeCode.Char: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Char)); + case Ecma.SignatureTypeCode.String: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.String)); + case Ecma.SignatureTypeCode.IntPtr: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.IntPtr)); + case Ecma.SignatureTypeCode.UIntPtr: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UIntPtr)); + case Ecma.SignatureTypeCode.Object: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Object)); + case Ecma.SignatureTypeCode.TypeHandle: + return HandleType(module.GetType(reader.ReadTypeHandle())); + case Ecma.SignatureTypeCode.SZArray: + return new TypeSpecification + { + Signature = new SZArraySignature() + { + ElementType = HandleType(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.Array: + { + MetadataRecord elementType = HandleType(module, ref reader); + int rank = reader.ReadCompressedInteger(); + + var boundsCount = reader.ReadCompressedInteger(); + for (int i = 0; i < boundsCount; i++) + reader.ReadCompressedInteger(); + var lowerBoundsCount = reader.ReadCompressedInteger(); + for (int j = 0; j < lowerBoundsCount; j++) + reader.ReadCompressedSignedInteger(); + + return new TypeSpecification + { + Signature = new ArraySignature() + { + ElementType = elementType, + Rank = rank, + // TODO: sizes & lower bounds + } + }; + } + case Ecma.SignatureTypeCode.ByReference: + return new TypeSpecification + { + Signature = new ByReferenceSignature() + { + Type = HandleType(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.Pointer: + return new TypeSpecification + { + Signature = new PointerSignature() + { + Type = HandleType(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.GenericTypeParameter: + return HandleType(module.Context.GetSignatureVariable(reader.ReadCompressedInteger(), false)); + case Ecma.SignatureTypeCode.GenericMethodParameter: + return HandleType(module.Context.GetSignatureVariable(reader.ReadCompressedInteger(), true)); + case Ecma.SignatureTypeCode.GenericTypeInstance: + { + var sig = new TypeInstantiationSignature + { + GenericType = HandleType(module, ref reader) + }; + + int count = reader.ReadCompressedInteger(); + for (int i = 0; i < count; i++) + sig.GenericTypeArguments.Add(HandleType(module, ref reader)); + + return new TypeSpecification + { + Signature = sig + }; + } + case Ecma.SignatureTypeCode.TypedReference: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.TypedReference)); + case Ecma.SignatureTypeCode.FunctionPointer: + return new TypeSpecification + { + Signature = new FunctionPointerSignature + { + Signature = HandleMethodSignature(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.OptionalModifier: + return new ModifiedType + { + IsOptional = true, + ModifierType = HandleType(module.GetType(reader.ReadTypeHandle())), + Type = HandleType(module, ref reader), + }; + case Ecma.SignatureTypeCode.RequiredModifier: + return new ModifiedType + { + IsOptional = false, + ModifierType = HandleType(module.GetType(reader.ReadTypeHandle())), + Type = HandleType(module, ref reader), + }; + + default: + throw new BadImageFormatException(); + } + } + private static TypeAttributes GetTypeAttributes(Cts.MetadataType type) { TypeAttributes result; diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs index 1691371d451e56..0e61942db03ca9 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs @@ -77,7 +77,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(ElementType == null || ElementType.HandleType == HandleType.TypeDefinition || ElementType.HandleType == HandleType.TypeReference || - ElementType.HandleType == HandleType.TypeSpecification); + ElementType.HandleType == HandleType.TypeSpecification || + ElementType.HandleType == HandleType.ModifiedType); writer.Write(ElementType); writer.Write(Rank); writer.Write(Sizes); @@ -151,7 +152,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(Type == null || Type.HandleType == HandleType.TypeDefinition || Type.HandleType == HandleType.TypeReference || - Type.HandleType == HandleType.TypeSpecification); + Type.HandleType == HandleType.TypeSpecification || + Type.HandleType == HandleType.ModifiedType); writer.Write(Type); } // Save @@ -2994,7 +2996,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(GenericTypeArguments.TrueForAll(handle => handle == null || handle.HandleType == HandleType.TypeDefinition || handle.HandleType == HandleType.TypeReference || - handle.HandleType == HandleType.TypeSpecification)); + handle.HandleType == HandleType.TypeSpecification || + handle.HandleType == HandleType.ModifiedType)); writer.Write(GenericTypeArguments); } // Save @@ -4692,7 +4695,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(GenericTypeArguments.TrueForAll(handle => handle == null || handle.HandleType == HandleType.TypeDefinition || handle.HandleType == HandleType.TypeReference || - handle.HandleType == HandleType.TypeSpecification)); + handle.HandleType == HandleType.TypeSpecification || + handle.HandleType == HandleType.ModifiedType)); writer.Write(GenericTypeArguments); } // Save diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs index 33388962e8679d..573eacc1fcc4cf 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs @@ -291,6 +291,10 @@ public override ICompilation ToCompilation() break; } + // Always allow frozen allocators for R2R (NativeAOT is able to preinitialize objects on + // frozen segments without JIT's help) + corJitFlags.Add(CorJitFlag.CORJIT_FLAG_FROZEN_ALLOC_ALLOWED); + if (!_isJitInitialized) { JitConfigProvider.Initialize(_context.Target, corJitFlags, _ryujitOptions, _jitPath); 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 c40ee03d8fb05f..f73c55cd0dc679 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -898,6 +898,12 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_DIRECT: id = ReadyToRunHelper.NewArray; break; + case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_MAYBEFROZEN: + id = ReadyToRunHelper.NewMaybeFrozenArray; + break; + case CorInfoHelpFunc.CORINFO_HELP_NEWFAST_MAYBEFROZEN: + id = ReadyToRunHelper.NewMaybeFrozenObject; + break; case CorInfoHelpFunc.CORINFO_HELP_VIRTUAL_FUNC_PTR: id = ReadyToRunHelper.VirtualFuncPtr; break; @@ -3015,7 +3021,7 @@ private int getExactClasses(CORINFO_CLASS_STRUCT_* baseType, int maxExactClasses return 0; } - private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) + private bool getStaticFieldContent(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) { Debug.Assert(fieldHandle != null); FieldDesc field = HandleToObject(fieldHandle); @@ -3028,6 +3034,11 @@ private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byt return false; } + private bool getObjectContent(CORINFO_OBJECT_STRUCT_* obj, byte* buffer, int bufferSize, int valueOffset) + { + throw new NotSupportedException(); + } + private CORINFO_CLASS_STRUCT_* getObjectType(CORINFO_OBJECT_STRUCT_* objPtr) { throw new NotSupportedException(); diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index 2d123c39d6178a..8d325f467d600f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -1774,6 +1774,14 @@ private void ParseHelper(StringBuilder builder) builder.Append("NEW_ARRAY"); break; + case ReadyToRunHelper.NewMaybeFrozenArray: + builder.Append("NEW_MAYBEFROZEN_ARRAY"); + break; + + case ReadyToRunHelper.NewMaybeFrozenObject: + builder.Append("NEW_MAYBEFROZEN_OBJECT"); + break; + case ReadyToRunHelper.CheckCastAny: builder.Append("CHECK_CAST_ANY"); break; 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 b336eb9665e61f..b8a56bb708cb08 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -544,10 +544,6 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) id = ReadyToRunHelper.GetRuntimeTypeHandle; break; - case CorInfoHelpFunc.CORINFO_HELP_ARE_TYPES_EQUIVALENT: - id = ReadyToRunHelper.AreTypesEquivalent; - break; - case CorInfoHelpFunc.CORINFO_HELP_ISINSTANCEOF_EXCEPTION: id = ReadyToRunHelper.IsInstanceOfException; break; @@ -2240,7 +2236,7 @@ private int getExactClasses(CORINFO_CLASS_STRUCT_* baseType, int maxExactClasses return index; } - private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) + private bool getStaticFieldContent(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) { Debug.Assert(fieldHandle != null); Debug.Assert(buffer != null); @@ -2303,6 +2299,33 @@ private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byt return false; } + private bool getObjectContent(CORINFO_OBJECT_STRUCT_* objPtr, byte* buffer, int bufferSize, int valueOffset) + { + Debug.Assert(objPtr != null); + Debug.Assert(buffer != null); + Debug.Assert(bufferSize >= 0); + Debug.Assert(valueOffset >= 0); + + object obj = HandleToObject(objPtr); + if (obj is FrozenStringNode frozenStr) + { + // Only support reading the string data + int strDataOffset = _compilation.TypeSystemContext.Target.PointerSize + sizeof(int); // 12 on 64bit + if (valueOffset >= strDataOffset && (long)frozenStr.Data.Length * 2 >= (valueOffset - strDataOffset) + bufferSize) + { + int offset = valueOffset - strDataOffset; + fixed (char* pStr = frozenStr.Data) + { + new Span((byte*)pStr + offset, bufferSize).CopyTo( + new Span(buffer, bufferSize)); + return true; + } + } + } + // TODO: handle FrozenObjectNode + return false; + } + private CORINFO_CLASS_STRUCT_* getObjectType(CORINFO_OBJECT_STRUCT_* objPtr) { object obj = HandleToObject(objPtr); diff --git a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj index 26251393ffa3ee..3630adaad3503c 100644 --- a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj +++ b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj @@ -81,7 +81,7 @@ Console true - $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\eventpipe-disabled.lib + $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\eventpipe-disabled.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.VxsortDisabled.lib @@ -101,7 +101,7 @@ true true true - $(ArtifactsRoot)bin\repro\x64\Checked\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\eventpipe-disabled.lib + $(ArtifactsRoot)bin\repro\x64\Checked\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\eventpipe-disabled.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\Runtime.VxsortDisabled.lib @@ -121,7 +121,7 @@ true true true - $(ArtifactsRoot)bin\repro\x64\Release\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\eventpipe-disabled.lib + $(ArtifactsRoot)bin\repro\x64\Release\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\eventpipe-disabled.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\Runtime.VxsortDisabled.lib diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj b/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj index 72fd7dffe14948..dc1dd6f608ced3 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj @@ -38,6 +38,9 @@ $(ArtifactsDir) + + $(CoreCLRArtifactsPath) + $(ArtifactsBinDir) diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs index fc9b8f26650bc5..2eb46309c7d379 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs @@ -34,6 +34,11 @@ public static IEnumerable LinkXml() return TestNamesBySuiteName(); } + public static IEnumerable Reflection () + { + return TestNamesBySuiteName (); + } + public static IEnumerable Repro () { return TestNamesBySuiteName (); diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs index add1386c9bad88..4e3901f2697069 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs @@ -37,6 +37,20 @@ public void LinkXml (string t) Run (t); } + [Theory] + [MemberData (nameof (TestDatabase.Reflection), MemberType = typeof (TestDatabase))] + public void Reflection (string t) + { + switch (t) { + case "TypeHierarchyReflectionWarnings": + Run (t); + break; + default: + // Skip the rest for now + break; + } + } + [Theory] [MemberData (nameof (TestDatabase.Repro), MemberType = typeof (TestDatabase))] public void Repro (string t) diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs index b2ef8520914794..961e4b6a9c0152 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs @@ -8,8 +8,6 @@ using System.Text; using FluentAssertions; using ILCompiler; -using ILCompiler.DependencyAnalysis; -using Internal.IL.Stubs; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; using Mono.Cecil; @@ -42,7 +40,10 @@ public class AssemblyChecker // Ignore NativeAOT injected members ".StartupCodeMain(Int32,IntPtr)", - ".MainMethodWrapper()" + ".MainMethodWrapper()", + + // Ignore compiler generated code which can't be reasonably matched to the source method + "", }; public AssemblyChecker ( @@ -130,6 +131,10 @@ private void PopulateLinkedMembers () AddMethod (method); } + foreach (MethodDesc method in testResult.TrimmingResults.ReflectedMethods) { + AddMethod (method); + } + void AddMethod (MethodDesc method) { MethodDesc methodDef = method.GetTypicalMethodDefinition (); diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs index af39d8d687883c..01693b1bdc0bdb 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs @@ -9,6 +9,7 @@ using Internal.TypeSystem.Ecma; using Internal.TypeSystem; using Mono.Cecil; +using MetadataType = Internal.TypeSystem.MetadataType; namespace Mono.Linker.Tests.TestCasesRunner { @@ -27,6 +28,7 @@ public AssemblyQualifiedToken (TypeSystemEntity entity) => PropertyPseudoDesc property => (((EcmaType) property.OwningType).Module.Assembly.GetName ().Name, MetadataTokens.GetToken (property.Handle)), EventPseudoDesc @event => (((EcmaType) @event.OwningType).Module.Assembly.GetName ().Name, MetadataTokens.GetToken (@event.Handle)), ILStubMethod => (null, 0), // Ignore compiler generated methods + MetadataType mt when mt.GetType().Name == "BoxedValueType" => (null, 0), _ => throw new NotSupportedException ($"The infra doesn't support getting a token for {entity} yet.") }; diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs index 2864f4c2c88566..d5fa880badfefe 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs @@ -64,6 +64,16 @@ public ILScanResults Trim (ILCompilerOptions options, ILogWriter logWriter) compilationRoots.Add (new MainMethodRootProvider (entrypointModule, CreateInitializerList (typeSystemContext, options), generateLibraryAndModuleInitializers: true)); + foreach (var rootedAssembly in options.AdditionalRootAssemblies) { + EcmaModule module = typeSystemContext.GetModuleForSimpleName (rootedAssembly); + + // We only root the module type. The rest will fall out because we treat rootedAssemblies + // same as conditionally rooted ones and here we're fulfilling the condition ("something is used"). + compilationRoots.Add ( + new GenericRootProvider (module, + (ModuleDesc module, IRootingServiceProvider rooter) => rooter.AddReflectionRoot (module.GetGlobalModuleType (), "Command line root"))); + } + ILProvider ilProvider = new NativeAotILProvider (); Logger logger = new Logger ( diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs index bffa9822c358f5..22b7a621acc6de 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs @@ -61,10 +61,9 @@ protected virtual NPath LocateIlasm () #if NETCOREAPP var extension = RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? ".exe" : ""; - // working directory is artifacts/bin/Mono.Linker.Tests// - var toolsDir = Path.Combine (Directory.GetCurrentDirectory (), "..", "..", "..", "..", "tools"); + var toolsDir = (string) AppContext.GetData ("Mono.Linker.Tests.ILToolsDir")!; - var ilasmPath = Path.GetFullPath (Path.Combine (toolsDir, "ilasm", $"ilasm{extension}")).ToNPath (); + var ilasmPath = Path.GetFullPath (Path.Combine (toolsDir, $"ilasm{extension}")).ToNPath (); if (ilasmPath.FileExists ()) return ilasmPath; diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 4d694b7ae0061c..cb752664e81fe6 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -80,7 +80,7 @@ public virtual void Check (ILCompilerTestCaseResult testResult) PerformOutputAssemblyChecks (original, testResult); PerformOutputSymbolChecks (original, testResult); - if (!HasAttribute (original.MainModule.GetType (testResult.TestCase.ReconstructedFullTypeName), nameof (SkipKeptItemsValidationAttribute))) { + if (!HasActiveSkipKeptItemsValidationAttribute (original.MainModule.GetType (testResult.TestCase.ReconstructedFullTypeName))) { CreateAssemblyChecker (original, testResult).Verify (); } } @@ -89,6 +89,16 @@ public virtual void Check (ILCompilerTestCaseResult testResult) } finally { _originalsResolver.Dispose (); } + + bool HasActiveSkipKeptItemsValidationAttribute(ICustomAttributeProvider provider) + { + if (TryGetCustomAttribute(provider, nameof(SkipKeptItemsValidationAttribute), out var attribute)) { + object? keptBy = attribute.GetPropertyValue (nameof (SkipKeptItemsValidationAttribute.By)); + return keptBy is null ? true : ((Tool) keptBy).HasFlag (Tool.NativeAot); + } + + return false; + } } protected virtual AssemblyChecker CreateAssemblyChecker (AssemblyDefinition original, ILCompilerTestCaseResult testResult) @@ -316,8 +326,8 @@ private void VerifyLoggedMessages (AssemblyDefinition original, TestLogWriter lo loggedMessages.Remove (loggedMessage); break; } - if (methodDesc.Name == ".ctor" && - methodDesc.OwningType.ToString () == expectedMember.FullName) { + if (methodDesc.IsConstructor && + new AssemblyQualifiedToken (methodDesc.OwningType).Equals(new AssemblyQualifiedToken (expectedMember))) { expectedWarningFound = true; loggedMessages.Remove (loggedMessage); break; @@ -400,10 +410,13 @@ static bool LogMessageHasSameOriginMember (MessageContainer mc, ICustomAttribute Debug.Assert (origin != null); if (origin?.MemberDefinition == null) return false; + if (origin?.MemberDefinition is IAssemblyDesc asm) + return expectedOriginProvider is AssemblyDefinition expectedAsm && asm.GetName().Name == expectedAsm.Name.Name; + if (expectedOriginProvider is not IMemberDefinition expectedOriginMember) return false; - var actualOriginToken = new AssemblyQualifiedToken (origin.Value.MemberDefinition); + var actualOriginToken = new AssemblyQualifiedToken (origin!.Value.MemberDefinition); var expectedOriginToken = new AssemblyQualifiedToken (expectedOriginMember); if (actualOriginToken.Equals (expectedOriginToken)) return true; diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs index 50442019768c01..5e9a63db86c054 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs @@ -129,11 +129,9 @@ protected virtual void AddLinkOptions (TestCaseSandbox sandbox, ManagedCompilati foreach (var inputReference in sandbox.InputDirectory.Files ()) { var ext = inputReference.ExtensionWithDot; if (ext == ".dll" || ext == ".exe") { - if (caseDefinedOptions.AssembliesAction.Contains (("link", inputReference.FileNameWithoutExtension))) { - builder.AddLinkAssembly (inputReference); - } else { - builder.AddReference (inputReference); - } + // It's important to add all assemblies as "link" assemblies since the default configuration + // is to run the compiler in multi-file mode which will not process anything which is just in the reference set. + builder.AddLinkAssembly (inputReference); } } var coreAction = caseDefinedOptions.TrimMode ?? "skip"; diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index bc1f1383c2966e..62db21d2232e23 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -91,7 +91,6 @@ struct JitInterfaceCallbacks CorInfoType (* getTypeForPrimitiveValueClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoType (* getTypeForPrimitiveNumericClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); bool (* canCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent); - bool (* areTypesEquivalent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); TypeCompareState (* compareTypesForCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass); TypeCompareState (* compareTypesForEquality)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); CORINFO_CLASS_HANDLE (* mergeClasses)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); @@ -166,7 +165,8 @@ struct JitInterfaceCallbacks bool (* canAccessFamily)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType); bool (* isRIDClassDomainID)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); unsigned (* getClassDomainID)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, void** ppIndirection); - bool (* getReadonlyStaticFieldValue)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); + bool (* getStaticFieldContent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); + bool (* getObjectContent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset); CORINFO_CLASS_HANDLE (* getStaticFieldCurrentClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, bool* pIsSpeculative); CORINFO_VARARGS_HANDLE (* getVarArgsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* pSig, void** ppIndirection); bool (* canGetVarArgsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* pSig); @@ -991,16 +991,6 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual bool areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - CorInfoExceptionClass* pException = nullptr; - bool temp = _callbacks->areTypesEquivalent(_thisHandle, &pException, cls1, cls2); - if (pException != nullptr) throw pException; - return temp; -} - virtual TypeCompareState compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) @@ -1702,7 +1692,7 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual bool getReadonlyStaticFieldValue( + virtual bool getStaticFieldContent( CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, @@ -1710,7 +1700,19 @@ class JitInterfaceWrapper : public ICorJitInfo bool ignoreMovableObjects) { CorInfoExceptionClass* pException = nullptr; - bool temp = _callbacks->getReadonlyStaticFieldValue(_thisHandle, &pException, field, buffer, bufferSize, valueOffset, ignoreMovableObjects); + bool temp = _callbacks->getStaticFieldContent(_thisHandle, &pException, field, buffer, bufferSize, valueOffset, ignoreMovableObjects); + if (pException != nullptr) throw pException; + return temp; +} + + virtual bool getObjectContent( + CORINFO_OBJECT_HANDLE obj, + uint8_t* buffer, + int bufferSize, + int valueOffset) +{ + CorInfoExceptionClass* pException = nullptr; + bool temp = _callbacks->getObjectContent(_thisHandle, &pException, obj, buffer, bufferSize, valueOffset); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs index a380db86080bc0..3e2d09aec92f8d 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs @@ -32,6 +32,8 @@ public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => _embeddedSignatureData; + public override bool HasEmbeddedSignatureData => _embeddedSignatureData != null; + public override bool IsStatic => throw new NotImplementedException(); public override bool IsInitOnly => throw new NotImplementedException(); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index f0798773428821..19a0600b3f582b 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -18,7 +18,6 @@ LWM(AllocPgoInstrumentationBySchema, DWORDLONG, Agnostic_AllocPgoInstrumentationBySchema) LWM(GetPgoInstrumentationResults, DWORDLONG, Agnostic_GetPgoInstrumentationResults) -LWM(AreTypesEquivalent, DLDL, DWORD) LWM(AsCorInfoType, DWORDLONG, DWORD) LWM(CanAccessClass, Agnostic_CanAccessClassIn, Agnostic_CanAccessClassOut) LWM(CanAccessFamily, DLDL, DWORD) @@ -81,7 +80,8 @@ LWM(GetDefaultEqualityComparerClass, DWORDLONG, DWORDLONG) LWM(GetDelegateCtor, Agnostic_GetDelegateCtorIn, Agnostic_GetDelegateCtorOut) LWM(GetEEInfo, DWORD, Agnostic_CORINFO_EE_INFO) LWM(GetEHinfo, DLD, Agnostic_CORINFO_EH_CLAUSE) -LWM(GetReadonlyStaticFieldValue, DLDDD, DD) +LWM(GetStaticFieldContent, DLDDD, DD) +LWM(GetObjectContent, DLDD, DD) LWM(GetStaticFieldCurrentClass, DLD, Agnostic_GetStaticFieldCurrentClass) LWM(GetFieldClass, DWORDLONG, DWORDLONG) LWM(GetFieldInClass, DLD, DWORDLONG) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 7680c8685fe8f8..469ff6f6d56d9e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -1201,6 +1201,8 @@ const char* CorJitFlagToString(CORJIT_FLAGS::CorJitFlag flag) return "CORJIT_FLAG_OSR"; case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_ALT_JIT: return "CORJIT_FLAG_ALT_JIT"; + case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED: + return "CORJIT_FLAG_FROZEN_ALLOC_ALLOWED"; case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_MAKEFINALCODE: return "CORJIT_FLAG_MAKEFINALCODE"; case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_READYTORUN: @@ -3727,10 +3729,10 @@ CORINFO_METHOD_HANDLE MethodContext::repEmbedMethodHandle(CORINFO_METHOD_HANDLE return (CORINFO_METHOD_HANDLE)value.B; } -void MethodContext::recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects, bool result) +void MethodContext::recGetStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects, bool result) { - if (GetReadonlyStaticFieldValue == nullptr) - GetReadonlyStaticFieldValue = new LightWeightMap(); + if (GetStaticFieldContent == nullptr) + GetStaticFieldContent = new LightWeightMap(); DLDDD key; ZeroMemory(&key, sizeof(key)); @@ -3741,21 +3743,21 @@ void MethodContext::recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, u DWORD tmpBuf = (DWORD)-1; if (buffer != nullptr && result) - tmpBuf = (DWORD)GetReadonlyStaticFieldValue->AddBuffer((uint8_t*)buffer, (uint32_t)bufferSize); + tmpBuf = (DWORD)GetStaticFieldContent->AddBuffer((uint8_t*)buffer, (uint32_t)bufferSize); DD value; value.A = (DWORD)result; value.B = (DWORD)tmpBuf; - GetReadonlyStaticFieldValue->Add(key, value); - DEBUG_REC(dmpGetReadonlyStaticFieldValue(key, value)); + GetStaticFieldContent->Add(key, value); + DEBUG_REC(dmpGetStaticFieldContent(key, value)); } -void MethodContext::dmpGetReadonlyStaticFieldValue(DLDDD key, DD value) +void MethodContext::dmpGetStaticFieldContent(DLDDD key, DD value) { - printf("GetReadonlyStaticFieldValue key fld-%016" PRIX64 " bufSize-%u, ignoremovable-%u, valOffset-%u result-%u", key.A, key.B, key.C, key.D, value.A); - GetReadonlyStaticFieldValue->Unlock(); + printf("GetStaticFieldContent key fld-%016" PRIX64 " bufSize-%u, ignoremovable-%u, valOffset-%u result-%u", key.A, key.B, key.C, key.D, value.A); + GetStaticFieldContent->Unlock(); } -bool MethodContext::repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) +bool MethodContext::repGetStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) { DLDDD key; ZeroMemory(&key, sizeof(key)); @@ -3764,12 +3766,59 @@ bool MethodContext::repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, u key.C = (DWORD)ignoreMovableObjects; key.D = (DWORD)valueOffset; - DD value = LookupByKeyOrMiss(GetReadonlyStaticFieldValue, key, ": key %016" PRIX64 "", key.A); + DD value = LookupByKeyOrMiss(GetStaticFieldContent, key, ": key %016" PRIX64 "", key.A); - DEBUG_REP(dmpGetReadonlyStaticFieldValue(key, value)); + DEBUG_REP(dmpGetStaticFieldContent(key, value)); if (buffer != nullptr && (bool)value.A) { - uint8_t* srcBuffer = (uint8_t*)GetReadonlyStaticFieldValue->GetBuffer(value.B); + uint8_t* srcBuffer = (uint8_t*)GetStaticFieldContent->GetBuffer(value.B); + Assert(srcBuffer != nullptr); + memcpy(buffer, srcBuffer, bufferSize); + } + return (bool)value.A; +} + +void MethodContext::recGetObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset, bool result) +{ + if (GetObjectContent == nullptr) + GetObjectContent = new LightWeightMap(); + + DLDD key; + ZeroMemory(&key, sizeof(key)); + key.A = CastHandle(obj); + key.B = (DWORD)bufferSize; + key.C = (DWORD)valueOffset; + + DWORD tmpBuf = (DWORD)-1; + if (buffer != nullptr && result) + tmpBuf = (DWORD)GetObjectContent->AddBuffer((uint8_t*)buffer, (uint32_t)bufferSize); + + DD value; + value.A = (DWORD)result; + value.B = (DWORD)tmpBuf; + + GetObjectContent->Add(key, value); + DEBUG_REC(dmpGetObjectContent(key, value)); +} +void MethodContext::dmpGetObjectContent(DLDD key, DD value) +{ + printf("GetObjectContent key fld-%016" PRIX64 " bufSize-%u, valOffset-%u result-%u", key.A, key.B, key.C, value.A); + GetObjectContent->Unlock(); +} +bool MethodContext::repGetObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset) +{ + DLDD key; + ZeroMemory(&key, sizeof(key)); + key.A = CastHandle(obj); + key.B = (DWORD)bufferSize; + key.C = (DWORD)valueOffset; + + DD value = LookupByKeyOrMiss(GetObjectContent, key, ": key %016" PRIX64 "", key.A); + + DEBUG_REP(dmpGetObjectContent(key, value)); + if (buffer != nullptr && (bool)value.A) + { + uint8_t* srcBuffer = (uint8_t*)GetObjectContent->GetBuffer(value.B); Assert(srcBuffer != nullptr); memcpy(buffer, srcBuffer, bufferSize); } @@ -6147,37 +6196,6 @@ CORINFO_FIELD_HANDLE MethodContext::repEmbedFieldHandle(CORINFO_FIELD_HANDLE han return (CORINFO_FIELD_HANDLE)value.B; } -void MethodContext::recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result) -{ - if (AreTypesEquivalent == nullptr) - AreTypesEquivalent = new LightWeightMap(); - - DLDL key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.A = CastHandle(cls1); - key.B = CastHandle(cls2); - - DWORD value = result ? 1 : 0; - AreTypesEquivalent->Add(key, value); - DEBUG_REC(dmpAreTypesEquivalent(key, value)); -} -void MethodContext::dmpAreTypesEquivalent(DLDL key, DWORD value) -{ - printf("AreTypesEquivalent NYI"); -} -bool MethodContext::repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) -{ - DLDL key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.A = CastHandle(cls1); - key.B = CastHandle(cls2); - - DWORD value = LookupByKeyOrMiss(AreTypesEquivalent, key, ": key %016" PRIX64 " %016" PRIX64 "", key.A, key.B); - - DEBUG_REP(dmpAreTypesEquivalent(key, value)); - return value != 0; -} - void MethodContext::recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass, TypeCompareState result) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 949d780b09089d..53b3b02f745eaa 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -497,9 +497,13 @@ class MethodContext void dmpEmbedMethodHandle(DWORDLONG key, DLDL value); CORINFO_METHOD_HANDLE repEmbedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection); - void recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects, bool result); - void dmpGetReadonlyStaticFieldValue(DLDDD key, DD value); - bool repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); + void recGetStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects, bool result); + void dmpGetStaticFieldContent(DLDDD key, DD value); + bool repGetStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); + + void recGetObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset, bool result); + void dmpGetObjectContent(DLDD key, DD value); + bool repGetObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset); void recGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative, CORINFO_CLASS_HANDLE result); void dmpGetStaticFieldCurrentClass(DLD key, const Agnostic_GetStaticFieldCurrentClass& value); @@ -773,10 +777,6 @@ class MethodContext void dmpEmbedFieldHandle(DWORDLONG key, DLDL value); CORINFO_FIELD_HANDLE repEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection); - void recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result); - void dmpAreTypesEquivalent(DLDL key, DWORD value); - bool repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); - void recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass, TypeCompareState result); void dmpCompareTypesForCast(DLDL key, DWORD value); TypeCompareState repCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass); @@ -982,7 +982,7 @@ class MethodContext enum mcPackets { - Packet_AreTypesEquivalent = 1, + //Packet_AreTypesEquivalent = 1, Packet_AsCorInfoType = 2, Packet_CanAccessClass = 3, Packet_CanAccessFamily = 4, @@ -1175,7 +1175,7 @@ enum mcPackets Packet_GetExactClasses = 195, Packet_GetRuntimeTypePointer = 196, Packet_PrintObjectDescription = 197, - Packet_GetReadonlyStaticFieldValue = 198, + Packet_GetStaticFieldContent = 198, Packet_GetObjectType = 199, Packet_IsObjectImmutable = 200, Packet_ExpandRawHandleIntrinsic = 201, @@ -1187,6 +1187,7 @@ enum mcPackets Packet_GetThreadLocalFieldInfo = 207, Packet_GetThreadLocalStaticBlocksInfo = 208, Packet_GetRISCV64PassStructInRegisterFlags = 209, + Packet_GetObjectContent = 210, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index c318a1a6481a46..96249dde36c0da 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -898,15 +898,6 @@ bool interceptor_ICJI::canCast(CORINFO_CLASS_HANDLE child, // subtype (extends p return temp; } -// TRUE if cls1 and cls2 are considered equivalent types. -bool interceptor_ICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) -{ - mc->cr->AddCall("areTypesEquivalent"); - bool temp = original_ICorJitInfo->areTypesEquivalent(cls1, cls2); - mc->recAreTypesEquivalent(cls1, cls2, temp); - return temp; -} - // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. TypeCompareState interceptor_ICJI::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) @@ -1743,11 +1734,19 @@ unsigned interceptor_ICJI::getClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppI return temp; } -bool interceptor_ICJI::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) +bool interceptor_ICJI::getStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) +{ + mc->cr->AddCall("getStaticFieldContent"); + bool result = original_ICorJitInfo->getStaticFieldContent(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); + mc->recGetStaticFieldContent(field, buffer, bufferSize, valueOffset, ignoreMovableObjects, result); + return result; +} + +bool interceptor_ICJI::getObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset) { - mc->cr->AddCall("getReadonlyStaticFieldValue"); - bool result = original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); - mc->recGetReadonlyStaticFieldValue(field, buffer, bufferSize, valueOffset, ignoreMovableObjects, result); + mc->cr->AddCall("getObjectContent"); + bool result = original_ICorJitInfo->getObjectContent(obj, buffer, bufferSize, valueOffset); + mc->recGetObjectContent(obj, buffer, bufferSize, valueOffset, result); return result; } diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index ab0c006b8c3ceb..58dc80abec8e1b 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -650,14 +650,6 @@ bool interceptor_ICJI::canCast( return original_ICorJitInfo->canCast(child, parent); } -bool interceptor_ICJI::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - mcs->AddCall("areTypesEquivalent"); - return original_ICorJitInfo->areTypesEquivalent(cls1, cls2); -} - TypeCompareState interceptor_ICJI::compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) @@ -1247,15 +1239,25 @@ unsigned interceptor_ICJI::getClassDomainID( return original_ICorJitInfo->getClassDomainID(cls, ppIndirection); } -bool interceptor_ICJI::getReadonlyStaticFieldValue( +bool interceptor_ICJI::getStaticFieldContent( CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) { - mcs->AddCall("getReadonlyStaticFieldValue"); - return original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); + mcs->AddCall("getStaticFieldContent"); + return original_ICorJitInfo->getStaticFieldContent(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); +} + +bool interceptor_ICJI::getObjectContent( + CORINFO_OBJECT_HANDLE obj, + uint8_t* buffer, + int bufferSize, + int valueOffset) +{ + mcs->AddCall("getObjectContent"); + return original_ICorJitInfo->getObjectContent(obj, buffer, bufferSize, valueOffset); } CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass( diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index d8e33021f62863..a9dced511ddce6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -570,13 +570,6 @@ bool interceptor_ICJI::canCast( return original_ICorJitInfo->canCast(child, parent); } -bool interceptor_ICJI::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - return original_ICorJitInfo->areTypesEquivalent(cls1, cls2); -} - TypeCompareState interceptor_ICJI::compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) @@ -1092,14 +1085,23 @@ unsigned interceptor_ICJI::getClassDomainID( return original_ICorJitInfo->getClassDomainID(cls, ppIndirection); } -bool interceptor_ICJI::getReadonlyStaticFieldValue( +bool interceptor_ICJI::getStaticFieldContent( CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) { - return original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); + return original_ICorJitInfo->getStaticFieldContent(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); +} + +bool interceptor_ICJI::getObjectContent( + CORINFO_OBJECT_HANDLE obj, + uint8_t* buffer, + int bufferSize, + int valueOffset) +{ + return original_ICorJitInfo->getObjectContent(obj, buffer, bufferSize, valueOffset); } CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 693ea2fe006735..9915b4699eeebc 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -759,13 +759,6 @@ bool MyICJI::canCast(CORINFO_CLASS_HANDLE child, // subtype (extends parent) return jitInstance->mc->repCanCast(child, parent); } -// TRUE if cls1 and cls2 are considered equivalent types. -bool MyICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) -{ - jitInstance->mc->cr->AddCall("areTypesEquivalent"); - return jitInstance->mc->repAreTypesEquivalent(cls1, cls2); -} - // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. TypeCompareState MyICJI::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) @@ -1515,10 +1508,16 @@ unsigned MyICJI::getClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection return jitInstance->mc->repGetClassDomainID(cls, ppIndirection); } -bool MyICJI::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) +bool MyICJI::getStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) +{ + jitInstance->mc->cr->AddCall("getStaticFieldContent"); + return jitInstance->mc->repGetStaticFieldContent(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); +} + +bool MyICJI::getObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset) { - jitInstance->mc->cr->AddCall("getReadonlyStaticFieldValue"); - return jitInstance->mc->repGetReadonlyStaticFieldValue(field, buffer, bufferSize, valueOffset, ignoreMovableObjects); + jitInstance->mc->cr->AddCall("getObjectContent"); + return jitInstance->mc->repGetObjectContent(obj, buffer, bufferSize, valueOffset); } // return the class handle for the current value of a static field diff --git a/src/coreclr/utilcode/log.cpp b/src/coreclr/utilcode/log.cpp index 79b9a9f50bdfd9..29c001f7d0e19b 100644 --- a/src/coreclr/utilcode/log.cpp +++ b/src/coreclr/utilcode/log.cpp @@ -327,8 +327,8 @@ VOID LogSpewAlwaysValist(const char *fmt, va_list args) needsPrefix = (fmt[strlen(fmt)-1] == '\n'); - int cCountWritten = _vsnprintf_s(&pBuffer[buflen], BUFFERSIZE-buflen, _TRUNCATE, fmt, args ); - pBuffer[BUFFERSIZE-1] = 0; + int cCountWritten = _vsnprintf_s(&pBuffer[buflen], BUFFERSIZE - buflen - 1, _TRUNCATE, fmt, args ); + pBuffer[BUFFERSIZE - 1] = 0; if (cCountWritten < 0) { buflen = BUFFERSIZE - 1; } else { diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index f9b466a19c8625..ec1e5b083fde69 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -545,6 +545,25 @@ void Module::SetDebuggerInfoBits(DebuggerAssemblyControlFlags newBits) } #ifndef DACCESS_COMPILE +static BOOL IsEditAndContinueCapable(Assembly *pAssembly, PEAssembly *pPEAssembly) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + SUPPORTS_DAC; + } + CONTRACTL_END; + + _ASSERTE(pAssembly != NULL && pPEAssembly != NULL); + + // Some modules are never EnC-capable + return ! (pAssembly->GetDebuggerInfoBits() & DACF_ALLOW_JIT_OPTS || + pPEAssembly->IsSystem() || + pPEAssembly->IsDynamic()); +} + /* static */ Module *Module::Create(Assembly *pAssembly, PEAssembly *pPEAssembly, AllocMemTracker *pamTracker) { @@ -566,7 +585,7 @@ Module *Module::Create(Assembly *pAssembly, PEAssembly *pPEAssembly, AllocMemTra // Create the module #ifdef EnC_SUPPORTED - if (IsEditAndContinueCapable(pAssembly, pPEAssembly)) + if (::IsEditAndContinueCapable(pAssembly, pPEAssembly)) { // if file is EnCCapable, always create an EnC-module, but EnC won't necessarily be enabled. // Debugger enables this by calling SetJITCompilerFlags on LoadModule callback. @@ -598,7 +617,7 @@ void Module::ApplyMetaData() } CONTRACTL_END; - LOG((LF_CLASSLOADER, LL_INFO100, "Module::ApplyNewMetaData %x\n", this)); + LOG((LF_CLASSLOADER, LL_INFO100, "Module::ApplyNewMetaData this:%p\n", this)); HRESULT hr = S_OK; ULONG ulCount; @@ -834,26 +853,6 @@ MethodTable *Module::GetGlobalMethodTable() #endif // !DACCESS_COMPILE -/*static*/ -BOOL Module::IsEditAndContinueCapable(Assembly *pAssembly, PEAssembly *pPEAssembly) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - _ASSERTE(pAssembly != NULL && pPEAssembly != NULL); - - // Some modules are never EnC-capable - return ! (pAssembly->GetDebuggerInfoBits() & DACF_ALLOW_JIT_OPTS || - pPEAssembly->IsSystem() || - pPEAssembly->IsDynamic()); -} - BOOL Module::IsManifest() { WRAPPER_NO_CONTRACT; @@ -5187,6 +5186,23 @@ void Module::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, } ECall::EnumFCallMethods(); + +#ifdef EnC_SUPPORTED + m_ClassList.EnumMemoryRegions(); + + DPTR(PTR_EnCEEClassData) classData = m_ClassList.Table(); + DPTR(PTR_EnCEEClassData) classLast = classData + m_ClassList.Count(); + + while (classData.IsValid() && classData < classLast) + { + if ((*classData).IsValid()) + { + (*classData)->EnumMemoryRegions(flags); + } + + classData++; + } +#endif // EnC_SUPPORTED } FieldDesc *Module::LookupFieldDef(mdFieldDef token) diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index b2a31352746e0f..a14916258ec7dd 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -62,12 +62,15 @@ class Module; class SString; class Pending; class MethodTable; -class AppDomain; class DynamicMethodTable; class CodeVersionManager; class TieredCompilationManager; class JITInlineTrackingMap; +#ifdef EnC_SUPPORTED +class EnCEEClassData; +#endif // EnC_SUPPORTED + // Hash table parameter of available classes (name -> module/class) hash #define AVAILABLE_CLASSES_HASH_BUCKETS 1024 #define AVAILABLE_CLASSES_HASH_BUCKETS_COLLECTIBLE 128 @@ -936,9 +939,12 @@ class Module : public ModuleBase BOOL IsPEFile() const { WRAPPER_NO_CONTRACT; return !GetPEAssembly()->IsDynamic(); } BOOL IsReflection() const { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; return GetPEAssembly()->IsDynamic(); } + BOOL IsSystem() { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; return m_pPEAssembly->IsSystem(); } // Returns true iff the debugger can see this module. BOOL IsVisibleToDebugger(); + virtual BOOL IsEditAndContinueCapable() const { return FALSE; } + BOOL IsEditAndContinueEnabled() { LIMITED_METHOD_CONTRACT; @@ -947,21 +953,22 @@ class Module : public ModuleBase return (m_dwTransientFlags & IS_EDIT_AND_CONTINUE) != 0; } - virtual BOOL IsEditAndContinueCapable() const { return FALSE; } - - BOOL IsSystem() { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; return m_pPEAssembly->IsSystem(); } - - static BOOL IsEditAndContinueCapable(Assembly *pAssembly, PEAssembly *file); +#ifdef EnC_SUPPORTED + // Holds a table of EnCEEClassData object for classes in this module that have been modified + CUnorderedArray m_ClassList; +#endif // EnC_SUPPORTED +private: void EnableEditAndContinue() { LIMITED_METHOD_CONTRACT; SUPPORTS_DAC; _ASSERTE(IsEditAndContinueCapable()); - LOG((LF_ENC, LL_INFO100, "EnableEditAndContinue: this:0x%x, %s\n", this, GetDebugName())); + LOG((LF_ENC, LL_INFO100, "M:EnableEditAndContinue: this:%p, %s\n", this, GetDebugName())); m_dwTransientFlags |= IS_EDIT_AND_CONTINUE; } +public: BOOL IsTenured() { LIMITED_METHOD_CONTRACT; diff --git a/src/coreclr/vm/class.cpp b/src/coreclr/vm/class.cpp index 4e8ca18fa09f6b..4a178e819b601c 100644 --- a/src/coreclr/vm/class.cpp +++ b/src/coreclr/vm/class.cpp @@ -84,12 +84,6 @@ void EEClass::Destruct(MethodTable * pOwningMT) } CONTRACTL_END - -#ifdef _DEBUG - _ASSERTE(!IsDestroyed()); - SetDestroyed(); -#endif - #ifdef PROFILING_SUPPORTED // If profiling, then notify the class is getting unloaded. { @@ -257,8 +251,7 @@ VOID EEClass::FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdField CONTRACTL { THROWS; - MODE_COOPERATIVE; - WRAPPER(GC_TRIGGERS); + GC_TRIGGERS; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -274,7 +267,7 @@ VOID EEClass::FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdField { szFieldName = "Invalid FieldDef record"; } - LOG((LF_ENC, LL_INFO100, "EEClass::FixupFieldDescForEnC %08x %s\n", fieldDef, szFieldName)); + LOG((LF_ENC, LL_INFO100, "EEClass::FixupFieldDescForEnC '%s' (0x%08x)\n", szFieldName, fieldDef)); } #endif //LOGGING @@ -291,17 +284,21 @@ VOID EEClass::FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdField // once this function is out of scope. ACQUIRE_STACKING_ALLOCATOR(pStackingAllocator); + // Collect the attributes for the field + mdToken fieldDefs[1] = { fieldDef }; + DWORD fieldAttrs[1]; + IfFailThrow(pImport->GetFieldDefProps(fieldDefs[0], &fieldAttrs[0])); + MethodTableBuilder::bmtMetaDataInfo bmtMetaData; - bmtMetaData.cFields = 1; - bmtMetaData.pFields = (mdToken*)_alloca(sizeof(mdToken)); - bmtMetaData.pFields[0] = fieldDef; - bmtMetaData.pFieldAttrs = (DWORD*)_alloca(sizeof(DWORD)); - IfFailThrow(pImport->GetFieldDefProps(fieldDef, &bmtMetaData.pFieldAttrs[0])); + bmtMetaData.cFields = ARRAY_SIZE(fieldDefs); + bmtMetaData.pFields = fieldDefs; + bmtMetaData.pFieldAttrs = fieldAttrs; - MethodTableBuilder::bmtMethAndFieldDescs bmtMFDescs; // We need to alloc the memory, but don't have to fill it in. InitializeFieldDescs // will copy pFD (1st arg) into here. - bmtMFDescs.ppFieldDescList = (FieldDesc**)_alloca(sizeof(FieldDesc*)); + FieldDesc* fieldDescs[1]; + MethodTableBuilder::bmtMethAndFieldDescs bmtMFDescs; + bmtMFDescs.ppFieldDescList = fieldDescs; MethodTableBuilder::bmtFieldPlacement bmtFP; @@ -329,37 +326,31 @@ VOID EEClass::FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdField } else { + _ASSERTE(!pMT->IsValueType()); bmtEnumFields.dwNumInstanceFields = 1; } // We shouldn't have to fill this in b/c we're not allowed to EnC value classes, or // anything else with layout info associated with it. - LayoutRawFieldInfo *pLayoutRawFieldInfos = (LayoutRawFieldInfo*)_alloca((2) * sizeof(LayoutRawFieldInfo)); + // Provide 2, 1 placeholder and 1 for the actual field - see BuildMethodTableThrowing(). + LayoutRawFieldInfo layoutRawFieldInfos[2]; // If not NULL, it means there are some by-value fields, and this contains an entry for each instance or static field, // which is NULL if not a by value field, and points to the EEClass of the field if a by value field. Instance fields // come first, statics come second. - MethodTable **pByValueClassCache = NULL; - - EEClass * pClass = pMT->GetClass(); - - // InitializeFieldDescs are going to change these numbers to something wrong, - // even though we already have the right numbers. Save & restore after. - WORD wNumInstanceFields = pMT->GetNumInstanceFields(); - WORD wNumStaticFields = pMT->GetNumStaticFields(); - unsigned totalDeclaredFieldSize = 0; + MethodTable** pByValueClassCache = NULL; AllocMemTracker dummyAmTracker; - BaseDomain * pDomain = pMT->GetDomain(); + EEClass* pClass = pMT->GetClass(); MethodTableBuilder builder(pMT, pClass, pStackingAllocator, &dummyAmTracker); + TypeHandle thisTH(pMT); + SigTypeContext typeContext(thisTH); MethodTableBuilder::bmtGenericsInfo genericsInfo; - - OBJECTREF pThrowable = NULL; - GCPROTECT_BEGIN(pThrowable); + genericsInfo.typeContext = typeContext; builder.SetBMTData(pMT->GetLoaderAllocator(), &bmtError, @@ -377,11 +368,11 @@ VOID EEClass::FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdField &genericsInfo, &bmtEnumFields); - EX_TRY { GCX_PREEMP(); + unsigned totalDeclaredFieldSize = 0; builder.InitializeFieldDescs(pFD, - pLayoutRawFieldInfos, + layoutRawFieldInfos, &bmtInternal, &genericsInfo, &bmtMetaData, @@ -392,29 +383,9 @@ VOID EEClass::FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdField &bmtFP, &totalDeclaredFieldSize); } - EX_CATCH_THROWABLE(&pThrowable); dummyAmTracker.SuppressRelease(); - // Restore now - pClass->SetNumInstanceFields(wNumInstanceFields); - pClass->SetNumStaticFields(wNumStaticFields); - - // PERF: For now, we turn off the fast equality check for valuetypes when a - // a field is modified by EnC. Consider doing a check and setting the bit only when - // necessary. - if (pMT->IsValueType()) - { - pClass->SetIsNotTightlyPacked(); - } - - if (pThrowable != NULL) - { - COMPlusThrow(pThrowable); - } - - GCPROTECT_END(); - pFD->SetMethodTable(pMT); // We set this when we first created the FieldDesc, but initializing the FieldDesc @@ -435,16 +406,19 @@ VOID EEClass::FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdField // Here we just create the FieldDesc and link it to the class. The actual storage will // be created lazily on demand. // -HRESULT EEClass::AddField(MethodTable * pMT, mdFieldDef fieldDef, EnCFieldDesc **ppNewFD) +HRESULT EEClass::AddField(MethodTable* pMT, mdFieldDef fieldDef, FieldDesc** ppNewFD) { CONTRACTL { THROWS; GC_NOTRIGGER; MODE_COOPERATIVE; + PRECONDITION(pMT != NULL); + PRECONDITION(ppNewFD != NULL); } CONTRACTL_END; + HRESULT hr; Module * pModule = pMT->GetModule(); IMDInternalImport *pImport = pModule->GetMDImport(); @@ -456,7 +430,7 @@ HRESULT EEClass::AddField(MethodTable * pMT, mdFieldDef fieldDef, EnCFieldDesc * { szFieldName = "Invalid FieldDef record"; } - LOG((LF_ENC, LL_INFO100, "EEClass::AddField %s\n", szFieldName)); + LOG((LF_ENC, LL_INFO100, "EEClass::AddField '%s' tok:0x%08x\n", szFieldName, fieldDef)); } #endif //LOGGING @@ -472,6 +446,101 @@ HRESULT EEClass::AddField(MethodTable * pMT, mdFieldDef fieldDef, EnCFieldDesc * DWORD dwFieldAttrs; IfFailThrow(pImport->GetFieldDefProps(fieldDef, &dwFieldAttrs)); + FieldDesc* pNewFD; + if (FAILED(hr = AddFieldDesc(pMT, fieldDef, dwFieldAttrs, &pNewFD))) + { + LOG((LF_ENC, LL_INFO100, "EEClass::AddField failed: 0x%08x\n", hr)); + return hr; + } + + // Store the FieldDesc into the module's field list + // This should not be done for instantiated types. Only fields on the + // open type are added to the module directly. This check is a + // consequence of calling AddField() for EnC static fields on generics. + if (!pMT->HasInstantiation()) + { + pModule->EnsureFieldDefCanBeStored(fieldDef); + pModule->EnsuredStoreFieldDef(fieldDef, pNewFD); + } + LOG((LF_ENC, LL_INFO100, "EEClass::AddField Added pFD:%p for token 0x%08x\n", + pNewFD, fieldDef)); + + // If the type is generic, then we need to update all existing instantiated types + if (pMT->IsGenericTypeDefinition()) + { + LOG((LF_ENC, LL_INFO100, "EEClass::AddField Looking for existing instantiations in all assemblies\n")); + + PTR_AppDomain pDomain = AppDomain::GetCurrentDomain(); + AppDomain::AssemblyIterator appIt = pDomain->IterateAssembliesEx((AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution)); + + bool isStaticField = !!pNewFD->IsStatic(); + CollectibleAssemblyHolder pDomainAssembly; + while (appIt.Next(pDomainAssembly.This()) && SUCCEEDED(hr)) + { + Module* pMod = pDomainAssembly->GetModule(); + LOG((LF_ENC, LL_INFO100, "EEClass::AddField Checking: %s mod:%p\n", pMod->GetDebugName(), pMod)); + + EETypeHashTable* paramTypes = pMod->GetAvailableParamTypes(); + EETypeHashTable::Iterator it(paramTypes); + EETypeHashEntry* pEntry; + while (paramTypes->FindNext(&it, &pEntry)) + { + TypeHandle th = pEntry->GetTypeHandle(); + if (th.IsTypeDesc()) + continue; + + // For instance fields we only update instantiations of the generic MethodTable we updated above. + // For static fields we update the the canonical version and instantiations. + MethodTable* pMTMaybe = th.AsMethodTable(); + if ((!isStaticField && !pMTMaybe->IsCanonicalMethodTable()) + || !pMT->HasSameTypeDefAs(pMTMaybe)) + { + continue; + } + + FieldDesc* pNewFDUnused; + if (FAILED(AddFieldDesc(pMTMaybe, fieldDef, dwFieldAttrs, &pNewFDUnused))) + { + LOG((LF_ENC, LL_INFO100, "EEClass::AddField failed: 0x%08x\n", hr)); + EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_FAILFAST, + W("Failed to add field to existing instantiated type instance")); + return E_FAIL; + } + } + } + } + + // Success, return the new FieldDesc + *ppNewFD = pNewFD; + + return S_OK; +} + +//--------------------------------------------------------------------------------------- +// +// AddFieldDesc - called when a new FieldDesc needs to be created and added for EnC +// +HRESULT EEClass::AddFieldDesc( + MethodTable* pMT, + mdMethodDef fieldDef, + DWORD dwFieldAttrs, + FieldDesc** ppNewFD) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + MODE_COOPERATIVE; + PRECONDITION(pMT != NULL); + PRECONDITION(ppNewFD != NULL); + } + CONTRACTL_END; + + LOG((LF_ENC, LL_INFO100, "EEClass::AddFieldDesc pMT:%p, %s <- tok:0x%08x attrs:%u\n", + pMT, pMT->debug_m_szClassName, fieldDef, dwFieldAttrs)); + + Module* pModule = pMT->GetModule(); + IMDInternalImport* pImport = pModule->GetMDImport(); LoaderAllocator* pAllocator = pMT->GetLoaderAllocator(); // Here we allocate a FieldDesc and set just enough info to be able to fix it up later @@ -489,26 +558,26 @@ HRESULT EEClass::AddField(MethodTable * pMT, mdFieldDef fieldDef, EnCFieldDesc * // Get the EnCEEClassData for this class // Don't adjust EEClass stats b/c EnC fields shouldn't touch EE data structures. // We'll just update our private EnC structures instead. - EnCEEClassData *pEnCClass = ((EditAndContinueModule*)pModule)->GetEnCEEClassData(pMT); - if (! pEnCClass) + _ASSERTE(pModule->IsEditAndContinueEnabled()); + EnCEEClassData* pEnCClass = ((EditAndContinueModule*)pModule)->GetEnCEEClassData(pMT); + if (!pEnCClass) return E_FAIL; // Add the field element to the list of added fields for this class pEnCClass->AddField(pAddedField); - - // Store the FieldDesc into the module's field list - { - CONTRACT_VIOLATION(ThrowsViolation); // B#25680 (Fix Enc violations): Must handle OOM's from Ensure - pModule->EnsureFieldDefCanBeStored(fieldDef); - } - pModule->EnsuredStoreFieldDef(fieldDef, pNewFD); pNewFD->SetMethodTable(pMT); + // Record that we are adding a new static field. Static generic fields + // are added for currently non-instantiated types during type construction. + // We want to limit the cost of making the check at that time so we use + // a bit on the EEClass to indicate we've added a static field and it should + // be checked. + if (IsFdStatic(dwFieldAttrs)) + pMT->GetClass()->SetHasEnCStaticFields(); + // Success, return the new FieldDesc - if (ppNewFD) - { - *ppNewFD = pNewFD; - } + *ppNewFD = pNewFD; + return S_OK; } @@ -517,20 +586,25 @@ HRESULT EEClass::AddField(MethodTable * pMT, mdFieldDef fieldDef, EnCFieldDesc * // AddMethod - called when a new method is added by EnC // // The method has already been added to the metadata with token methodDef. -// Create a new MethodDesc for the method. +// Create a new MethodDesc for the method, add to the associated EEClass and +// update any existing Generic instantiations if the MethodTable represents a +// generic type. // -HRESULT EEClass::AddMethod(MethodTable * pMT, mdMethodDef methodDef, RVA newRVA, MethodDesc **ppMethod) +HRESULT EEClass::AddMethod(MethodTable* pMT, mdMethodDef methodDef, MethodDesc** ppMethod) { CONTRACTL { THROWS; GC_NOTRIGGER; MODE_COOPERATIVE; + PRECONDITION(pMT != NULL); + PRECONDITION(methodDef != mdTokenNil); } CONTRACTL_END; - Module * pModule = pMT->GetModule(); - IMDInternalImport *pImport = pModule->GetMDImport(); + HRESULT hr; + Module* pModule = pMT->GetModule(); + IMDInternalImport* pImport = pModule->GetMDImport(); #ifdef LOGGING if (LoggingEnabled()) @@ -540,26 +614,23 @@ HRESULT EEClass::AddMethod(MethodTable * pMT, mdMethodDef methodDef, RVA newRVA, { szMethodName = "Invalid MethodDef record"; } - LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod %s\n", szMethodName)); + LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod '%s' tok:0x%08x\n", szMethodName, methodDef)); } #endif //LOGGING DWORD dwDescrOffset; DWORD dwImplFlags; - HRESULT hr = S_OK; - if (FAILED(pImport->GetMethodImplProps(methodDef, &dwDescrOffset, &dwImplFlags))) - { return COR_E_BADIMAGEFORMAT; - } DWORD dwMemberAttrs; - IfFailThrow(pImport->GetMethodDefProps(methodDef, &dwMemberAttrs)); + if (FAILED(pImport->GetMethodDefProps(methodDef, &dwMemberAttrs))) + return COR_E_BADIMAGEFORMAT; // Refuse to add other special cases - if (IsReallyMdPinvokeImpl(dwMemberAttrs) || - (pMT->IsInterface() && !IsMdStatic(dwMemberAttrs)) || - IsMiRuntime(dwImplFlags)) + if (IsReallyMdPinvokeImpl(dwMemberAttrs) + || (pMT->IsInterface() && !IsMdStatic(dwMemberAttrs)) + || IsMiRuntime(dwImplFlags)) { _ASSERTE(! "**Error** EEClass::AddMethod only IL private non-virtual methods are supported"); LOG((LF_ENC, LL_INFO100, "**Error** EEClass::AddMethod only IL private non-virtual methods are supported\n")); @@ -569,7 +640,7 @@ HRESULT EEClass::AddMethod(MethodTable * pMT, mdMethodDef methodDef, RVA newRVA, #ifdef _DEBUG // Validate that this methodDef correctly has a parent typeDef mdTypeDef parentTypeDef; - if (FAILED(hr = pImport->GetParentToken(methodDef, &parentTypeDef))) + if (FAILED(pImport->GetParentToken(methodDef, &parentTypeDef))) { _ASSERTE(! "**Error** EEClass::AddMethod parent token not found"); LOG((LF_ENC, LL_INFO100, "**Error** EEClass::AddMethod parent token not found\n")); @@ -577,75 +648,173 @@ HRESULT EEClass::AddMethod(MethodTable * pMT, mdMethodDef methodDef, RVA newRVA, } #endif // _DEBUG - EEClass * pClass = pMT->GetClass(); + MethodDesc* pNewMD; + if (FAILED(hr = AddMethodDesc(pMT, methodDef, dwImplFlags, dwMemberAttrs, &pNewMD))) + { + LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod failed: 0x%08x\n", hr)); + return hr; + } - // @todo: OOM: InitMethodDesc will allocate loaderheap memory but leak it - // on failure. This AllocMemTracker should be replaced with a real one. - AllocMemTracker dummyAmTracker; + // Store the new MethodDesc into the collection for this class + pModule->EnsureMethodDefCanBeStored(methodDef); + pModule->EnsuredStoreMethodDef(methodDef, pNewMD); + + LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod Added pMD:%p for token 0x%08x\n", + pNewMD, methodDef)); + + // If the type is generic, then we need to update all existing instantiated types + if (pMT->IsGenericTypeDefinition()) + { + LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod Looking for existing instantiations in all assemblies\n")); + + PTR_AppDomain pDomain = AppDomain::GetCurrentDomain(); + AppDomain::AssemblyIterator appIt = pDomain->IterateAssembliesEx((AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution)); + + CollectibleAssemblyHolder pDomainAssembly; + while (appIt.Next(pDomainAssembly.This()) && SUCCEEDED(hr)) + { + Module* pMod = pDomainAssembly->GetModule(); + LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod Checking: %s mod:%p\n", pMod->GetDebugName(), pMod)); + + EETypeHashTable* paramTypes = pMod->GetAvailableParamTypes(); + EETypeHashTable::Iterator it(paramTypes); + EETypeHashEntry* pEntry; + while (paramTypes->FindNext(&it, &pEntry)) + { + TypeHandle th = pEntry->GetTypeHandle(); + if (th.IsTypeDesc()) + continue; + + // Only update instantiations of the generic MethodTable we updated above. + MethodTable* pMTMaybe = th.AsMethodTable(); + if (!pMTMaybe->IsCanonicalMethodTable() || !pMT->HasSameTypeDefAs(pMTMaybe)) + { + continue; + } + + MethodDesc* pNewMDUnused; + if (FAILED(AddMethodDesc(pMTMaybe, methodDef, dwImplFlags, dwMemberAttrs, &pNewMDUnused))) + { + LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod failed: 0x%08x\n", hr)); + EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_FAILFAST, + W("Failed to add method to existing instantiated type instance")); + return E_FAIL; + } + } + } + } + + // Success - return the new MethodDesc + if (ppMethod) + *ppMethod = pNewMD; + + return S_OK; +} + +//--------------------------------------------------------------------------------------- +// +// AddMethodDesc - called when a new MethodDesc needs to be created and added for EnC +// +HRESULT EEClass::AddMethodDesc( + MethodTable* pMT, + mdMethodDef methodDef, + DWORD dwImplFlags, + DWORD dwMemberAttrs, + MethodDesc** ppNewMD) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + MODE_COOPERATIVE; + PRECONDITION(pMT != NULL); + PRECONDITION(methodDef != mdTokenNil); + PRECONDITION(ppNewMD != NULL); + } + CONTRACTL_END; + + LOG((LF_ENC, LL_INFO100, "EEClass::AddMethodDesc pMT:%p, %s <- tok:0x%08x flags:%u attrs:%u\n", + pMT, pMT->debug_m_szClassName, methodDef, dwImplFlags, dwMemberAttrs)); + + HRESULT hr; + Module* pModule = pMT->GetModule(); + IMDInternalImport* pImport = pModule->GetMDImport(); + + // Check if signature is generic. + ULONG sigLen; + PCCOR_SIGNATURE sig; + if (FAILED(hr = pImport->GetSigOfMethodDef(methodDef, &sigLen, &sig))) + return hr; + uint32_t callConv = CorSigUncompressData(sig); + DWORD classification = (callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) + ? mcInstantiated + : mcIL; LoaderAllocator* pAllocator = pMT->GetLoaderAllocator(); - DWORD classification = mcIL; + // [TODO] OOM: InitMethodDesc will allocate loaderheap memory but leak it + // on failure. This AllocMemTracker should be replaced with a real one. + AllocMemTracker dummyAmTracker; - // Create a new MethodDescChunk to hold the new MethodDesc - // Create the chunk somewhere we'll know is within range of the VTable + // Create a new MethodDescChunk to hold the new MethodDesc. + // Create the chunk somewhere we'll know is within range of the VTable. MethodDescChunk *pChunk = MethodDescChunk::CreateChunk(pAllocator->GetHighFrequencyHeap(), - 1, // methodDescCount - classification, - TRUE /* fNonVtableSlot */, - TRUE /* fNativeCodeSlot */, - pMT, - &dummyAmTracker); + 1, // methodDescCount + classification, + TRUE, // fNonVtableSlot + TRUE, // fNativeCodeSlot + pMT, + &dummyAmTracker); // Get the new MethodDesc (Note: The method desc memory is zero initialized) - MethodDesc *pNewMD = pChunk->GetFirstMethodDesc(); - + MethodDesc* pNewMD = pChunk->GetFirstMethodDesc(); - // Initialize the new MethodDesc + EEClass* pClass = pMT->GetClass(); - // This method runs on a debugger thread. Debugger threads do not have Thread object that caches StackingAllocator. - // Use a local StackingAllocator instead. + // This method runs on a debugger thread. Debugger threads do not have Thread object + // that caches StackingAllocator, use a local StackingAllocator instead. StackingAllocator stackingAllocator; MethodTableBuilder::bmtInternalInfo bmtInternal; - bmtInternal.pModule = pMT->GetModule(); + bmtInternal.pModule = pModule; bmtInternal.pInternalImport = NULL; bmtInternal.pParentMT = NULL; MethodTableBuilder builder(pMT, - pClass, - &stackingAllocator, - &dummyAmTracker); + pClass, + &stackingAllocator, + &dummyAmTracker); builder.SetBMTData(pMT->GetLoaderAllocator(), - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - &bmtInternal); + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &bmtInternal); + // Initialize the new MethodDesc EX_TRY { - INDEBUG(LPCSTR debug_szFieldName); - INDEBUG(if (FAILED(pImport->GetNameOfMethodDef(methodDef, &debug_szFieldName))) { debug_szFieldName = "Invalid MethodDef record"; }); + INDEBUG(LPCSTR debug_szMethodName); + INDEBUG(if (FAILED(pImport->GetNameOfMethodDef(methodDef, &debug_szMethodName))) { debug_szMethodName = "Invalid MethodDef record"; }); builder.InitMethodDesc(pNewMD, - classification, - methodDef, - dwImplFlags, - dwMemberAttrs, - TRUE, // fEnC - newRVA, - pImport, - NULL - COMMA_INDEBUG(debug_szFieldName) - COMMA_INDEBUG(pMT->GetDebugClassName()) - COMMA_INDEBUG(NULL) - ); + classification, + methodDef, + dwImplFlags, + dwMemberAttrs, + TRUE, // fEnC + 0, // RVA - non-zero only for NDirect + pImport, + NULL + COMMA_INDEBUG(debug_szMethodName) + COMMA_INDEBUG(pMT->GetDebugClassName()) + COMMA_INDEBUG(NULL) + ); pNewMD->SetTemporaryEntryPoint(pAllocator, &dummyAmTracker); @@ -665,18 +834,8 @@ HRESULT EEClass::AddMethod(MethodTable * pMT, mdMethodDef methodDef, RVA newRVA, pClass->AddChunk(pChunk); - // Store the new MethodDesc into the collection for this class - pModule->EnsureMethodDefCanBeStored(methodDef); - pModule->EnsuredStoreMethodDef(methodDef, pNewMD); - - LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod new methoddesc %p for token %p\n", pNewMD, methodDef)); + *ppNewMD = pNewMD; - // Success - return the new MethodDesc - _ASSERTE( SUCCEEDED(hr) ); - if (ppMethod) - { - *ppMethod = pNewMD; - } return S_OK; } @@ -936,6 +1095,81 @@ ClassLoader::LoadExactParentAndInterfacesTransitively(MethodTable *pMT) #endif //_DEBUG } // ClassLoader::LoadExactParentAndInterfacesTransitively +namespace +{ +#ifdef EnC_SUPPORTED + void CreateAllEnCStaticFields(MethodTable* pMT, MethodTable* pMTCanon, EditAndContinueModule* pModule) + { + CONTRACTL + { + STANDARD_VM_CHECK; + PRECONDITION(CheckPointer(pMT)); + PRECONDITION(pMT->HasInstantiation()); + PRECONDITION(CheckPointer(pMTCanon)); + PRECONDITION(pMTCanon->IsCanonicalMethodTable()); + PRECONDITION(CheckPointer(pModule)); + } + CONTRACTL_END; + + LOG((LF_ENC, LL_INFO100, "CreateAllEnCStaticFields: pMT:%p pMTCanon:%p\n", pMT, pMTCanon)); + +#ifdef _DEBUG + // Sanity check there is relevant EnC data. + EnCEEClassData* pEnCClass = pModule->GetEnCEEClassData(pMTCanon); + _ASSERTE(pEnCClass != NULL && pEnCClass->GetAddedStaticFields() > 0); +#endif // _DEBUG + + // Iterate over the Canonical MethodTable and see if there are any EnC static fields + // we need to add to the current MethodTable. + EncApproxFieldDescIterator canonFieldIter( + pMTCanon, + ApproxFieldDescIterator::STATIC_FIELDS, + (EncApproxFieldDescIterator::FixUpEncFields | EncApproxFieldDescIterator::OnlyEncFields)); + PTR_FieldDesc pCanonFD; + while ((pCanonFD = canonFieldIter.Next()) != NULL) + { + mdFieldDef canonTok = pCanonFD->GetMemberDef(); + + // Check if the current MethodTable already has an entry for + // this FieldDesc. + bool shouldAdd = true; + EncApproxFieldDescIterator mtFieldIter( + pMT, + ApproxFieldDescIterator::STATIC_FIELDS, + (EncApproxFieldDescIterator::FixUpEncFields | EncApproxFieldDescIterator::OnlyEncFields)); + PTR_FieldDesc pFD; + while ((pFD = mtFieldIter.Next()) != NULL) + { + mdFieldDef tok = pFD->GetMemberDef(); + if (tok == canonTok) + { + shouldAdd = false; + break; + } + } + + // The FieldDesc already exists, no need to add. + if (!shouldAdd) + continue; + + LOG((LF_ENC, LL_INFO100, "CreateAllEnCStaticFields: Must add pCanonFD:%p\n", pCanonFD)); + + { + GCX_COOP(); + PTR_FieldDesc pNewFD; + HRESULT hr = EEClass::AddField(pMT, canonTok, &pNewFD); + if (FAILED(hr)) + { + LOG((LF_ENC, LL_INFO100, "CreateAllEnCStaticFields failed: 0x%08x\n", hr)); + EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_FAILFAST, + W("Failed to add static field to instantiated type instance")); + } + } + } + } +#endif // EnC_SUPPORTED +} + // CLASS_LOAD_EXACTPARENTS phase of loading: // * Load the base class at exact instantiation // * Recurse LoadExactParents up parent hierarchy @@ -943,7 +1177,7 @@ ClassLoader::LoadExactParentAndInterfacesTransitively(MethodTable *pMT) // * Fixup vtable // /*static*/ -void ClassLoader::LoadExactParents(MethodTable *pMT) +void ClassLoader::LoadExactParents(MethodTable* pMT) { CONTRACT_VOID { @@ -966,6 +1200,23 @@ void ClassLoader::LoadExactParents(MethodTable *pMT) PropagateCovariantReturnMethodImplSlots(pMT); +#ifdef EnC_SUPPORTED + // Generics for EnC - create static FieldDescs. + // Instance FieldDescs don't need to be created here because they + // are added during type load by reading the updated metadata tables. + if (pMT->HasInstantiation()) + { + // Check if the MethodTable has any EnC static fields + PTR_MethodTable pMTCanon = pMT->GetCanonicalMethodTable(); + if (pMTCanon->GetClass()->HasEnCStaticFields()) + { + Module* pModule = pMT->GetModule(); + if (pModule->IsEditAndContinueEnabled()) + CreateAllEnCStaticFields(pMT, pMTCanon, (EditAndContinueModule*)pModule); + } + } +#endif // EnC_SUPPORTED + // We can now mark this type as having exact parents pMT->SetHasExactParent(); diff --git a/src/coreclr/vm/class.h b/src/coreclr/vm/class.h index 8515765826a483..fe2990b64d5ade 100644 --- a/src/coreclr/vm/class.h +++ b/src/coreclr/vm/class.h @@ -780,10 +780,24 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! #ifdef EnC_SUPPORTED // Add a new method to an already loaded type for EnC - static HRESULT AddMethod(MethodTable * pMT, mdMethodDef methodDef, RVA newRVA, MethodDesc **ppMethod); - + static HRESULT AddMethod(MethodTable* pMT, mdMethodDef methodDef, MethodDesc** ppMethod); +private: + static HRESULT AddMethodDesc( + MethodTable* pMT, + mdMethodDef methodDef, + DWORD dwImplFlags, + DWORD dwMemberAttrs, + MethodDesc** ppNewMD); +public: // Add a new field to an already loaded type for EnC - static HRESULT AddField(MethodTable * pMT, mdFieldDef fieldDesc, EnCFieldDesc **pAddedField); + static HRESULT AddField(MethodTable* pMT, mdFieldDef fieldDesc, FieldDesc** pAddedField); +private: + static HRESULT AddFieldDesc( + MethodTable* pMT, + mdMethodDef fieldDef, + DWORD dwFieldAttrs, + FieldDesc** ppNewFD); +public: static VOID FixupFieldDescForEnC(MethodTable * pMT, EnCFieldDesc *pFD, mdFieldDef fieldDef); #endif // EnC_SUPPORTED @@ -1182,14 +1196,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! return (m_VMFlags & VMFLAG_COVARIANTOVERRIDE); } -#ifdef _DEBUG - inline DWORD IsDestroyed() - { - LIMITED_METHOD_CONTRACT; - return (m_wAuxFlags & AUXFLAG_DESTROYED); - } -#endif - inline DWORD IsUnsafeValueClass() { LIMITED_METHOD_CONTRACT; @@ -1237,13 +1243,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! LIMITED_METHOD_CONTRACT; m_VMFlags |= VMFLAG_HAS_CUSTOM_FIELD_ALIGNMENT; } -#ifdef _DEBUG - inline void SetDestroyed() - { - LIMITED_METHOD_CONTRACT; - m_wAuxFlags |= AUXFLAG_DESTROYED; - } -#endif inline void SetHasFixedAddressVTStatics() { LIMITED_METHOD_CONTRACT; @@ -1320,6 +1319,19 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! m_VMFlags |= VMFLAG_DELEGATE; } +#ifdef EnC_SUPPORTED + inline BOOL HasEnCStaticFields() + { + LIMITED_METHOD_CONTRACT; + return m_VMFlags & VMFLAG_ENC_STATIC_FIELDS; + } + inline void SetHasEnCStaticFields() + { + LIMITED_METHOD_CONTRACT; + m_VMFlags |= VMFLAG_ENC_STATIC_FIELDS; + } +#endif // EnC_SUPPORTED + BOOL HasFixedAddressVTStatics() { LIMITED_METHOD_CONTRACT; @@ -1431,9 +1443,9 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! BOOL HasExplicitSize(); BOOL IsAutoLayoutOrHasAutoLayoutField(); - + // Only accurate on non-auto layout types - BOOL IsInt128OrHasInt128Fields(); + BOOL IsInt128OrHasInt128Fields(); static void GetBestFitMapping(MethodTable * pMT, BOOL *pfBestFitMapping, BOOL *pfThrowOnUnmappableChar); @@ -1664,13 +1676,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! SigPointer sp, CorGenericParamAttr position); -#if defined(_DEBUG) -public: - enum{ - AUXFLAG_DESTROYED = 0x00000008, // The Destruct() method has already been called on this class - }; -#endif // defined(_DEBUG) - //------------------------------------------------------------- // CONCRETE DATA LAYOUT // @@ -1691,7 +1696,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! // sets of flags - a full field is used. Please avoid adding such members if possible. //------------------------------------------------------------- - // @TODO: needed for asm code in cgenx86.cpp. Can this enum be private? // // Flags for m_VMFlags // @@ -1703,7 +1707,11 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! #endif VMFLAG_DELEGATE = 0x00000002, - // VMFLAG_UNUSED = 0x0000001c, +#ifdef EnC_SUPPORTED + VMFLAG_ENC_STATIC_FIELDS = 0x00000004, +#endif // EnC_SUPPORTED + + // VMFLAG_UNUSED = 0x00000018, VMFLAG_FIXED_ADDRESS_VT_STATICS = 0x00000020, // Value type Statics in this class will be pinned VMFLAG_HASLAYOUT = 0x00000040, @@ -2131,7 +2139,7 @@ inline BOOL EEClass::IsAutoLayoutOrHasAutoLayoutField() inline BOOL EEClass::IsInt128OrHasInt128Fields() { - // The name of this type is a slight misnomer as it doesn't detect Int128 fields on + // The name of this type is a slight misnomer as it doesn't detect Int128 fields on // auto layout types, but since we only need this for interop scenarios, it works out. LIMITED_METHOD_CONTRACT; // If this type is not auto @@ -2180,13 +2188,6 @@ PCODE TheVarargNDirectStub(BOOL hasRetBuffArg); #define METH_NAME_CACHE_SIZE 5 #define MAX_MISSES 3 -#ifdef EnC_SUPPORTED - -struct EnCAddedFieldElement; - -#endif // EnC_SUPPORTED - - // -------------------------------------------------------------------------------------------- // For generic instantiations the FieldDescs stored for instance // fields are approximate, not exact, i.e. they are representatives owned by diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index c9645202f07f8f..5be7e91f7e0622 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1433,6 +1433,9 @@ void EEJitManager::SetCpuInfo() // CORJIT_FLAG_USE_AVX_512DQ_VL if the following feature bit is set (input EAX of 0x07 and input ECX of 0): // CORJIT_FLAG_USE_AVX512F_VL // CORJIT_FLAG_USE_AVX_512DQ + // CORJIT_FLAG_USE_AVX_512VBMI if the following feature bit is set (input EAX of 0x07 and input ECX of 0): + // CORJIT_FLAG_USE_AVX512F + // AVX512VBMI - ECX bit 1 // CORJIT_FLAG_USE_BMI1 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): // BMI1 - EBX bit 3 // CORJIT_FLAG_USE_BMI2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): @@ -1554,10 +1557,20 @@ void EEJitManager::SetCpuInfo() CPUCompileFlags.Set(InstructionSet_AVX512DQ_VL); } } + + if ((cpuidInfo[CPUID_ECX] & (1 << 1)) != 0) // AVX512VBMI + { + CPUCompileFlags.Set(InstructionSet_AVX512VBMI); + if (isAVX512_VLSupported) // AVX512VBMI_VL + { + CPUCompileFlags.Set(InstructionSet_AVX512VBMI_VL); + } + } } } __cpuidex(cpuidInfo, 0x00000007, 0x00000001); + if ((cpuidInfo[CPUID_EAX] & (1 << 4)) != 0) // AVX-VNNI { CPUCompileFlags.Set(InstructionSet_AVXVNNI); @@ -1761,6 +1774,16 @@ void EEJitManager::SetCpuInfo() CPUCompileFlags.Clear(InstructionSet_AVX512DQ_VL); } + if (!CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableAVX512VBMI)) + { + CPUCompileFlags.Clear(InstructionSet_AVX512VBMI); + } + + if (!CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableAVX512VBMI_VL)) + { + CPUCompileFlags.Clear(InstructionSet_AVX512VBMI_VL); + } + if (!CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableAVXVNNI)) { CPUCompileFlags.Clear(InstructionSet_AVXVNNI); @@ -5076,7 +5099,7 @@ void ExecutionManager::AddCodeRange(TADDR pStartRange, } CONTRACTL_END; ReaderLockHolder rlh; - RangeSectionLockState lockState = RangeSectionLockState::ReaderLocked; // + RangeSectionLockState lockState = RangeSectionLockState::ReaderLocked; // PTR_RangeSection pRange = GetCodeRangeMap()->AllocateRange(Range(pStartRange, pEndRange), pJit, flags, pModule, &lockState); if (pRange == NULL) @@ -5100,7 +5123,7 @@ void ExecutionManager::AddCodeRange(TADDR pStartRange, } CONTRACTL_END; ReaderLockHolder rlh; - RangeSectionLockState lockState = RangeSectionLockState::ReaderLocked; // + RangeSectionLockState lockState = RangeSectionLockState::ReaderLocked; // PTR_RangeSection pRange = GetCodeRangeMap()->AllocateRange(Range(pStartRange, pEndRange), pJit, flags, pHp, &lockState); @@ -5125,7 +5148,7 @@ void ExecutionManager::AddCodeRange(TADDR pStartRange, } CONTRACTL_END; ReaderLockHolder rlh; - RangeSectionLockState lockState = RangeSectionLockState::ReaderLocked; // + RangeSectionLockState lockState = RangeSectionLockState::ReaderLocked; // PTR_RangeSection pRange = GetCodeRangeMap()->AllocateRange(Range(pStartRange, pEndRange), pJit, flags, pRangeList, &lockState); @@ -5157,7 +5180,7 @@ void ExecutionManager::DeleteRange(TADDR pStartRange) WriterLockHolder wlh; RangeSectionLockState lockState = RangeSectionLockState::WriteLocked; - + GetCodeRangeMap()->CleanupRangeSections(&lockState); // Unlike the previous implementation, we no longer attempt to avoid freeing // the memory behind the RangeSection here, as we do not support the hosting diff --git a/src/coreclr/vm/codeversion.cpp b/src/coreclr/vm/codeversion.cpp index 6a5db21db37f69..55fbb5cdd1e2ea 100644 --- a/src/coreclr/vm/codeversion.cpp +++ b/src/coreclr/vm/codeversion.cpp @@ -1955,10 +1955,7 @@ HRESULT CodeVersionManager::EnumerateClosedMethodDescs( return E_OUTOFMEMORY; } *ppMD = pMD; - } - if (!pMD->HasClassOrMethodInstantiation()) - { // not generic, we're done for this method return S_OK; } diff --git a/src/coreclr/vm/crst.cpp b/src/coreclr/vm/crst.cpp index ea4c3376c89cf5..3eacfc29f76a15 100644 --- a/src/coreclr/vm/crst.cpp +++ b/src/coreclr/vm/crst.cpp @@ -92,7 +92,7 @@ void CrstBase::Destroy() DeleteCriticalSection(&m_criticalsection); } - LOG((LF_SYNC, INFO3, "Deleting 0x%x\n", this)); + LOG((LF_SYNC, INFO3, "CrstBase::Destroy %p\n", this)); #ifdef _DEBUG DebugDestroy(); #endif @@ -616,7 +616,7 @@ void CrstBase::DebugInit(CrstType crstType, CrstFlags flags) // @todo - Any Crst w/ CRST_DEBUGGER_THREAD must be on a special blessed list. Check that here. - LOG((LF_SYNC, INFO3, "ConstructCrst with this:0x%x\n", this)); + LOG((LF_SYNC, INFO3, "CrstBase::DebugInit %p\n", this)); for (int i = 0; i < crstDebugInfoCount; i++) { diff --git a/src/coreclr/vm/eepolicy.cpp b/src/coreclr/vm/eepolicy.cpp index 35671c4f2ef03f..af27338544e861 100644 --- a/src/coreclr/vm/eepolicy.cpp +++ b/src/coreclr/vm/eepolicy.cpp @@ -612,14 +612,39 @@ void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pE if (pExceptionInfo && pExceptionInfo->ContextRecord) { GCX_COOP(); + CONTEXT *pExceptionContext = pExceptionInfo->ContextRecord; + #if defined(TARGET_X86) && defined(TARGET_WINDOWS) // For Windows x86, we don't have a reliable method to unwind to the first managed call frame, // so we handle at least the cases when the stack overflow happens in JIT helpers AdjustContextForJITHelpers(pExceptionInfo->ExceptionRecord, pExceptionInfo->ContextRecord); #else - Thread::VirtualUnwindToFirstManagedCallFrame(pExceptionInfo->ContextRecord); + // There are three possible kinds of locations where the stack overflow can happen: + // 1. In managed code + // 2. In native code with no explicit frame above the topmost managed frame + // 3. In native code with a explicit frame(s) above the topmost managed frame + // The FaultingExceptionFrame's context needs to point to the topmost managed code frame except for the case 3. + // In that case, it needs to point to the actual frame where the stack overflow happened, otherwise the stack + // walker would skip the explicit frame(s) and misbehave. + Thread *pThread = GetThreadNULLOk(); + if (pThread) + { + // Use the context in the FaultingExceptionFrame as a temporary store for unwinding to the first managed frame + CopyOSContext((&fef)->GetExceptionContext(), pExceptionInfo->ContextRecord); + Thread::VirtualUnwindToFirstManagedCallFrame((&fef)->GetExceptionContext()); + if (GetSP((&fef)->GetExceptionContext()) > (TADDR)pThread->GetFrame()) + { + // If the unwind has crossed any explicit frame, use the original exception context. + pExceptionContext = pExceptionInfo->ContextRecord; + } + else + { + // Otherwise use the first managed frame context. + pExceptionContext = (&fef)->GetExceptionContext(); + } + } #endif - fef.InitAndLink(pExceptionInfo->ContextRecord); + fef.InitAndLink(pExceptionContext); } static volatile LONG g_stackOverflowCallStackLogged = 0; diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 9b83cd39d92407..56500271314b57 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -15,6 +15,7 @@ #include "eeconfig.h" #include "excep.h" #include "stackwalk.h" +#include "methoditer.h" #ifdef DACCESS_COMPILE #include "../debug/daccess/gcinterface.dac.h" @@ -211,14 +212,14 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue( mdToken token; while (pIMDInternalImportENC->EnumNext(&enumENC, &token)) { - STRESS_LOG3(LF_ENC, LL_INFO100, "EACM::AEAC: updated token %08x; type %08x; rid %08x\n", token, TypeFromToken(token), RidFromToken(token)); + STRESS_LOG1(LF_ENC, LL_INFO100, "EACM::AEAC: updated token 0x%08x\n", token); switch (TypeFromToken(token)) { case mdtMethodDef: // MethodDef token - update/add a method - LOG((LF_ENC, LL_INFO10000, "EACM::AEAC: Found method %08x\n", token)); + LOG((LF_ENC, LL_INFO10000, "EACM::AEAC: Found method 0x%08x\n", token)); ULONG dwMethodRVA; DWORD dwMethodFlags; @@ -251,7 +252,7 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue( case mdtFieldDef: // FieldDef token - add a new field - LOG((LF_ENC, LL_INFO10000, "EACM::AEAC: Found field %08x\n", token)); + LOG((LF_ENC, LL_INFO10000, "EACM::AEAC: Found field 0x%08x\n", token)); if (LookupFieldDef(token)) { @@ -317,7 +318,8 @@ HRESULT EditAndContinueModule::UpdateMethod(MethodDesc *pMethod) // Notify the JIT that we've got new IL for this method // This will ensure that all new calls to the method will go to the new version. // The runtime does this by never backpatching the methodtable slots in EnC-enabled modules. - LOG((LF_ENC, LL_INFO100000, "EACM::UM: Updating function %s to version %d\n", pMethod->m_pszDebugMethodName, m_applyChangesCount)); + LOG((LF_ENC, LL_INFO100000, "EACM::UM: Updating function %s::%s to version %d\n", + pMethod->m_pszDebugClassName, pMethod->m_pszDebugMethodName, m_applyChangesCount)); // Reset any flags relevant to the old code // @@ -325,7 +327,30 @@ HRESULT EditAndContinueModule::UpdateMethod(MethodDesc *pMethod) // to the Method's code must be to the call/jmp blob immediately in front of the // MethodDesc itself. See MethodDesc::InEnCEnabledModule() // - pMethod->ResetCodeEntryPointForEnC(); + if (!pMethod->HasClassOrMethodInstantiation()) + { + // Not a method impacted by generics, so this is the MethodDesc to use. + pMethod->ResetCodeEntryPointForEnC(); + } + else + { + // Generics are involved so we need to search for all related MethodDescs. + Module* module = pMethod->GetLoaderModule(); + AppDomain* appDomain = module->GetDomain()->AsAppDomain(); + mdMethodDef tkMethod = pMethod->GetMemberDef(); + + LoadedMethodDescIterator it( + appDomain, + module, + tkMethod, + AssemblyIterationFlags(kIncludeLoaded | kIncludeExecution)); + CollectibleAssemblyHolder pDomainAssembly; + while (it.Next(pDomainAssembly.This())) + { + MethodDesc* pMD = it.Current(); + pMD->ResetCodeEntryPointForEnC(); + } + } return S_OK; } @@ -383,7 +408,7 @@ HRESULT EditAndContinueModule::AddMethod(mdMethodDef token) // Add the method to the runtime's Class data structures LOG((LF_ENC, LL_INFO100000, "EACM::AM: Adding function %08x to type %08x\n", token, parentTypeDef)); MethodDesc *pMethod = NULL; - hr = EEClass::AddMethod(pParentType, token, 0, &pMethod); + hr = EEClass::AddMethod(pParentType, token, &pMethod); if (FAILED(hr)) { @@ -439,7 +464,7 @@ HRESULT EditAndContinueModule::AddField(mdFieldDef token) if (FAILED(hr)) { - LOG((LF_ENC, LL_INFO100, "**Error** EnCModule::AF can't find parent token for field token %08x\n", token)); + LOG((LF_ENC, LL_INFO100, "**Error** EnCModule::AF can't find parent token for field token 0x%08x\n", token)); return E_FAIL; } @@ -451,18 +476,18 @@ HRESULT EditAndContinueModule::AddField(mdFieldDef token) MethodTable * pParentType = LookupTypeDef(parentTypeDef).AsMethodTable(); if (pParentType == NULL) { - LOG((LF_ENC, LL_INFO100, "EnCModule::AF class %08x not loaded (field %08x), our work is done\n", parentTypeDef, token)); + LOG((LF_ENC, LL_INFO100, "EnCModule::AF class 0x%08x not loaded (field 0x%08x), our work is done\n", parentTypeDef, token)); return S_OK; } - // Create a new EnCFieldDesc for the field and add it to the class - LOG((LF_ENC, LL_INFO100000, "EACM::AM: Adding field %08x to type %08x\n", token, parentTypeDef)); - EnCFieldDesc *pField; + // Create a new FieldDesc for the field and add it to the class + LOG((LF_ENC, LL_INFO100000, "EACM::AF: Adding field 0x%08x to type 0x%08x\n", token, parentTypeDef)); + FieldDesc *pField; hr = EEClass::AddField(pParentType, token, &pField); if (FAILED(hr)) { - LOG((LF_ENC, LL_INFO100000, "**Error** EACM::AF: Failed to add field %08x to EE with hr %08x\n", token, hr)); + LOG((LF_ENC, LL_INFO100000, "**Error** EACM::AF: Failed to add field 0x%08x to EE with hr 0x%08x\n", token, hr)); return hr; } @@ -508,8 +533,8 @@ PCODE EditAndContinueModule::JitUpdatedFunction( MethodDesc *pMD, } CONTRACTL_END; - LOG((LF_ENC, LL_INFO100, "EnCModule::JitUpdatedFunction for %s\n", - pMD->m_pszDebugMethodName)); + LOG((LF_ENC, LL_INFO100, "EnCModule::JitUpdatedFunction for %s::%s\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); PCODE jittedCode = NULL; @@ -543,15 +568,15 @@ PCODE EditAndContinueModule::JitUpdatedFunction( MethodDesc *pMD, // get the code address (may jit the fcn if not already jitted) EX_TRY { - if (!pMD->IsPointingToNativeCode()) + if (pMD->IsPointingToNativeCode()) { - GCX_PREEMP(); - pMD->DoPrestub(NULL); - LOG((LF_ENC, LL_INFO100, "EnCModule::ResumeInUpdatedFunction JIT successful\n")); + LOG((LF_ENC, LL_INFO100, "EnCModule::ResumeInUpdatedFunction %p already JITed\n", pMD)); } else { - LOG((LF_ENC, LL_INFO100, "EnCModule::ResumeInUpdatedFunction function already JITed\n")); + GCX_PREEMP(); + pMD->DoPrestub(NULL); + LOG((LF_ENC, LL_INFO100, "EnCModule::ResumeInUpdatedFunction JIT of %p successful\n", pMD)); } jittedCode = pMD->GetNativeCode(); } EX_CATCH { @@ -611,8 +636,8 @@ HRESULT EditAndContinueModule::ResumeInUpdatedFunction( #if defined(TARGET_ARM) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) return E_NOTIMPL; #else - LOG((LF_ENC, LL_INFO100, "EnCModule::ResumeInUpdatedFunction for %s at IL offset 0x%x, ", - pMD->m_pszDebugMethodName, newILOffset)); + LOG((LF_ENC, LL_INFO100, "EnCModule::ResumeInUpdatedFunction for %s::%s at IL offset 0x%zx\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, newILOffset)); #ifdef _DEBUG BOOL shouldBreak = CLRConfig::GetConfigValue( @@ -622,8 +647,6 @@ HRESULT EditAndContinueModule::ResumeInUpdatedFunction( } #endif - HRESULT hr = E_FAIL; - // JIT-compile the updated version of the method PCODE jittedCode = JitUpdatedFunction(pMD, pOrigContext); if ( jittedCode == NULL ) @@ -706,12 +729,10 @@ HRESULT EditAndContinueModule::ResumeInUpdatedFunction( LOG((LF_ENC, LL_ERROR, "**Error** EnCModule::ResumeInUpdatedFunction returned from ResumeAtJit")); _ASSERTE(!"Should not return from FixContextAndResume()"); - hr = E_FAIL; - // If we fail for any reason we have already potentially trashed with new locals and we have also unwound any // Win32 handlers on the stack so cannot ever return from this function. EEPOLICY_HANDLE_FATAL_ERROR(CORDBG_E_ENC_INTERNAL_ERROR); - return hr; + return E_FAIL; #endif // #if defined(TARGET_ARM) || defined(TARGET_LOONGARCH64) } @@ -1015,8 +1036,9 @@ PTR_EnCEEClassData EditAndContinueModule::GetEnCEEClassData(MethodTable * pMT, B _ASSERTE(getOnly == TRUE); #endif // DACCESS_COMPILE - DPTR(PTR_EnCEEClassData) ppData = m_ClassList.Table(); - DPTR(PTR_EnCEEClassData) ppLast = ppData + m_ClassList.Count(); + Module* loaderModule = pMT->GetLoaderModule(); + DPTR(PTR_EnCEEClassData) ppData = loaderModule->m_ClassList.Table(); + DPTR(PTR_EnCEEClassData) ppLast = ppData + loaderModule->m_ClassList.Count(); // Look for an existing entry for the specified class while (ppData < ppLast) @@ -1037,7 +1059,7 @@ PTR_EnCEEClassData EditAndContinueModule::GetEnCEEClassData(MethodTable * pMT, B // Create a new entry and add it to the end our our table EnCEEClassData *pNewData = (EnCEEClassData*)(void*)pMT->GetLoaderAllocator()->GetLowFrequencyHeap()->AllocMem_NoThrow(S_SIZE_T(sizeof(EnCEEClassData))); pNewData->Init(pMT); - ppData = m_ClassList.Append(); + ppData = loaderModule->m_ClassList.Append(); if (!ppData) return NULL; *ppData = pNewData; @@ -1604,36 +1626,6 @@ EnCEEClassData::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) elt = elt->m_next; } } - -void -EditAndContinueModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, - bool enumThis) -{ - SUPPORTS_DAC; - - if (enumThis) - { - DAC_ENUM_VTHIS(); - } - - Module::EnumMemoryRegions(flags, false); - - m_ClassList.EnumMemoryRegions(); - - DPTR(PTR_EnCEEClassData) classData = m_ClassList.Table(); - DPTR(PTR_EnCEEClassData) classLast = classData + m_ClassList.Count(); - - while (classData.IsValid() && classData < classLast) - { - if ((*classData).IsValid()) - { - (*classData)->EnumMemoryRegions(flags); - } - - classData++; - } -} - #endif // #ifdef DACCESS_COMPILE @@ -1644,12 +1636,12 @@ EditAndContinueModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, // pMT - MethodTable indicating the type of interest // iteratorType - one of the ApproxFieldDescIterator::IteratorType values specifying which fields // are of interest. -// fixupEnC - if true, then any partially-initialized EnC FieldDescs will be fixed up to be complete -// initialized FieldDescs as they are returned by Next(). This may load types and do -// other things to trigger a GC. +// flags - See EncApproxFieldDescIterator::Flags. // -EncApproxFieldDescIterator::EncApproxFieldDescIterator(MethodTable *pMT, int iteratorType, BOOL fixupEnC) : - m_nonEnCIter( pMT, iteratorType ) +EncApproxFieldDescIterator::EncApproxFieldDescIterator(MethodTable *pMT, int iteratorType, uint32_t flags) + : m_nonEnCIter( pMT, iteratorType ) + , m_flags( flags ) + , m_encFieldsReturned( 0 ) { CONTRACTL { @@ -1659,22 +1651,19 @@ EncApproxFieldDescIterator::EncApproxFieldDescIterator(MethodTable *pMT, int ite } CONTRACTL_END - m_fixupEnC = fixupEnC; - #ifndef DACCESS_COMPILE // can't fixup for EnC on the debugger thread - _ASSERTE((g_pDebugInterface->GetRCThreadId() != GetCurrentThreadId()) || fixupEnC == FALSE); + _ASSERTE((g_pDebugInterface->GetRCThreadId() != GetCurrentThreadId()) || !(m_flags & FixUpEncFields)); #endif m_pCurrListElem = NULL; m_encClassData = NULL; - m_encFieldsReturned = 0; // If this is an EnC module, then grab a pointer to the EnC data if( pMT->GetModule()->IsEditAndContinueEnabled() ) { PTR_EditAndContinueModule encMod = PTR_EditAndContinueModule(pMT->GetModule()); - m_encClassData = encMod->GetEnCEEClassData( pMT, TRUE); + m_encClassData = encMod->GetEnCEEClassData(pMT, TRUE /* getOnly */); } } @@ -1684,14 +1673,15 @@ PTR_FieldDesc EncApproxFieldDescIterator::Next() CONTRACTL { NOTHROW; - if (m_fixupEnC) {GC_TRIGGERS;} else {GC_NOTRIGGER;} + if (m_flags & FixUpEncFields) {GC_TRIGGERS;} else {GC_NOTRIGGER;} FORBID_FAULT; SUPPORTS_DAC; } CONTRACTL_END - // If we still have non-EnC fields to look at, return one of them - if( m_nonEnCIter.CountRemaining() > 0 ) + // If we still have non-EnC fields to look at and the caller didn't + // request only EnC fields, return one of them + if ( !(m_flags & OnlyEncFields) && m_nonEnCIter.CountRemaining() > 0 ) { _ASSERTE( m_encFieldsReturned == 0 ); return m_nonEnCIter.Next(); @@ -1699,7 +1689,7 @@ PTR_FieldDesc EncApproxFieldDescIterator::Next() // Get the next EnC field Desc if any PTR_EnCFieldDesc pFD = NextEnC(); - if( pFD == NULL ) + if ( pFD == NULL ) { // No more fields return NULL; @@ -1707,7 +1697,7 @@ PTR_FieldDesc EncApproxFieldDescIterator::Next() #ifndef DACCESS_COMPILE // Fixup the fieldDesc if requested and necessary - if ( m_fixupEnC && (pFD->NeedsFixup()) ) + if ((m_flags & FixUpEncFields) && (pFD->NeedsFixup())) { // if we get an OOM during fixup, the field will just not get fixed up EX_TRY @@ -1745,7 +1735,11 @@ int EncApproxFieldDescIterator::Count() } CONTRACTL_END - int count = m_nonEnCIter.Count(); + int count = 0; + + // Check if the caller is only interested in EnC FieldDescs. + if (!(m_flags & OnlyEncFields)) + count = m_nonEnCIter.Count(); // If this module doesn't have any EnC data then there aren't any EnC fields if (m_encClassData == NULL) diff --git a/src/coreclr/vm/encee.h b/src/coreclr/vm/encee.h index bb18c99ec465a9..ae3ed4a0158be7 100644 --- a/src/coreclr/vm/encee.h +++ b/src/coreclr/vm/encee.h @@ -63,7 +63,7 @@ class EnCFieldDesc : public FieldDesc VOID Fixup(mdFieldDef token) { WRAPPER_NO_CONTRACT; - EEClass::FixupFieldDescForEnC(GetEnclosingMethodTable(), this, token); + EEClass::FixupFieldDescForEnC(GetApproxEnclosingMethodTable(), this, token); m_bNeedsFixup = FALSE; } @@ -195,9 +195,6 @@ class EditAndContinueModule : public Module // function itself has been edited. int m_applyChangesCount; - // Holds a table of EnCEEClassData object for classes in this module that have been modified - CUnorderedArray m_ClassList; - #ifndef DACCESS_COMPILE // Return the minimum permissable address for new IL to be stored at // This can't be less than the current load address because then we'd @@ -266,7 +263,6 @@ class EditAndContinueModule : public Module PTR_CBYTE ResolveOrAllocateField(OBJECTREF thisPointer, EnCFieldDesc * pFD); - // Get class-specific EnC data for a class in this module // Note: For DAC build, getOnly must be TRUE PTR_EnCEEClassData GetEnCEEClassData(MethodTable * pMT, BOOL getOnly = FALSE); @@ -276,11 +272,6 @@ class EditAndContinueModule : public Module { return m_applyChangesCount; } - -#ifdef DACCESS_COMPILE - virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags, - bool enumThis); -#endif }; // Information about an instance field value added by EnC @@ -397,12 +388,26 @@ class EnCSyncBlockInfo // ApproxFieldDescIterator because none of our clients need it. But it would // be easy to add this using the data from m_classData // -class EncApproxFieldDescIterator +class EncApproxFieldDescIterator final { public: + enum Flags + { + None, + + // If set, then any partially-initialized EnC FieldDescs will be fixed up + // to be a completely initialized FieldDescs as they are returned by Next(). + // This may load types and do other things to trigger a GC. + // If an EnC FieldDesc is not fixed up, an assert will fire prior to return. + FixUpEncFields, + + // Only iterate over EnC FieldDescs + OnlyEncFields, + }; + #ifdef EnC_SUPPORTED // Create and initialize the iterator - EncApproxFieldDescIterator(MethodTable *pMT, int iteratorType, BOOL fixupEnC); + EncApproxFieldDescIterator(MethodTable *pMT, int iteratorType, uint32_t flags = None); // Get the next fieldDesc (either EnC or non-EnC) PTR_FieldDesc Next(); @@ -410,7 +415,7 @@ class EncApproxFieldDescIterator int Count(); #else // Non-EnC version - simple wrapper - EncApproxFieldDescIterator(MethodTable *pMT, int iteratorType, BOOL fixupEnC) : + EncApproxFieldDescIterator(MethodTable *pMT, int iteratorType, uint32_t flags = None) : m_nonEnCIter( pMT, iteratorType ) {} PTR_FieldDesc Next() { WRAPPER_NO_CONTRACT; return m_nonEnCIter.Next(); } @@ -434,11 +439,10 @@ class EncApproxFieldDescIterator // Return the next available EnC FieldDesc or NULL when done PTR_EnCFieldDesc NextEnC(); - // True if our client wants us to fixup any EnC fieldDescs before handing them back - BOOL m_fixupEnC; + uint32_t m_flags; // A count of how many EnC fields have been returned so far - int m_encFieldsReturned; + int32_t m_encFieldsReturned; // The current pointer into one of the EnC field lists when enumerating EnC fields PTR_EnCAddedFieldElement m_pCurrListElem; diff --git a/src/coreclr/vm/field.h b/src/coreclr/vm/field.h index 8e4f8539a3d138..5297c7b24ef483 100644 --- a/src/coreclr/vm/field.h +++ b/src/coreclr/vm/field.h @@ -334,7 +334,7 @@ class FieldDesc void* GetInstanceAddress(OBJECTREF o); - // Get the address of a field within object 'o' + // Get the address of a field within object 'o' PTR_VOID GetAddress(PTR_VOID o); PTR_VOID GetAddressNoThrowNoGC(PTR_VOID o); diff --git a/src/coreclr/vm/frozenobjectheap.cpp b/src/coreclr/vm/frozenobjectheap.cpp index e11ade341649cb..45492155d2089c 100644 --- a/src/coreclr/vm/frozenobjectheap.cpp +++ b/src/coreclr/vm/frozenobjectheap.cpp @@ -39,6 +39,9 @@ Object* FrozenObjectHeapManager::TryAllocateObject(PTR_MethodTable type, size_t _ASSERT(type != nullptr); _ASSERT(FOH_COMMIT_SIZE >= MIN_OBJECT_SIZE); + // Currently we don't support frozen objects with special alignment requirements + // TODO: We should also give up on arrays of doubles on 32-bit platforms. + // (we currently never allocate them on frozen segments) #ifdef FEATURE_64BIT_ALIGNMENT if (type->RequiresAlign8()) { @@ -161,6 +164,7 @@ Object* FrozenObjectSegment::TryAllocateObject(PTR_MethodTable type, size_t obje { _ASSERT(m_pStart != nullptr && m_Size > 0 && m_SegmentHandle != nullptr); // Expected to be inited _ASSERT(IS_ALIGNED(m_pCurrent, DATA_ALIGNMENT)); + _ASSERT(IS_ALIGNED(objectSize, DATA_ALIGNMENT)); _ASSERT(objectSize <= FOH_COMMIT_SIZE); _ASSERT(m_pCurrent >= m_pStart + sizeof(ObjHeader)); @@ -202,3 +206,30 @@ Object* FrozenObjectSegment::TryAllocateObject(PTR_MethodTable type, size_t obje return object; } + +Object* FrozenObjectSegment::GetFirstObject() const +{ + if (m_pStart + sizeof(ObjHeader) == m_pCurrent) + { + // Segment is empty + return nullptr; + } + return reinterpret_cast(m_pStart + sizeof(ObjHeader)); +} + +Object* FrozenObjectSegment::GetNextObject(Object* obj) const +{ + // Input must not be null and should be within the segment + _ASSERT(obj != nullptr); + _ASSERT((uint8_t*)obj >= m_pStart + sizeof(ObjHeader) && (uint8_t*)obj < m_pCurrent); + + // FOH doesn't support objects with non-DATA_ALIGNMENT alignment yet. + uint8_t* nextObj = (reinterpret_cast(obj) + ALIGN_UP(obj->GetSize(), DATA_ALIGNMENT)); + if (nextObj < m_pCurrent) + { + return reinterpret_cast(nextObj); + } + + // Current object is the last one in the segment + return nullptr; +} diff --git a/src/coreclr/vm/frozenobjectheap.h b/src/coreclr/vm/frozenobjectheap.h index f62d37678a7850..d2c0bb62f134af 100644 --- a/src/coreclr/vm/frozenobjectheap.h +++ b/src/coreclr/vm/frozenobjectheap.h @@ -33,6 +33,9 @@ class FrozenObjectHeapManager Crst m_Crst; SArray m_FrozenSegments; FrozenObjectSegment* m_CurrentSegment; + + friend class ProfilerObjectEnum; + friend class ProfToEEInterfaceImpl; }; class FrozenObjectSegment @@ -40,13 +43,15 @@ class FrozenObjectSegment public: FrozenObjectSegment(size_t sizeHint); Object* TryAllocateObject(PTR_MethodTable type, size_t objectSize); - size_t GetSize() const { return m_Size; } private: + Object* GetFirstObject() const; + Object* GetNextObject(Object* obj) const; + // Start of the reserved memory, the first object starts at "m_pStart + sizeof(ObjHeader)" (its pMT) uint8_t* m_pStart; @@ -66,6 +71,9 @@ class FrozenObjectSegment segment_handle m_SegmentHandle; INDEBUG(size_t m_ObjectsCount); + + friend class ProfilerObjectEnum; + friend class ProfToEEInterfaceImpl; }; #endif // _FROZENOBJECTHEAP_H diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index cccf11914aad29..e3c882f623b244 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -493,6 +493,83 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS return ObjectToOBJECTREF((Object*)orArray); } +OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) +{ + CONTRACTL{ + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } CONTRACTL_END; + + SetTypeHandleOnThreadForAlloc(TypeHandle(pArrayMT)); + + _ASSERTE(pArrayMT->CheckInstanceActivated()); + _ASSERTE(pArrayMT->GetInternalCorElementType() == ELEMENT_TYPE_SZARRAY); + + // The initial validation is copied from AllocateSzArray impl + + CorElementType elemType = pArrayMT->GetArrayElementType(); + + if (pArrayMT->ContainsPointers() && cElements > 0) + { + // For arrays with GC pointers we can only work with empty arrays + return NULL; + } + + // Disallow the creation of void[] (an array of System.Void) + if (elemType == ELEMENT_TYPE_VOID) + COMPlusThrow(kArgumentException); + + if (cElements < 0) + COMPlusThrow(kOverflowException); + + if ((SIZE_T)cElements > MaxArrayLength()) + ThrowOutOfMemoryDimensionsExceeded(); + + SIZE_T componentSize = pArrayMT->GetComponentSize(); +#ifdef TARGET_64BIT + // POSITIVE_INT32 * UINT16 + SMALL_CONST + // this cannot overflow on 64bit + size_t totalSize = cElements * componentSize + pArrayMT->GetBaseSize(); + +#else + S_SIZE_T safeTotalSize = S_SIZE_T((DWORD)cElements) * S_SIZE_T((DWORD)componentSize) + S_SIZE_T((DWORD)pArrayMT->GetBaseSize()); + if (safeTotalSize.IsOverflow()) + ThrowOutOfMemoryDimensionsExceeded(); + + size_t totalSize = safeTotalSize.Value(); +#endif + + // FrozenObjectHeapManager doesn't yet support objects with a custom alignment, + // so we give up on arrays of value types requiring 8 byte alignment on 32bit platforms. + if ((DATA_ALIGNMENT < sizeof(double)) && (elemType == ELEMENT_TYPE_R8)) + { + return NULL; + } +#ifdef FEATURE_64BIT_ALIGNMENT + MethodTable* pElementMT = pArrayMT->GetArrayElementTypeHandle().GetMethodTable(); + if (pElementMT->RequiresAlign8() && pElementMT->IsValueType()) + { + return NULL; + } +#endif + + FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); + ArrayBase* orArray = static_cast(foh->TryAllocateObject(pArrayMT, PtrAlign(totalSize), /*publish*/ false)); + if (orArray == nullptr) + { + // We failed to allocate on a frozen segment, fallback to AllocateSzArray + // E.g. if the array is too big to fit on a frozen segment + return NULL; + } + orArray->m_NumComponents = cElements; + + // Publish needs to be postponed in this case because we need to specify array length + PublishObjectAndNotify(orArray, GC_ALLOC_NO_FLAGS); + + return ObjectToOBJECTREF(orArray); +} + void ThrowOutOfMemoryDimensionsExceeded() { CONTRACTL { @@ -1036,6 +1113,37 @@ OBJECTREF AllocateObject(MethodTable *pMT return UNCHECKED_OBJECTREF_TO_OBJECTREF(oref); } +OBJECTREF TryAllocateFrozenObject(MethodTable* pObjMT) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(pObjMT)); + PRECONDITION(pObjMT->CheckInstanceActivated()); + } CONTRACTL_END; + + SetTypeHandleOnThreadForAlloc(TypeHandle(pObjMT)); + + if (pObjMT->ContainsPointers() || pObjMT->IsComObjectType()) + { + return NULL; + } + +#ifdef FEATURE_64BIT_ALIGNMENT + if (pObjMT->RequiresAlign8()) + { + // Custom alignment is not supported for frozen objects yet. + return NULL; + } +#endif // FEATURE_64BIT_ALIGNMENT + + FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); + Object* orObject = foh->TryAllocateObject(pObjMT, PtrAlign(pObjMT->GetBaseSize()), /*publish*/ true); + + return ObjectToOBJECTREF(orObject); +} + //======================================================================== // // WRITE BARRIER HELPERS diff --git a/src/coreclr/vm/gchelpers.h b/src/coreclr/vm/gchelpers.h index 3a0382f6f6bb6f..3528ef8bb47b43 100644 --- a/src/coreclr/vm/gchelpers.h +++ b/src/coreclr/vm/gchelpers.h @@ -23,6 +23,12 @@ OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); OBJECTREF AllocateSzArray(TypeHandle arrayType, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); +// Allocate single-dimensional array on a frozen segment +// Returns nullptr if it's not possible. +OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); +// Same for non-array objects +OBJECTREF TryAllocateFrozenObject(MethodTable* pObjMT); + // The main Array allocation routine, can do multi-dimensional OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); OBJECTREF AllocateArrayEx(TypeHandle arrayType, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); diff --git a/src/coreclr/vm/genericdict.cpp b/src/coreclr/vm/genericdict.cpp index 52645f0d92cf50..2a79009f4cbd78 100644 --- a/src/coreclr/vm/genericdict.cpp +++ b/src/coreclr/vm/genericdict.cpp @@ -1161,6 +1161,7 @@ Dictionary::PopulateEntry( } IfFailThrow(ptr.SkipExactlyOne()); + // Computed by MethodTable::GetIndexForFieldDesc(). uint32_t fieldIndex; IfFailThrow(ptr.GetData(&fieldIndex)); diff --git a/src/coreclr/vm/generics.cpp b/src/coreclr/vm/generics.cpp index 1ccf8128445a1a..ed095d20fdcd00 100644 --- a/src/coreclr/vm/generics.cpp +++ b/src/coreclr/vm/generics.cpp @@ -487,7 +487,6 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation( pMT->Debug_SetHasInjectedInterfaceDuplicates(); #endif // _DEBUG - // This logic is identical to logic in class.cpp. Factor these out. // No need to generate IDs for open types. However // we still leave the optional member in the MethodTable holding the value -1 for the ID. if (fHasGenericsStaticsInfo) diff --git a/src/coreclr/vm/genmeth.cpp b/src/coreclr/vm/genmeth.cpp index e7687194c6507c..a1d7af7c038bc5 100644 --- a/src/coreclr/vm/genmeth.cpp +++ b/src/coreclr/vm/genmeth.cpp @@ -1356,7 +1356,7 @@ MethodDesc * MethodDesc::FindOrCreateTypicalSharedInstantiation(BOOL allowCreate allowCreate)); } -//@GENERICSVER: Set the typical (ie. formal) instantiation +//@GENERICSVER: Set up the typical instance (i.e., non-instantiated) void InstantiatedMethodDesc::SetupGenericMethodDefinition(IMDInternalImport* pIMDII, LoaderAllocator* pAllocator, AllocMemTracker* pamTracker, @@ -1380,7 +1380,7 @@ void InstantiatedMethodDesc::SetupGenericMethodDefinition(IMDInternalImport* pIM //@GENERICSVER: allocate space for and initialize the typical instantiation //we share the typical instantiation among all instantiations by placing it in the generic method desc - LOG((LF_JIT, LL_INFO10000, "GENERICSVER: Initializing typical method instantiation with type handles\n")); + LOG((LF_JIT, LL_INFO10000, "IMD::SGMD: Initializing typical MethodDesc this:%p\n", this)); mdGenericParam tkTyPar; HENUMInternalHolder hEnumTyPars(pIMDII); hEnumTyPars.EnumInit(mdtGenericParam, tok); @@ -1431,7 +1431,8 @@ void InstantiatedMethodDesc::SetupGenericMethodDefinition(IMDInternalImport* pIM pInstDest[i] = TypeHandle(pTypeVarTypeDesc); } } - LOG((LF_JIT, LL_INFO10000, "GENERICSVER: Initialized typical method instantiation with %d type handles\n",numTyPars)); + LOG((LF_JIT, LL_INFO10000, "IMD::SGMD: Initialized typical MethodDesc. type handles: %u\n", + numTyPars)); } void InstantiatedMethodDesc::SetupWrapperStubWithInstantiations(MethodDesc* wrappedMD,DWORD numGenericArgs, TypeHandle *pInst) diff --git a/src/coreclr/vm/interpreter.h b/src/coreclr/vm/interpreter.h index 51a82a6da047af..94866d174b8e49 100644 --- a/src/coreclr/vm/interpreter.h +++ b/src/coreclr/vm/interpreter.h @@ -418,7 +418,8 @@ struct CORINFO_SIG_INFO_SMALL CorInfoCallConv getCallConv() { return CorInfoCallConv((callConv & CORINFO_CALLCONV_MASK)); } bool hasThis() { return ((callConv & CORINFO_CALLCONV_HASTHIS) != 0); } bool hasExplicitThis() { return ((callConv & CORINFO_CALLCONV_EXPLICITTHIS) != 0); } - unsigned totalILArgs() { return (numArgs + hasThis()); } + bool hasImplicitThis() { return ((callConv & (CORINFO_CALLCONV_HASTHIS | CORINFO_CALLCONV_EXPLICITTHIS)) == CORINFO_CALLCONV_HASTHIS); } + unsigned totalILArgs() { return (numArgs + (hasImplicitThis() ? 1 : 0)); } bool isVarArg() { return ((getCallConv() == CORINFO_CALLCONV_VARARG) || (getCallConv() == CORINFO_CALLCONV_NATIVEVARARG)); } bool hasTypeArg() { return ((callConv & CORINFO_CALLCONV_PARAMTYPE) != 0); } diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index c36e50d77d2fd7..084281763c0107 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -746,9 +746,9 @@ HCIMPLEND //======================================================================== /*********************************************************************/ -// Returns the address of the field in the object (This is an interior -// pointer and the caller has to use it appropriately). obj can be -// either a reference or a byref +// Returns the address of the instance field in the object (This is an interior +// pointer and the caller has to use it appropriately) or a static field. +// obj can be either a reference or a byref HCIMPL2(void*, JIT_GetFieldAddr_Framed, Object *obj, FieldDesc* pFD) { CONTRACTL { @@ -761,10 +761,9 @@ HCIMPL2(void*, JIT_GetFieldAddr_Framed, Object *obj, FieldDesc* pFD) HELPER_METHOD_FRAME_BEGIN_RET_1(objRef); - if (objRef == NULL) + if (!pFD->IsStatic() && objRef == NULL) COMPlusThrow(kNullReferenceException); - fldAddr = pFD->GetAddress(OBJECTREFToObject(objRef)); HELPER_METHOD_FRAME_END(); @@ -792,6 +791,25 @@ HCIMPL2(void*, JIT_GetFieldAddr, Object *obj, FieldDesc* pFD) HCIMPLEND #include +#include +HCIMPL1(void*, JIT_GetStaticFieldAddr, FieldDesc* pFD) +{ + CONTRACTL { + FCALL_CHECK; + PRECONDITION(CheckPointer(pFD)); + } CONTRACTL_END; + + // [TODO] Only handling EnC for now + _ASSERTE(pFD->IsEnCNew()); + + { + ENDFORBIDGC(); + return HCCALL2(JIT_GetFieldAddr_Framed, NULL, pFD); + } +} +HCIMPLEND +#include + /*********************************************************************/ #define HCallAssert(cache, target) // suppressed to avoid ambiguous cast errors caused by use of template template @@ -2386,6 +2404,37 @@ HCIMPL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_) } HCIMPLEND +/*************************************************************/ +HCIMPL1(Object*, JIT_NewMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_) +{ + FCALL_CONTRACT; + + OBJECTREF newobj = NULL; + HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame + + TypeHandle typeHnd(typeHnd_); + + _ASSERTE(!typeHnd.IsTypeDesc()); // heap objects must have method tables + MethodTable* pMT = typeHnd.AsMethodTable(); + _ASSERTE(pMT->IsRestored_NoLogging()); + +#ifdef _DEBUG + if (g_pConfig->FastGCStressLevel()) { + GetThread()->DisableStressHeap(); + } +#endif // _DEBUG + + newobj = TryAllocateFrozenObject(pMT); + if (newobj == NULL) + { + // Fallback to normal heap allocation. + newobj = AllocateObject(pMT); + } + + HELPER_METHOD_FRAME_END(); + return(OBJECTREFToObject(newobj)); +} +HCIMPLEND //======================================================================== @@ -2701,6 +2750,53 @@ HCIMPL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size) } HCIMPLEND + +/*************************************************************/ +HCIMPL2(Object*, JIT_NewArr1MaybeFrozen, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size) +{ + FCALL_CONTRACT; + + OBJECTREF newArray = NULL; + + HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame + + MethodTable* pArrayMT = (MethodTable*)arrayMT; + + _ASSERTE(pArrayMT->IsFullyLoaded()); + _ASSERTE(pArrayMT->IsArray()); + _ASSERTE(!pArrayMT->IsMultiDimArray()); + + if (size < 0) + COMPlusThrow(kOverflowException); + +#ifdef HOST_64BIT + // Even though ECMA allows using a native int as the argument to newarr instruction + // (therefore size is INT_PTR), ArrayBase::m_NumComponents is 32-bit, so even on 64-bit + // platforms we can't create an array whose size exceeds 32 bits. + if (size > INT_MAX) + EX_THROW(EEMessageException, (kOverflowException, IDS_EE_ARRAY_DIMENSIONS_EXCEEDED)); +#endif + +#ifdef _DEBUG + if (g_pConfig->FastGCStressLevel()) { + GetThread()->DisableStressHeap(); + } +#endif // _DEBUG + + newArray = TryAllocateFrozenSzArray(pArrayMT, (INT32)size); + if (newArray == NULL) + { + // Fallback to default heap allocation + newArray = AllocateSzArray(pArrayMT, (INT32)size); + } + _ASSERTE(newArray != NULL); + + HELPER_METHOD_FRAME_END(); + + return(OBJECTREFToObject(newArray)); +} +HCIMPLEND + /*************************************************************/ HCIMPL3(Object*, JIT_NewMDArr, CORINFO_CLASS_HANDLE classHnd, unsigned dwNumArgs, INT32 * pArgList) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 32d338a0da6b44..62a4400c7d86c0 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -747,7 +747,7 @@ size_t CEEInfo::printObjectDescription ( } else { - _ASSERTE(!"Unexpected object type"); + obj->GetMethodTable()->_GetFullyQualifiedNameForClass(stackStr); } const UTF8* utf8data = stackStr.GetUTF8(); @@ -980,8 +980,7 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken EnsureActive(th, pMD); } } - else - if (pFD != NULL) + else if (pFD != NULL) { if ((tkType != mdtFieldDef) && (tkType != mdtMemberRef)) ThrowBadTokenException(pResolvedToken); @@ -1021,7 +1020,7 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken } else { - unsigned metaTOK = pResolvedToken->token; + mdToken metaTOK = pResolvedToken->token; Module * pModule = (Module *)pResolvedToken->tokenScope; switch (TypeFromToken(metaTOK)) @@ -1533,9 +1532,18 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, if (pFieldMT->IsSharedByGenericInstantiations()) { - fieldAccessor = CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER; + if (pField->IsEnCNew()) + { + fieldAccessor = CORINFO_FIELD_STATIC_ADDR_HELPER; - pResult->helper = getGenericStaticsHelper(pField); + pResult->helper = CORINFO_HELP_GETSTATICFIELDADDR; + } + else + { + fieldAccessor = CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER; + + pResult->helper = getGenericStaticsHelper(pField); + } } else if (pFieldMT->GetModule()->IsSystem() && (flags & CORINFO_ACCESS_GET) && @@ -4197,29 +4205,6 @@ bool CEEInfo::canCast( return result; } -/*********************************************************************/ -// TRUE if cls1 and cls2 are considered equivalent types. -bool CEEInfo::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - bool result = false; - - JIT_TO_EE_TRANSITION(); - - result = !!((TypeHandle)cls1).IsEquivalentTo((TypeHandle)cls2); - - EE_TO_JIT_TRANSITION(); - - return result; -} - /*********************************************************************/ // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. @@ -6149,20 +6134,33 @@ bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objHandle) _ASSERT(objHandle != NULL); -#ifdef DEBUG + bool isImmutable = false; + JIT_TO_EE_TRANSITION(); GCX_COOP(); OBJECTREF obj = getObjectFromJitHandle(objHandle); MethodTable* type = obj->GetMethodTable(); - _ASSERTE(type->IsString() || type == g_pRuntimeTypeClass); + if (type->IsString() || type == g_pRuntimeTypeClass) + { + // These types are always immutable + isImmutable = true; + } + else if (type->IsArray() && ((ArrayBase*)OBJECTREFToObject(obj))->GetComponentSize() == 0) + { + // Empty arrays are always immutable + isImmutable = true; + } + else if (type->IsDelegate() || type->GetNumInstanceFields() == 0) + { + // Delegates and types without fields are always immutable + isImmutable = true; + } EE_TO_JIT_TRANSITION(); -#endif - // All currently allocated frozen objects can be treated as immutable - return true; + return isImmutable; } /***********************************************************************/ @@ -11843,7 +11841,7 @@ InfoAccessType CEEJitInfo::emptyStringLiteral(void ** ppValue) return result; } -bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) +bool CEEInfo::getStaticFieldContent(CORINFO_FIELD_HANDLE fieldHnd, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects) { CONTRACTL { THROWS; @@ -11981,6 +11979,40 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t return result; } +bool CEEInfo::getObjectContent(CORINFO_OBJECT_HANDLE handle, uint8_t* buffer, int bufferSize, int valueOffset) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + _ASSERT(handle != NULL); + _ASSERT(buffer != NULL); + _ASSERT(bufferSize > 0); + _ASSERT(valueOffset >= 0); + + bool result = false; + + JIT_TO_EE_TRANSITION(); + + GCX_COOP(); + OBJECTREF objRef = getObjectFromJitHandle(handle); + _ASSERTE(objRef != NULL); + + // TODO: support types containing GC pointers + if (!objRef->GetMethodTable()->ContainsPointers() && bufferSize + valueOffset <= (int)objRef->GetSize()) + { + Object* obj = OBJECTREFToObject(objRef); + memcpy(buffer, (uint8_t*)obj + valueOffset, bufferSize); + result = true; + } + + EE_TO_JIT_TRANSITION(); + + return result; +} + /*********************************************************************/ CORINFO_CLASS_HANDLE CEEJitInfo::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE fieldHnd, bool* pIsSpeculative) @@ -12827,6 +12859,12 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE); #endif // PROFILING_SUPPORTED + // Don't allow allocations on FOH from collectible contexts to avoid memory leaks + if (!ftn->GetLoaderAllocator()->CanUnload()) + { + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED); + } + // Set optimization flags if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT)) { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 5f2fd20abda2a7..73778a1ca6baba 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -422,6 +422,7 @@ class CEEInfo : public ICorJitInfo public: #include "icorjitinfoimpl_generated.h" uint32_t getClassAttribsInternal (CORINFO_CLASS_HANDLE cls); + bool isObjectImmutableInteral(OBJECTREF obj); static unsigned getClassAlignmentRequirementStatic(TypeHandle clsHnd); diff --git a/src/coreclr/vm/memberload.cpp b/src/coreclr/vm/memberload.cpp index 446370949771fe..57c9072db3a4b4 100644 --- a/src/coreclr/vm/memberload.cpp +++ b/src/coreclr/vm/memberload.cpp @@ -239,8 +239,7 @@ void MemberLoader::GetDescFromMemberRef(ModuleBase * pModule, { fMissingMethod = TRUE; } - else - if (pMethodDef->HasClassOrMethodInstantiation()) + else if (pMethodDef->HasClassOrMethodInstantiation()) { // A memberref to a varargs method must not find a MethodDesc that is generic (as varargs methods may not be implemented on generics) fMissingMethod = TRUE; @@ -653,24 +652,24 @@ MethodDesc* MemberLoader::GetMethodDescFromMethodDef(Module *pModule, //--------------------------------------------------------------------------------------- // FieldDesc* MemberLoader::GetFieldDescFromFieldDef(Module *pModule, - mdToken FieldDef, + mdToken fieldDef, BOOL strictMetadataChecks) { CONTRACTL { THROWS; GC_TRIGGERS; - PRECONDITION(TypeFromToken(FieldDef) == mdtFieldDef); + PRECONDITION(TypeFromToken(fieldDef) == mdtFieldDef); } CONTRACTL_END; // In lookup table? - FieldDesc * pFD = pModule->LookupFieldDef(FieldDef); + FieldDesc* pFD = pModule->LookupFieldDef(fieldDef); if (!pFD) { // No, so do it the long way mdTypeDef typeDef; - IfFailThrow(pModule->GetMDImport()->GetParentToken(FieldDef, &typeDef)); + IfFailThrow(pModule->GetMDImport()->GetParentToken(fieldDef, &typeDef)); // Load the class - that should set the desc in the rid map // Field defs to generic things resolve to the formal instantiation @@ -684,11 +683,11 @@ FieldDesc* MemberLoader::GetFieldDescFromFieldDef(Module *pModule, strictMetadataChecks ? ClassLoader::FailIfUninstDefOrRef : ClassLoader::PermitUninstDefOrRef); - pFD = pModule->LookupFieldDef(FieldDef); + pFD = pModule->LookupFieldDef(fieldDef); if (pFD == NULL) { LPCUTF8 szMember; - if (FAILED(pModule->GetMDImport()->GetNameOfFieldDef(FieldDef, &szMember))) + if (FAILED(pModule->GetMDImport()->GetNameOfFieldDef(fieldDef, &szMember))) { szMember = "Invalid FieldDef record"; } @@ -707,7 +706,7 @@ FieldDesc* MemberLoader::GetFieldDescFromFieldDef(Module *pModule, if (pEnCFD->NeedsFixup()) { GCX_COOP(); - pEnCFD->Fixup(FieldDef); + pEnCFD->Fixup(fieldDef); } } #endif // EnC_SUPPORTED @@ -817,14 +816,14 @@ MethodDesc * MemberLoader::GetMethodDescFromMethodSpec(Module * pModule, CQuickBytes qbGenericMethodArgs; - mdMemberRef GenericMemberRef; + mdToken genericMember; PCCOR_SIGNATURE pSig; ULONG cSig; IMDInternalImport * pInternalImport = pModule->GetMDImport(); // Get the member def/ref and instantiation signature - IfFailThrow(pInternalImport->GetMethodSpecProps(MethodSpec, &GenericMemberRef, &pSig, &cSig)); + IfFailThrow(pInternalImport->GetMethodSpecProps(MethodSpec, &genericMember, &pSig, &cSig)); if (ppMethodSig != NULL) { @@ -861,15 +860,15 @@ MethodDesc * MemberLoader::GetMethodDescFromMethodSpec(Module * pModule, MethodDesc * pMD = NULL; FieldDesc * pFD = NULL; - switch (TypeFromToken(GenericMemberRef)) + switch (TypeFromToken(genericMember)) { case mdtMethodDef: - pMD = GetMethodDescFromMethodDef(pModule, GenericMemberRef, strictMetadataChecks); + pMD = GetMethodDescFromMethodDef(pModule, genericMember, strictMetadataChecks); *ppTH = pMD->GetMethodTable(); break; case mdtMemberRef: - GetDescFromMemberRef(pModule, GenericMemberRef, &pMD, &pFD, pTypeContext, strictMetadataChecks, ppTH, + GetDescFromMemberRef(pModule, genericMember, &pMD, &pFD, pTypeContext, strictMetadataChecks, ppTH, actualTypeRequired, ppTypeSig, pcbTypeSig); if (pMD == NULL) @@ -1031,7 +1030,7 @@ BOOL MemberLoader::FM_ShouldSkipMethod(DWORD dwAttrs, FM_Flags flags) // but with generics, we need to have a properly set up Substitution, so that // we have a correct set of types to compare with. The idea is that either the current // EEClass matches up with the methoddesc, or a parent EEClass will match up. -BOOL CompareMethodSigWithCorrectSubstitution( +static BOOL CompareMethodSigWithCorrectSubstitution( PCCOR_SIGNATURE pSignature, DWORD cSignature, ModuleBase* pModule, @@ -1078,14 +1077,13 @@ BOOL CompareMethodSigWithCorrectSubstitution( // signature is defined. MethodDesc * MemberLoader::FindMethod( - MethodTable * pMT, + MethodTable* pMT, LPCUTF8 pszName, PCCOR_SIGNATURE pSignature, DWORD cSignature, ModuleBase* pModule, FM_Flags flags, // = FM_Default const Substitution *pDefSubst) // = NULL { - CONTRACT (MethodDesc *) { THROWS; GC_TRIGGERS; @@ -1093,9 +1091,15 @@ MemberLoader::FindMethod( MODE_ANY; } CONTRACT_END; + LOG((LF_LOADER, LL_INFO10000, "ML::FM pMT:%p for %s sig:%p sigLen:%u\n", + pMT, pszName, pSignature, cSignature)); + // Retrieve the right comparison function to use. UTF8StringCompareFuncPtr StrCompFunc = FM_GetStrCompFunc(flags); + const bool canSkipMethod = FM_PossibleToSkipMethod(flags); + const bool ignoreName = (flags & FM_IgnoreName) != 0; + // Statistically it's most likely for a method to be found in non-vtable portion of this class's members, then in the // vtable of this class's declared members, then in the inherited portion of the vtable, so we search backwards. @@ -1115,18 +1119,21 @@ MemberLoader::FindMethod( for (; it.IsValid(); it.Prev()) { MethodDesc *pCurDeclMD = it.GetDeclMethodDesc(); + + LOG((LF_LOADER, LL_INFO100000, "ML::FM Considering %s::%s, pMD:%p\n", + pCurDeclMD->m_pszDebugClassName, pCurDeclMD->m_pszDebugMethodName, pCurDeclMD)); + #ifdef _DEBUG MethodTable *pCurDeclMT = pCurDeclMD->GetMethodTable(); CONSISTENCY_CHECK(!pMT->IsInterface() || pCurDeclMT == pMT->GetCanonicalMethodTable()); #endif - if (FM_PossibleToSkipMethod(flags) && FM_ShouldSkipMethod(pCurDeclMD->GetAttrs(), flags)) + if (canSkipMethod && FM_ShouldSkipMethod(pCurDeclMD->GetAttrs(), flags)) { continue; } - if ((flags & FM_IgnoreName) != 0 - || StrCompFunc(pszName, pCurDeclMD->GetNameThrowing()) == 0) + if (ignoreName || StrCompFunc(pszName, pCurDeclMD->GetNameThrowing()) == 0) { if (CompareMethodSigWithCorrectSubstitution(pSignature, cSignature, pModule, pCurDeclMD, pDefSubst, pMT)) { @@ -1135,7 +1142,6 @@ MemberLoader::FindMethod( } } - // No inheritance on value types or interfaces if (pMT->IsValueType() || pMT->IsInterface()) { @@ -1146,30 +1152,63 @@ MemberLoader::FindMethod( //@todo: This routine might be factored slightly to improve perf. CONSISTENCY_CHECK(pMT->CheckLoadLevel(CLASS_LOAD_APPROXPARENTS)); - MethodTable *pParentMT = pMT->GetParentMethodTable(); + MethodDesc* md = NULL; + MethodTable* pParentMT = pMT->GetParentMethodTable(); if (pParentMT != NULL) { Substitution subst2 = pMT->GetSubstitutionForParent(pDefSubst); - MethodDesc *md = MemberLoader::FindMethod(pParentMT, - pszName, pSignature, cSignature, pModule, flags, &subst2); + md = MemberLoader::FindMethod(pParentMT, pszName, pSignature, cSignature, pModule, flags, &subst2); // Don't inherit constructors from parent classes. It is important to forbid this, // because the JIT needs to get the class handle from the memberRef, and when the // constructor is inherited, the JIT will get the class handle for the parent class - // (and not allocate enough space, etc.). See bug #50035 for details. - if (md) + // (and not allocate enough space, etc.). + if (md != NULL + && IsMdInstanceInitializer(md->GetAttrs(), pszName)) { - if (IsMdInstanceInitializer(md->GetAttrs(), pszName)) + md = NULL; + } + } + +#ifdef EnC_SUPPORTED + // In the event the method wasn't found and the current module has + // EnC enabled, try the slow path and go through all available methods. + if (md == NULL + && pMT->GetModule()->IsEditAndContinueEnabled()) + { + LOG((LF_LOADER, LL_INFO100000, "ML::FM Falling back to EnC slow path\n")); + + MethodTable::IntroducedMethodIterator itMethods(pMT, FALSE); + for (; itMethods.IsValid(); itMethods.Next()) + { + MethodDesc* pCurDeclMD = itMethods.GetMethodDesc(); + +#ifdef _DEBUG + MethodTable *pCurDeclMT = pCurDeclMD->GetMethodTable(); + CONSISTENCY_CHECK(!pMT->IsInterface() || pCurDeclMT == pMT->GetCanonicalMethodTable()); +#endif + + if (canSkipMethod && FM_ShouldSkipMethod(pCurDeclMD->GetAttrs(), flags)) { - md = NULL; + continue; } - } - RETURN md; + LOG((LF_LOADER, LL_INFO100000, "ML::FM EnC - Considering %s::%s, pMD:%p\n", + pCurDeclMD->m_pszDebugClassName, pCurDeclMD->m_pszDebugMethodName, pCurDeclMD)); + + if (ignoreName || StrCompFunc(pszName, pCurDeclMD->GetNameThrowing()) == 0) + { + if (CompareMethodSigWithCorrectSubstitution(pSignature, cSignature, pModule, pCurDeclMD, pDefSubst, pMT)) + { + RETURN pCurDeclMD; + } + } + } } +#endif // EnC_SUPPORTED - RETURN NULL; + RETURN md; } //******************************************************************************* @@ -1460,7 +1499,7 @@ MemberLoader::FindConstructor(MethodTable * pMT, PCCOR_SIGNATURE pSignature,DWOR #endif // DACCESS_COMPILE FieldDesc * -MemberLoader::FindField(MethodTable * pMT, LPCUTF8 pszName, PCCOR_SIGNATURE pSignature, DWORD cSignature, ModuleBase* pModule, BOOL bCaseSensitive) +MemberLoader::FindField(MethodTable* pMT, LPCUTF8 pszName, PCCOR_SIGNATURE pSignature, DWORD cSignature, ModuleBase* pModule, BOOL bCaseSensitive) { CONTRACTL { @@ -1471,52 +1510,49 @@ MemberLoader::FindField(MethodTable * pMT, LPCUTF8 pszName, PCCOR_SIGNATURE pSig } CONTRACTL_END - DWORD i; - DWORD dwFieldDescsToScan; - IMDInternalImport *pInternalImport = pMT->GetMDImport(); // All explicitly declared fields in this class will have the same scope + LOG((LF_LOADER, LL_INFO100000, "ML::FF '%s' in pModule:%p pMT:%p, %s\n", + pszName, pModule, pMT, pMT->GetDebugClassName())); + // Array classes don't have fields, and don't have metadata + if (pMT->IsArray()) + return NULL; + + IMDInternalImport *pInternalImport = pMT->GetMDImport(); // All explicitly declared fields in this class will have the same scope CONSISTENCY_CHECK(pMT->CheckLoadLevel(CLASS_LOAD_APPROXPARENTS)); // Retrieve the right comparison function to use. UTF8StringCompareFuncPtr StrCompFunc = bCaseSensitive ? strcmp : stricmpUTF8; - // Array classes don't have fields, and don't have metadata - if (pMT->IsArray()) - return NULL; - EEClass * pClass = pMT->GetClass(); MethodTable *pParentMT = pMT->GetParentMethodTable(); // Scan the FieldDescs of this class - if (pParentMT != NULL) - dwFieldDescsToScan = pClass->GetNumInstanceFields() - pParentMT->GetNumInstanceFields() + pClass->GetNumStaticFields(); - else - dwFieldDescsToScan = pClass->GetNumInstanceFields() + pClass->GetNumStaticFields(); + DWORD fieldDescCount = (pParentMT != NULL) + ? pClass->GetNumInstanceFields() - pParentMT->GetNumInstanceFields() + pClass->GetNumStaticFields() + : pClass->GetNumInstanceFields() + pClass->GetNumStaticFields(); PTR_FieldDesc pFieldDescList = pClass->GetFieldDescList(); - for (i = 0; i < dwFieldDescsToScan; i++) + LPCUTF8 szMemberName; + mdFieldDef mdField; + for (DWORD i = 0; i < fieldDescCount; i++) { - LPCUTF8 szMemberName; FieldDesc * pFD = &pFieldDescList[i]; PREFIX_ASSUME(pFD!=NULL); - mdFieldDef mdField = pFD->GetMemberDef(); // Check is valid FieldDesc, and not some random memory INDEBUGIMPL(pFD->GetApproxEnclosingMethodTable()->SanityCheck()); + mdField = pFD->GetMemberDef(); IfFailThrow(pInternalImport->GetNameOfFieldDef(mdField, &szMemberName)); if (StrCompFunc(szMemberName, pszName) != 0) - { continue; - } if (pSignature != NULL) { PCCOR_SIGNATURE pMemberSig; DWORD cMemberSig; - IfFailThrow(pInternalImport->GetSigOfFieldDef(mdField, &cMemberSig, &pMemberSig)); if (!MetaSig::CompareFieldSigs( @@ -1526,7 +1562,7 @@ MemberLoader::FindField(MethodTable * pMT, LPCUTF8 pszName, PCCOR_SIGNATURE pSig pSignature, cSignature, pModule)) - { + { continue; } } @@ -1534,5 +1570,52 @@ MemberLoader::FindField(MethodTable * pMT, LPCUTF8 pszName, PCCOR_SIGNATURE pSig return pFD; } +#if defined(EnC_SUPPORTED) && !defined(DACCESS_COMPILE) + if (pModule != NULL + && pModule->IsFullModule() + && ((Module*)pModule)->IsEditAndContinueEnabled()) + { + LOG((LF_LOADER, LL_INFO100000, "ML::FF Falling back to EnC slow path\n")); + + // We may not have the full FieldDesc info at ApplyEnC time because we don't + // have a thread so can't do things like load classes (due to possible exceptions) + EncApproxFieldDescIterator fdIterator( + pMT, + ApproxFieldDescIterator::ALL_FIELDS, + (EncApproxFieldDescIterator::FixUpEncFields | EncApproxFieldDescIterator::OnlyEncFields)); + PTR_FieldDesc pCurrentFD; + while ((pCurrentFD = fdIterator.Next()) != NULL) + { + // Check is valid FieldDesc, and not some random memory + INDEBUGIMPL(pCurrentFD->GetApproxEnclosingMethodTable()->SanityCheck()); + + mdField = pCurrentFD->GetMemberDef(); + IfFailThrow(pInternalImport->GetNameOfFieldDef(mdField, &szMemberName)); + + if (StrCompFunc(szMemberName, pszName) != 0) + continue; + + if (pSignature != NULL) + { + PCCOR_SIGNATURE pMemberSig; + DWORD cMemberSig; + IfFailThrow(pInternalImport->GetSigOfFieldDef(mdField, &cMemberSig, &pMemberSig)); + + if (!MetaSig::CompareFieldSigs( + pMemberSig, + cMemberSig, + pMT->GetModule(), + pSignature, + cSignature, + pModule)) + { + continue; + } + } + return pCurrentFD; + } + } +#endif // defined(EnC_SUPPORTED) && !defined(DACCESS_COMPILE) + return NULL; } diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index c09056a0121fcc..3e59a08cb47ace 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -918,9 +918,10 @@ PCODE MethodDesc::GetNativeCode() { // When profiler is enabled, profiler may ask to rejit a code even though we // we have ngen code for this MethodDesc. (See MethodDesc::DoPrestub). - // This means that *GetAddrOfNativeCodeSlot() - // is not stable. It can turn from non-zero to zero. - PCODE pCode = *GetAddrOfNativeCodeSlot(); + // This means that *ppCode is not stable. It can turn from non-zero to zero. + PTR_PCODE ppCode = GetAddrOfNativeCodeSlot(); + PCODE pCode = *ppCode; + #ifdef TARGET_ARM if (pCode != NULL) pCode |= THUMB_CODE; @@ -1548,12 +1549,17 @@ MethodDesc* MethodDesc::LoadTypicalMethodDefinition() #ifndef DACCESS_COMPILE if (HasClassOrMethodInstantiation()) { - MethodTable *pMT = GetMethodTable(); + MethodTable* pMT = GetMethodTable(); if (!pMT->IsTypicalTypeDefinition()) - pMT = ClassLoader::LoadTypeDefThrowing(pMT->GetModule(), - pMT->GetCl(), - ClassLoader::ThrowIfNotFound, - ClassLoader::PermitUninstDefOrRef).GetMethodTable(); + { + MethodTable* pMTTypical = ClassLoader::LoadTypeDefThrowing(pMT->GetModule(), + pMT->GetCl(), + ClassLoader::ThrowIfNotFound, + ClassLoader::PermitUninstDefOrRef).GetMethodTable(); + LOG((LF_CLASSLOADER, LL_INFO100000, "MD:LTMD: pMT:%p => pMTTypical:%p\n", + pMT, pMTTypical)); + pMT = pMTTypical; + } CONSISTENCY_CHECK(TypeHandle(pMT).CheckFullyLoaded()); MethodDesc *resultMD = pMT->GetParallelMethodDesc(this); PREFIX_ASSUME(resultMD != NULL); @@ -1562,7 +1568,9 @@ MethodDesc* MethodDesc::LoadTypicalMethodDefinition() } else #endif // !DACCESS_COMPILE + { RETURN(this); + } } //******************************************************************************* @@ -3244,6 +3252,8 @@ void MethodDesc::ResetCodeEntryPointForEnC() _ASSERTE(!IsVersionableWithPrecode()); _ASSERTE(!MayHaveEntryPointSlotsToBackpatch()); + LOG((LF_ENC, LL_INFO100000, "MD::RCEPFENC: this:%p - %s::%s - HasPrecode():%s, HasNativeCodeSlot():%s\n", + this, m_pszDebugClassName, m_pszDebugMethodName, (HasPrecode() ? "true" : "false"), (HasNativeCodeSlot() ? "true" : "false"))); if (HasPrecode()) { GetPrecode()->ResetTargetInterlocked(); @@ -3251,7 +3261,11 @@ void MethodDesc::ResetCodeEntryPointForEnC() if (HasNativeCodeSlot()) { - *GetAddrOfNativeCodeSlot() = NULL; + PTR_PCODE ppCode = GetAddrOfNativeCodeSlot(); + PCODE pCode = *ppCode; + LOG((LF_CORDB, LL_INFO1000000, "MD::RCEPFENC: %p -> %p\n", + ppCode, pCode)); + *ppCode = NULL; } } diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index d27a7eb0e9d533..e59c2dd71dc357 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -3205,10 +3205,10 @@ class ComPlusCallMethodDesc : public MethodDesc // come in four flavours, discriminated by the // low order bits of the first field: // -// 00 --> GenericMethodDefinition -// 01 --> UnsharedMethodInstantiation -// 10 --> SharedMethodInstantiation -// 11 --> WrapperStubWithInstantiations - and unboxing or instantiating stub +// 001 --> GenericMethodDefinition +// 010 --> UnsharedMethodInstantiation +// 011 --> SharedMethodInstantiation +// 100 --> WrapperStubWithInstantiations - and unboxing or instantiating stub // // A SharedMethodInstantiation descriptor extends MethodDesc // with a pointer to dictionary layout and a representative instantiation. @@ -3358,15 +3358,6 @@ class InstantiatedMethodDesc final : public MethodDesc void SetupWrapperStubWithInstantiations(MethodDesc* wrappedMD,DWORD numGenericArgs, TypeHandle *pGenericMethodInst); private: - enum - { - KindMask = 0x07, - GenericMethodDefinition = 0x00, - UnsharedMethodInstantiation = 0x01, - SharedMethodInstantiation = 0x02, - WrapperStubWithInstantiations = 0x03, - }; - friend class MethodDesc; // this fields are currently accessed by MethodDesc::Save/Restore etc. union { PTR_DictionaryLayout m_pDictLayout; //SharedMethodInstantiation @@ -3387,6 +3378,14 @@ class InstantiatedMethodDesc final : public MethodDesc PTR_Dictionary m_pPerInstInfo; //SHARED private: + enum + { + KindMask = 0x07, + GenericMethodDefinition = 0x01, + UnsharedMethodInstantiation = 0x02, + SharedMethodInstantiation = 0x03, + WrapperStubWithInstantiations = 0x04, + }; WORD m_wFlags2; WORD m_wNumGenericArgs; diff --git a/src/coreclr/vm/methoditer.cpp b/src/coreclr/vm/methoditer.cpp index 1da1dbf29897d9..82def6a1bec50a 100644 --- a/src/coreclr/vm/methoditer.cpp +++ b/src/coreclr/vm/methoditer.cpp @@ -24,7 +24,7 @@ BOOL LoadedMethodDescIterator::Next( { NOTHROW; GC_NOTRIGGER; - MODE_PREEMPTIVE; + MODE_ANY; } CONTRACTL_END @@ -203,15 +203,11 @@ MethodDesc *LoadedMethodDescIterator::Current() return m_mainMD; } - MethodTable *pMT = m_typeIteratorEntry->GetTypeHandle().GetMethodTable(); + MethodTable *pMT = m_typeIteratorEntry->GetTypeHandle().GetMethodTable()->GetCanonicalMethodTable(); PREFIX_ASSUME(pMT != NULL); - _ASSERTE(pMT); - - return pMT->GetMethodDescForSlot(m_mainMD->GetSlot()); + return pMT->GetParallelMethodDesc(m_mainMD); } -// Initialize the iterator. It will cover generics + prejitted; -// but it is not EnC aware. void LoadedMethodDescIterator::Start( AppDomain * pAppDomain, diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 55413bb818e921..d40eb089953ba9 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -2081,11 +2081,40 @@ MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(TypeHandle ownerType, M } #endif // DACCESS_COMPILE +const DWORD EnCFieldIndex = 0x10000000; + //========================================================================================== PTR_FieldDesc MethodTable::GetFieldDescByIndex(DWORD fieldIndex) { LIMITED_METHOD_CONTRACT; + // Check if the field index is for an EnC field lookup. + // See GetIndexForFieldDesc() for when this is applied and why. + if ((fieldIndex & EnCFieldIndex) == EnCFieldIndex) + { + DWORD rid = fieldIndex & ~EnCFieldIndex; + LOG((LF_ENC, LL_INFO100, "MT:GFDBI: rid:0x%08x\n", rid)); + + mdFieldDef tokenToFind = TokenFromRid(rid, mdtFieldDef); + EncApproxFieldDescIterator fdIterator( + this, + ApproxFieldDescIterator::ALL_FIELDS, + (EncApproxFieldDescIterator::FixUpEncFields | EncApproxFieldDescIterator::OnlyEncFields)); + PTR_FieldDesc pField; + while ((pField = fdIterator.Next()) != NULL) + { + mdFieldDef token = pField->GetMemberDef(); + if (tokenToFind == token) + { + LOG((LF_ENC, LL_INFO100, "MT:GFDBI: Found pField:%p\n", pField)); + return pField; + } + } + + LOG((LF_ENC, LL_INFO100, "MT:GFDBI: Failed to find rid:0x%08x\n", rid)); + return NULL; + } + if (HasGenericsStaticsInfo() && fieldIndex >= GetNumIntroducedInstanceFields()) { @@ -2102,6 +2131,19 @@ DWORD MethodTable::GetIndexForFieldDesc(FieldDesc *pField) { LIMITED_METHOD_CONTRACT; + // EnC methods are not in a location where computing an index through + // pointer arithmetic is possible. Instead we use the RID and a high + // bit that is ECMA encodable (that is, < 0x1fffffff) and also doesn't + // conflict with any other RID (that is, > 0x00ffffff). + // See FieldDescSlot usage in the JIT interface. + if (pField->IsEnCNew()) + { + mdFieldDef tok = pField->GetMemberDef(); + DWORD rid = RidFromToken(tok); + LOG((LF_ENC, LL_INFO100, "MT:GIFFD: pField:%p rid:0x%08x\n", pField, rid)); + return rid | EnCFieldIndex; + } + if (pField->IsStatic() && HasGenericsStaticsInfo()) { FieldDesc *pStaticFields = GetGenericsStaticFieldDescs(); @@ -8301,7 +8343,7 @@ void MethodTable::MethodIterator::Init(MethodTable *pMTDecl, MethodTable *pMTImp PRECONDITION(CheckPointer(pMTImpl)); } CONTRACTL_END; - LOG((LF_LOADER, LL_INFO10000, "SD: MT::MethodIterator created for %s.\n", pMTDecl->GetDebugClassName())); + LOG((LF_LOADER, LL_INFO10000, "MT::MethodIterator created for %s.\n", pMTDecl->GetDebugClassName())); m_pMethodData = MethodTable::GetMethodData(pMTDecl, pMTImpl); CONSISTENCY_CHECK(CheckPointer(m_pMethodData)); @@ -8715,7 +8757,46 @@ MethodTable * MethodTable::GetRestoredSlotMT(DWORD slotNumber) } //========================================================================================== -MethodDesc * MethodTable::GetParallelMethodDesc(MethodDesc * pDefMD) +namespace +{ + // Methods added by EnC cannot be looked up by slot since + // they have none, see EEClass::AddMethodDesc(). We must perform + // a slow lookup instead of using the fast slot lookup path. + MethodDesc* GetParallelMethodDescForEnC(MethodTable* pMT, MethodDesc* pDefMD) + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + PRECONDITION(pMT != NULL); + PRECONDITION(pMT->IsCanonicalMethodTable()); + PRECONDITION(pDefMD != NULL); + PRECONDITION(pDefMD->IsEnCAddedMethod()); + PRECONDITION(pDefMD->GetSlot() == MethodTable::NO_SLOT); + } + CONTRACTL_END; + + mdMethodDef tkMethod = pDefMD->GetMemberDef(); + Module* mod = pDefMD->GetModule(); + LOG((LF_ENC, LL_INFO100, "GPMDENC: pMT:%p tok:0x%08x mod:%p\n", pMT, tkMethod, mod)); + + MethodTable::IntroducedMethodIterator it(pMT); + for (; it.IsValid(); it.Next()) + { + MethodDesc* pMD = it.GetMethodDesc(); + if (pMD->GetMemberDef() == tkMethod + && pMD->GetModule() == mod) + { + return pMD; + } + } + LOG((LF_ENC, LL_INFO10000, "GPMDENC: Not found\n")); + return NULL; + } +} + +MethodDesc* MethodTable::GetParallelMethodDesc(MethodDesc* pDefMD) { CONTRACTL { @@ -8724,6 +8805,12 @@ MethodDesc * MethodTable::GetParallelMethodDesc(MethodDesc * pDefMD) MODE_ANY; } CONTRACTL_END; + +#ifdef EnC_SUPPORTED + if (pDefMD->IsEnCAddedMethod()) + return GetParallelMethodDescForEnC(this, pDefMD); +#endif // EnC_SUPPORTED + return GetMethodDescForSlot(pDefMD->GetSlot()); } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index fbda486d729aee..acffd1b6141c7c 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3554,20 +3554,14 @@ public : } private: - /* - * This stuff must be first in the struct and should fit on a cache line - don't move it. Used by the GC. - */ - // struct - // { - // Low WORD is component size for array and string types (HasComponentSize() returns true). // Used for flags otherwise. DWORD m_dwFlags; // Base size of instance of this class when allocated on the heap DWORD m_BaseSize; - // } + // See WFLAGS2_ENUM for values. WORD m_wFlags2; // Class token if it fits into 16-bits. If this is (WORD)-1, the class token is stored in the TokenOverflow optional member. @@ -3583,7 +3577,7 @@ public : PTR_MethodTable m_pParentMethodTable; - PTR_Module m_pLoaderModule; // LoaderModule. It is equal to the ZapModule in ngened images + PTR_Module m_pLoaderModule; PTR_MethodTableWriteableData m_pWriteableData; diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index bd867cddbacb68..147b2221fad472 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -1902,7 +1902,6 @@ MethodTableBuilder::BuildMethodTableThrowing( // if there are context or thread static set the info in the method table optional members // - // Check for the RemotingProxy Attribute // structs with GC pointers MUST be pointer sized aligned because the GC assumes it if (IsValueClass() && pMT->ContainsPointers() && (bmtFP->NumInstanceFieldBytes % TARGET_POINTER_SIZE != 0)) { @@ -4118,7 +4117,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, &bmtGenerics->typeContext, ClassLoader::LoadTypes, CLASS_LOAD_APPROXPARENTS, - TRUE, NULL, NULL, NULL, + TRUE, NULL, NULL, NULL, &recursiveControl).GetMethodTable(); } } @@ -4477,9 +4476,12 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, BuildMethodTableThrowException(IDS_EE_TOOMANYFIELDS); } - GetHalfBakedClass()->SetNumInstanceFields((WORD)dwNumInstanceFields); - GetHalfBakedClass()->SetNumStaticFields((WORD)dwNumStaticFields); - GetHalfBakedClass()->SetNumThreadStaticFields((WORD)dwNumThreadStaticFields); + if (!isEnCField) + { + GetHalfBakedClass()->SetNumInstanceFields((WORD)dwNumInstanceFields); + GetHalfBakedClass()->SetNumStaticFields((WORD)dwNumStaticFields); + GetHalfBakedClass()->SetNumThreadStaticFields((WORD)dwNumThreadStaticFields); + } if (bmtFP->fHasFixedAddressValueTypes) { @@ -6075,7 +6077,7 @@ MethodTableBuilder::InitMethodDesc( } CONTRACTL_END; - LOG((LF_CORDB, LL_EVERYTHING, "MTB::IMD: pNewMD:%p (%u) EnC: %s tok:%x (%s::%s)\n", + LOG((LF_CORDB, LL_EVERYTHING, "MTB::IMD: pNewMD:%p (%u) EnC: %s tok:0x%08x (%s::%s)\n", pNewMD, Classification, (fEnC ? "true" : "false"), tok, pszDebugClassName, pszDebugMethodName)); // Now we know the classification we can perform any classification specific initialization. diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index d608fe0493a557..cca2b7e8ba8491 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -522,6 +522,7 @@ class ArrayBase : public Object friend class CObjectHeader; friend class Object; friend OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags); + friend OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); friend OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags); friend FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); friend FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index 3425f944bf47cf..29965fd0477a28 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -650,7 +650,7 @@ PCODE MethodDesc::JitCompileCode(PrepareCodeConfig* pConfig) STANDARD_VM_CONTRACT; LOG((LF_JIT, LL_INFO1000000, - "JitCompileCode(" FMT_ADDR ", %s) for %s:%s\n", + "JitCompileCode(" FMT_ADDR ", ILStub: %s) for %s::%s\n", DBG_ADDR(this), IsILStub() ? " TRUE" : "FALSE", GetMethodTable()->GetDebugClassName(), diff --git a/src/coreclr/vm/profilingenumerators.cpp b/src/coreclr/vm/profilingenumerators.cpp index 7d537924df8919..1d19a87324be92 100644 --- a/src/coreclr/vm/profilingenumerators.cpp +++ b/src/coreclr/vm/profilingenumerators.cpp @@ -15,6 +15,7 @@ // #include "common.h" +#include "frozenobjectheap.h" #ifdef PROFILING_SUPPORTED @@ -88,6 +89,42 @@ BOOL ProfilerFunctionEnum::Init(BOOL fWithReJITIDs) return TRUE; } +// --------------------------------------------------------------------------------------- +// ProfilerObjectEnum/ICorProfilerObjectEnum implementation +// --------------------------------------------------------------------------------------- + +BOOL ProfilerObjectEnum::Init() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + CAN_TAKE_LOCK; + } + CONTRACTL_END; + + FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); + CrstHolder ch(&foh->m_Crst); + + const unsigned segmentsCount = foh->m_FrozenSegments.GetCount(); + FrozenObjectSegment** segments = foh->m_FrozenSegments.GetElements(); + if (segments != nullptr) + { + for (unsigned segmentIdx = 0; segmentIdx < segmentsCount; segmentIdx++) + { + const FrozenObjectSegment* segment = segments[segmentIdx]; + + Object* currentObj = segment->GetFirstObject(); + while (currentObj != nullptr) + { + *m_elements.Append() = reinterpret_cast(currentObj); + currentObj = segment->GetNextObject(currentObj); + } + } + } + return TRUE; +} + // --------------------------------------------------------------------------------------- // Catch-up helpers // diff --git a/src/coreclr/vm/profilingenumerators.h b/src/coreclr/vm/profilingenumerators.h index de050af4e34223..4582da67ceb42a 100644 --- a/src/coreclr/vm/profilingenumerators.h +++ b/src/coreclr/vm/profilingenumerators.h @@ -453,7 +453,7 @@ ProfilerEnum< EnumInterface, IID_EnumInterface, Element >::Clone(EnumInterface** // Enumerators have their base class defined here, as an instantiation of ProfilerEnum // --------------------------------------------------------------------------------------- -typedef ProfilerEnum< ICorProfilerObjectEnum, IID_ICorProfilerObjectEnum, ObjectID > ProfilerObjectEnum; +typedef ProfilerEnum< ICorProfilerObjectEnum, IID_ICorProfilerObjectEnum, ObjectID > ProfilerObjectEnumBase; typedef ProfilerEnum< ICorProfilerFunctionEnum, IID_ICorProfilerFunctionEnum, COR_PRF_FUNCTION > ProfilerFunctionEnumBase; typedef ProfilerEnum< ICorProfilerModuleEnum, IID_ICorProfilerModuleEnum, ModuleID > ProfilerModuleEnumBase; typedef ProfilerEnum< ICorProfilerThreadEnum, IID_ICorProfilerThreadEnum, ThreadID > ProfilerThreadEnumBase; @@ -470,6 +470,17 @@ class ProfilerFunctionEnum : public ProfilerFunctionEnumBase }; +// --------------------------------------------------------------------------------------- +// This class derives from the template enumerator instantiation, and provides specific +// code to populate the enumerator with the function list + +class ProfilerObjectEnum : public ProfilerObjectEnumBase +{ +public: + BOOL Init(); +}; + + // --------------------------------------------------------------------------------------- // This class derives from the template enumerator instantiation, and provides specific // code to populate the enumerator with the module list diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp index 1d78588b328a51..455cfc32e44a6b 100644 --- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp @@ -125,6 +125,7 @@ #include "safemath.h" #include "threadsuspend.h" #include "inlinetracking.h" +#include "frozenobjectheap.h" #ifdef PROFILING_SUPPORTED #include "profilinghelper.h" @@ -571,6 +572,10 @@ COM_METHOD ProfToEEInterfaceImpl::QueryInterface(REFIID id, void ** pInterface) { *pInterface = static_cast(this); } + else if (id == IID_ICorProfilerInfo14) + { + *pInterface = static_cast(this); + } else if (id == IID_IUnknown) { *pInterface = static_cast(static_cast(this)); @@ -7586,6 +7591,102 @@ HRESULT ProfToEEInterfaceImpl::GetObjectIDFromHandle( return S_OK; } +HRESULT ProfToEEInterfaceImpl::EnumerateNonGCObjects(ICorProfilerObjectEnum** ppEnum) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + EE_THREAD_NOT_REQUIRED; + + // FrozenObjectHeapManager takes a lock + CAN_TAKE_LOCK; + } + CONTRACTL_END; + + PROFILER_TO_CLR_ENTRYPOINT_SYNC_EX(kP2EEAllowableAfterAttach, + (LF_CORPROF, LL_INFO1000, "**PROF: EnumerateNonGCObjects.\n")); + + if (NULL == ppEnum) + { + return E_INVALIDARG; + } + + HRESULT hr = S_OK; + + *ppEnum = NULL; + + NewHolder pEnum(new (nothrow) ProfilerObjectEnum()); + if (pEnum == NULL || !pEnum->Init()) + { + return E_OUTOFMEMORY; + } + + *ppEnum = (ICorProfilerObjectEnum*)pEnum.Extract(); + + return hr; +} + +HRESULT ProfToEEInterfaceImpl::GetNonGCHeapBounds(ULONG cObjectRanges, + ULONG *pcObjectRanges, + COR_PRF_NONGC_HEAP_RANGE ranges[]) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + EE_THREAD_NOT_REQUIRED; + + // FrozenObjectHeapManager takes a lock + CAN_TAKE_LOCK; + } + CONTRACTL_END; + + if ((cObjectRanges > 0) && (ranges == nullptr)) + { + // Copy GetGenerationBounds's behavior for consistency + return E_INVALIDARG; + } + + FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); + CrstHolder ch(&foh->m_Crst); + + const unsigned segmentsCount = foh->m_FrozenSegments.GetCount(); + FrozenObjectSegment** segments = foh->m_FrozenSegments.GetElements(); + if (segments != nullptr && segmentsCount > 0) + { + const ULONG segmentsToInspect = min(cObjectRanges, (ULONG)segmentsCount); + + for (unsigned segIdx = 0; segIdx < segmentsToInspect; segIdx++) + { + uint8_t* firstObj = segments[segIdx]->m_pStart + sizeof(ObjHeader); + + // Start of the segment (first object) + ranges[segIdx].rangeStart = (ObjectID)firstObj; + + // Total size reserved for a segment + ranges[segIdx].rangeLengthReserved = (UINT_PTR)segments[segIdx]->m_Size; + + // Size of the segment that is currently in use + ranges[segIdx].rangeLength = (UINT_PTR)(segments[segIdx]->m_pCurrent - firstObj); + } + + if (pcObjectRanges != nullptr) + { + *pcObjectRanges = (ULONG)segmentsCount; + } + } + else + { + if (pcObjectRanges != nullptr) + { + *pcObjectRanges = 0; + } + } + return S_OK; +} /* * GetStringLayout @@ -9141,6 +9242,15 @@ HRESULT ProfToEEInterfaceImpl::GetObjectGeneration(ObjectID objectId, IGCHeap *hp = GCHeapUtilities::GetGCHeap(); + if (hp->IsInFrozenSegment((Object*)objectId)) + { + range->generation = (COR_PRF_GC_GENERATION)INT32_MAX; + range->rangeStart = 0; + range->rangeLength = 0; + range->rangeLengthReserved = 0; + return CORPROF_E_NOT_GC_OBJECT; + } + uint8_t* pStart; uint8_t* pAllocated; uint8_t* pReserved; diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.h b/src/coreclr/vm/proftoeeinterfaceimpl.h index 8fedc66e455e9d..a0f9ab681d2000 100644 --- a/src/coreclr/vm/proftoeeinterfaceimpl.h +++ b/src/coreclr/vm/proftoeeinterfaceimpl.h @@ -150,7 +150,7 @@ typedef struct _PROFILER_STACK_WALK_DATA PROFILER_STACK_WALK_DATA; // from the profiler implementation. The profiler will call back on the v-table // to get at EE internals as required. -class ProfToEEInterfaceImpl : public ICorProfilerInfo13 +class ProfToEEInterfaceImpl : public ICorProfilerInfo14 { private: ProfilerInfo *m_pProfilerInfo; @@ -722,6 +722,17 @@ class ProfToEEInterfaceImpl : public ICorProfilerInfo13 // end ICorProfilerInfo13 + // begin ICorProfilerInfo14 + + COM_METHOD EnumerateNonGCObjects( + ICorProfilerObjectEnum** ppEnum); + + COM_METHOD GetNonGCHeapBounds(ULONG cObjectRanges, + ULONG * pcObjectRanges, + COR_PRF_NONGC_HEAP_RANGE ranges[]); + + // end ICorProfilerInfo14 + protected: // Internal Helper Functions diff --git a/src/coreclr/vm/riscv64/asmconstants.h b/src/coreclr/vm/riscv64/asmconstants.h index e61abe2ea57e7d..12aedda2db5f87 100644 --- a/src/coreclr/vm/riscv64/asmconstants.h +++ b/src/coreclr/vm/riscv64/asmconstants.h @@ -141,7 +141,7 @@ ASMCONSTANTS_C_ASSERT(SIZEOF__GSCookie == sizeof(GSCookie)); #define SIZEOF__Frame 0x10 ASMCONSTANTS_C_ASSERT(SIZEOF__Frame == sizeof(Frame)); -#define SIZEOF__CONTEXT 0x210 +#define SIZEOF__CONTEXT 0x220 ASMCONSTANTS_C_ASSERT(SIZEOF__CONTEXT == sizeof(T_CONTEXT)); diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 5972c887effad4..e0eba7e1726134 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -2413,7 +2413,8 @@ FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pM REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); TypeHandle instType = refType->GetType(); - MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod); + MethodTable* pCanonMT = instType.GetMethodTable()->GetCanonicalMethodTable(); + MethodDesc* pMDescInCanonMT = pCanonMT->GetParallelMethodDesc(pMethod); return pMDescInCanonMT; } diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 8be38ce3b6e7df..71a32d4fe164e0 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -46,15 +46,12 @@ class SyncBlockArray BYTE m_Blocks[MAXSYNCBLOCK * sizeof (SyncBlock)]; }; -// For in-place constructor -BYTE g_SyncBlockCacheInstance[sizeof(SyncBlockCache)]; +SyncBlockCache g_SyncBlockCacheInstance; SPTR_IMPL (SyncBlockCache, SyncBlockCache, s_pSyncBlockCache); #ifndef DACCESS_COMPILE - - #ifndef TARGET_UNIX // static SLIST_HEADER InteropSyncBlockInfo::s_InteropInfoStandbyList; @@ -463,27 +460,7 @@ size_t BitMapSize (size_t cacheSize) // // *************************************************************************** -SyncBlockCache::SyncBlockCache() - : m_pCleanupBlockList(NULL), - m_FreeBlockList(NULL), - - // NOTE: CRST_UNSAFE_ANYMODE prevents a GC mode switch when entering this crst. - // If you remove this flag, we will switch to preemptive mode when entering - // g_criticalSection, which means all functions that enter it will become - // GC_TRIGGERS. (This includes all uses of LockHolder around SyncBlockCache::GetSyncBlockCache(). - // So be sure to update the contracts if you remove this flag. - m_CacheLock(CrstSyncBlockCache, (CrstFlags) (CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD)), - - m_FreeCount(0), - m_ActiveCount(0), - m_SyncBlocks(0), - m_FreeSyncBlock(0), - m_FreeSyncTableIndex(1), - m_FreeSyncTableList(0), - m_SyncTableSize(SYNC_TABLE_INITIAL_SIZE), - m_OldSyncTables(0), - m_bSyncBlockCleanupInProgress(FALSE), - m_EphemeralBitmap(0) +void SyncBlockCache::Init() { CONTRACTL { @@ -494,11 +471,30 @@ SyncBlockCache::SyncBlockCache() INJECT_FAULT(COMPlusThrowOM()); } CONTRACTL_END; -} + m_pCleanupBlockList = NULL; + m_FreeBlockList = NULL; + + // NOTE: CRST_UNSAFE_ANYMODE prevents a GC mode switch when entering this crst. + // If you remove this flag, we will switch to preemptive mode when entering + // g_criticalSection, which means all functions that enter it will become + // GC_TRIGGERS. (This includes all uses of LockHolder around SyncBlockCache::GetSyncBlockCache(). + // So be sure to update the contracts if you remove this flag. + m_CacheLock.Init(CrstSyncBlockCache, (CrstFlags) (CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD)); + + m_FreeCount = 0; + m_ActiveCount = 0; + m_SyncBlocks = 0; + m_FreeSyncBlock = 0; + m_FreeSyncTableIndex = 1; + m_FreeSyncTableList = 0; + m_SyncTableSize = SYNC_TABLE_INITIAL_SIZE; + m_OldSyncTables = 0; + m_bSyncBlockCleanupInProgress = FALSE; + m_EphemeralBitmap = 0; +} -// This method is NO longer called. -SyncBlockCache::~SyncBlockCache() +void SyncBlockCache::Destroy() { CONTRACTL { @@ -514,6 +510,8 @@ SyncBlockCache::~SyncBlockCache() //@todo we can clear this fast too I guess m_pCleanupBlockList = NULL; + m_CacheLock.Destroy(); + // destruct all arrays while (m_SyncBlocks) { @@ -655,7 +653,8 @@ void SyncBlockCache::Start() #endif SyncTableEntry::GetSyncTableEntry()[0].m_SyncBlock = 0; - SyncBlockCache::GetSyncBlockCache() = new (&g_SyncBlockCacheInstance) SyncBlockCache; + SyncBlockCache::GetSyncBlockCache() = &g_SyncBlockCacheInstance; + g_SyncBlockCacheInstance.Init(); SyncBlockCache::GetSyncBlockCache()->m_EphemeralBitmap = bm; @@ -681,7 +680,7 @@ void SyncBlockCache::Stop() // sync blocks which are live and thus must have their critical sections destroyed. if (SyncBlockCache::GetSyncBlockCache()) { - delete SyncBlockCache::GetSyncBlockCache(); + SyncBlockCache::GetSyncBlockCache()->Destroy(); SyncBlockCache::GetSyncBlockCache() = 0; } diff --git a/src/coreclr/vm/syncblk.h b/src/coreclr/vm/syncblk.h index 32ad8c522076d0..a45d03e7bf2e6d 100644 --- a/src/coreclr/vm/syncblk.h +++ b/src/coreclr/vm/syncblk.h @@ -1309,7 +1309,7 @@ class SyncBlockCache private: PTR_SLink m_pCleanupBlockList; // list of sync blocks that need cleanup SLink* m_FreeBlockList; // list of free sync blocks - Crst m_CacheLock; // cache lock + CrstStatic m_CacheLock; // cache lock DWORD m_FreeCount; // count of active sync blocks DWORD m_ActiveCount; // number active SyncBlockArray *m_SyncBlocks; // Array of new SyncBlocks. @@ -1345,19 +1345,9 @@ class SyncBlockCache SPTR_DECL(SyncBlockCache, s_pSyncBlockCache); static SyncBlockCache*& GetSyncBlockCache(); - void *operator new(size_t size, void *pInPlace) - { - LIMITED_METHOD_CONTRACT; - return pInPlace; - } - - void operator delete(void *p) - { - LIMITED_METHOD_CONTRACT; - } - - SyncBlockCache(); - ~SyncBlockCache(); + // Note: No constructors/destructors - global instance + void Init(); + void Destroy(); static void Attach(); static void Detach(); diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index 2dd6b621599728..76b133b0d1248d 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -5533,6 +5533,7 @@ void ThreadStore::TriggerGCForDeadThreadsIfNecessary() } unsigned exposedObjectGeneration = gcHeap->WhichGeneration(exposedObject); + _ASSERTE(exposedObjectGeneration != INT32_MAX); SIZE_T newDeadThreadGenerationCount = ++s_DeadThreadGenerationCounts[exposedObjectGeneration]; if (exposedObjectGeneration > gcGenerationToTrigger && newDeadThreadGenerationCount >= generationCountThreshold) { diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index ffff61764fc97c..e7414425ece2d9 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -2404,7 +2404,7 @@ void Thread::RareEnablePreemptiveGC() } } - STRESS_LOG0(LF_SYNC, LL_INFO100000, " RareEnablePreemptiveGC: leaving.\n"); + STRESS_LOG0(LF_SYNC, LL_INFO100000, "RareEnablePreemptiveGC: leaving.\n"); } // Called when we are passing through a safe point in CommonTripThread or diff --git a/src/coreclr/vm/typedesc.cpp b/src/coreclr/vm/typedesc.cpp index db045069c2691f..0650f58475a9be 100644 --- a/src/coreclr/vm/typedesc.cpp +++ b/src/coreclr/vm/typedesc.cpp @@ -87,6 +87,23 @@ PTR_Module TypeDesc::GetLoaderModule() } } +BOOL TypeDesc::IsSharedByGenericInstantiations() +{ + LIMITED_METHOD_DAC_CONTRACT; + + if (HasTypeParam()) + { + return GetRootTypeParam().IsCanonicalSubtype(); + } + + if (IsFnPtr()) + { + return dac_cast(this)->IsSharedByGenericInstantiations(); + } + + return FALSE; +} + PTR_BaseDomain TypeDesc::GetDomain() { CONTRACTL @@ -1634,18 +1651,26 @@ OBJECTREF TypeVarTypeDesc::GetManagedClassObject() TypeHandle * FnPtrTypeDesc::GetRetAndArgTypes() { - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - + LIMITED_METHOD_CONTRACT; return m_RetAndArgTypes; } // FnPtrTypeDesc::GetRetAndArgTypes +BOOL +FnPtrTypeDesc::IsSharedByGenericInstantiations() +{ + LIMITED_METHOD_DAC_CONTRACT; + + for (DWORD i = 0; i <= m_NumArgs; i++) + { + if (m_RetAndArgTypes[i].IsCanonicalSubtype()) + { + return TRUE; + } + } + return FALSE; +} // FnPtrTypeDesc::IsSharedByGenericInstantiations + #ifndef DACCESS_COMPILE // Returns TRUE if all return and argument types are externally visible. @@ -1660,10 +1685,9 @@ FnPtrTypeDesc::IsExternallyVisible() const } CONTRACTL_END; - const TypeHandle * rgRetAndArgTypes = GetRetAndArgTypes(); for (DWORD i = 0; i <= m_NumArgs; i++) { - if (!rgRetAndArgTypes[i].IsExternallyVisible()) + if (!m_RetAndArgTypes[i].IsExternallyVisible()) { return FALSE; } diff --git a/src/coreclr/vm/typedesc.h b/src/coreclr/vm/typedesc.h index 7134195d8fd6a6..a306930342aee6 100644 --- a/src/coreclr/vm/typedesc.h +++ b/src/coreclr/vm/typedesc.h @@ -181,6 +181,8 @@ class TypeDesc return GetLoaderModule()->GetLoaderAllocator(); } + BOOL IsSharedByGenericInstantiations(); + protected: // See methodtable.h for details of the flags with the same name there enum @@ -524,6 +526,8 @@ class FnPtrTypeDesc : public TypeDesc return PTR_TypeHandle(m_RetAndArgTypes); } + BOOL IsSharedByGenericInstantiations(); + #ifndef DACCESS_COMPILE // Returns TRUE if all return and argument types are externally visible. BOOL IsExternallyVisible() const; diff --git a/src/coreclr/vm/typehandle.cpp b/src/coreclr/vm/typehandle.cpp index 292d14f036f952..647e14eeaa6f64 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -325,12 +325,15 @@ BOOL TypeHandle::IsSharedByGenericInstantiations() const { LIMITED_METHOD_DAC_CONTRACT; - if (IsArray()) + if (IsTypeDesc()) { - return GetArrayElementTypeHandle().IsCanonicalSubtype(); + return AsTypeDesc()->IsSharedByGenericInstantiations(); } - else if (!IsTypeDesc()) + else { + if (IsArray()) + return GetArrayElementTypeHandle().IsCanonicalSubtype(); + return AsMethodTable()->IsSharedByGenericInstantiations(); } diff --git a/src/installer/Directory.Build.props b/src/installer/Directory.Build.props index 44582bc378b271..33a094c082f790 100644 --- a/src/installer/Directory.Build.props +++ b/src/installer/Directory.Build.props @@ -8,8 +8,8 @@ $(TargetArchitecture) $(DefineConstants),DEBUG,TRACE $(DefineConstants),TRACE - $(OutputRid) - $(OutputRid) + $(OutputRID) + $(OutputRID) diff --git a/src/installer/pkg/projects/Directory.Build.props b/src/installer/pkg/projects/Directory.Build.props index e95f6a113e7874..5f04dc00030530 100644 --- a/src/installer/pkg/projects/Directory.Build.props +++ b/src/installer/pkg/projects/Directory.Build.props @@ -122,7 +122,7 @@ @(RestoreBuildRID) - $(OutputRid) + $(OutputRID) 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 index 315a1dc8b44751..3995419fc90984 100644 --- a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj +++ b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj @@ -27,7 +27,6 @@ - diff --git a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/sdk/Sdk.props b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/sdk/Sdk.props deleted file mode 100644 index 7772d9059c4e56..00000000000000 --- a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/sdk/Sdk.props +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - true - - - - - - diff --git a/src/installer/pkg/projects/host-packages.proj b/src/installer/pkg/projects/host-packages.proj index 9a6e896b59f87f..772ee1b0f6369f 100644 --- a/src/installer/pkg/projects/host-packages.proj +++ b/src/installer/pkg/projects/host-packages.proj @@ -4,6 +4,6 @@ - + diff --git a/src/installer/pkg/projects/nativeaot-packages.proj b/src/installer/pkg/projects/nativeaot-packages.proj index 10ab1d60c56fa5..592b4565154216 100644 --- a/src/installer/pkg/projects/nativeaot-packages.proj +++ b/src/installer/pkg/projects/nativeaot-packages.proj @@ -4,7 +4,7 @@ - + diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index 8c1d243d6bbb5f..5760758d70ecb5 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -77,6 +77,7 @@ + @@ -174,6 +175,18 @@ + + + + + + + + + + + + @@ -240,7 +253,6 @@ - diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj index e442fdcfc41895..c28c6ea8fb53ca 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj @@ -48,7 +48,6 @@ ;RuntimeIdentifier=$(PackageRID) ;NativeAotSupported=$(NativeAotSupported) ;CoreCLRArtifactsPath=$(CoreCLRArtifactsPath) - ;StripSymbols=true ;ObjCopyName=$(ObjCopyName) ;R2ROverridePath=$(MSBuildThisFileDirectory)ReadyToRun.targets"> - true - false + true + false false false + + false true true The .NET Shared Framework + + NativeAOT + Mono @@ -38,7 +43,7 @@ We add the entries here to ensure that we don't fail the validation that every file included in the runtime pack is in the platform manifest without adding the entries to the manifest in the ref pack. --> - + @@ -47,14 +52,18 @@ + + + + - - + + @@ -64,7 +73,8 @@ runtimes/$(RuntimeIdentifier)/native - + + tools @@ -87,7 +97,7 @@ runtimes/$(RuntimeIdentifier)/native/Mono.debug.framework/%(RecursiveDir) - runtimes/$(RuntimeIdentifier)/build/%(RecursiveDir) @@ -110,6 +120,8 @@ Condition="Exists('$(CoreCLRArtifactsPath)StandardOptimizationData.mibc')"> tools + + @@ -123,7 +135,7 @@ - + <_diaSymArch>$(_hostArch) <_diaSymReaderPath>$(PkgMicrosoft_DiaSymReader_Native)/runtimes/win/native/Microsoft.DiaSymReader.Native.$(_diaSymArch).dll @@ -134,7 +146,7 @@ <_diaSymReaderTargetArchPath>$(PkgMicrosoft_DiaSymReader_Native)/runtimes/win/native/Microsoft.DiaSymReader.Native.$(_diaSymTargetArch).dll - + runtimes/$(CoreCLRCrossTargetComponentDirName)_$(TargetArchitecture)/native @@ -160,10 +172,10 @@ - + - + true diff --git a/src/installer/tests/Directory.Build.targets b/src/installer/tests/Directory.Build.targets index 7691ad32cee765..43154f340b7807 100644 --- a/src/installer/tests/Directory.Build.targets +++ b/src/installer/tests/Directory.Build.targets @@ -73,7 +73,7 @@ - + diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs index c881c56d656b6b..074c292d715a36 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs @@ -37,40 +37,6 @@ internal static partial class Crypto [LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "CryptoNative_GetMaxMdSize")] private static partial int GetMaxMdSize(); - [LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "CryptoNative_Pbkdf2")] - private static unsafe partial int Pbkdf2( - byte* pPassword, - int passwordLength, - byte* pSalt, - int saltLength, - int iterations, - IntPtr digestEvp, - byte* pDestination, - int destinationLength); - - internal static unsafe int Pbkdf2( - ReadOnlySpan password, - ReadOnlySpan salt, - int iterations, - IntPtr digestEvp, - Span destination) - { - fixed (byte* pPassword = password) - fixed (byte* pSalt = salt) - fixed (byte* pDestination = destination) - { - return Pbkdf2( - pPassword, - password.Length, - pSalt, - salt.Length, - iterations, - digestEvp, - pDestination, - destination.Length); - } - } - internal static readonly int EVP_MAX_MD_SIZE = GetMaxMdSize(); } } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs b/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs index 693b908a0c6910..5294d846ad7e8f 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs @@ -9,5 +9,11 @@ internal static unsafe partial class JsGlobalization { [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern unsafe int CompareString(out string exceptionMessage, in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern unsafe bool StartsWith(out string exceptionMessage, in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern unsafe bool EndsWith(out string exceptionMessage, in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options); } } 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 485b08c61b81b3..14a6066eeb3b75 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 @@ -4,6 +4,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Net; @@ -226,7 +227,7 @@ internal static unsafe SafeSslContextHandle AllocateSslContext(SslAuthentication { SetSslCertificate(sslCtx, sslAuthenticationOptions.CertificateContext.CertificateHandle, sslAuthenticationOptions.CertificateContext.KeyHandle); - if (sslAuthenticationOptions.CertificateContext.IntermediateCertificates.Length > 0) + if (sslAuthenticationOptions.CertificateContext.IntermediateCertificates.Count > 0) { if (!Ssl.AddExtraChainCertificates(sslCtx, sslAuthenticationOptions.CertificateContext.IntermediateCertificates)) { @@ -274,7 +275,7 @@ internal static void UpdateClientCertificate(SafeSslHandle ssl, SslAuthenticatio throw CreateSslException(SR.net_ssl_use_private_key_failed); } - if (sslAuthenticationOptions.CertificateContext.IntermediateCertificates.Length > 0) + if (sslAuthenticationOptions.CertificateContext.IntermediateCertificates.Count > 0) { if (!Ssl.AddExtraChainCertificates(ssl, sslAuthenticationOptions.CertificateContext.IntermediateCertificates)) { 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 a7d5d5d28c95dd..71d23c26d34532 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 @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Net.Security; using System.Runtime.InteropServices; @@ -262,10 +263,10 @@ internal static unsafe void SslStapleOcsp(SafeSslHandle ssl, ReadOnlySpan } } - internal static bool AddExtraChainCertificates(SafeSslHandle ssl, ReadOnlySpan chain) + internal static bool AddExtraChainCertificates(SafeSslHandle ssl, ReadOnlyCollection chain) { // send pre-computed list of intermediates. - for (int i = 0; i < chain.Length; i++) + for (int i = 0; i < chain.Count; i++) { SafeX509Handle dupCertHandle = Crypto.X509UpRef(chain[i].Handle); Crypto.CheckValidOpenSslHandle(dupCertHandle); diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs index 44f3e424e99ca9..aae292fe35c64b 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Net.Security; using System.Runtime.InteropServices; @@ -35,10 +36,10 @@ internal static partial class Ssl [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCaching")] internal static unsafe partial int SslCtxSetCaching(SafeSslContextHandle ctx, int mode, int cacheSize, int contextIdLength, Span contextId, delegate* unmanaged neewSessionCallback, delegate* unmanaged removeSessionCallback); - internal static bool AddExtraChainCertificates(SafeSslContextHandle ctx, ReadOnlySpan chain) + internal static bool AddExtraChainCertificates(SafeSslContextHandle ctx, ReadOnlyCollection chain) { // send pre-computed list of intermediates. - for (int i = 0; i < chain.Length; i++) + for (int i = 0; i < chain.Count; i++) { SafeX509Handle dupCertHandle = Crypto.X509UpRef(chain[i].Handle); Crypto.CheckValidOpenSslHandle(dupCertHandle); diff --git a/src/libraries/Common/src/System/IO/Archiving.Utils.Windows.cs b/src/libraries/Common/src/System/IO/Archiving.Utils.Windows.cs index 4a3f3728134f33..ddbc2712279dbf 100644 --- a/src/libraries/Common/src/System/IO/Archiving.Utils.Windows.cs +++ b/src/libraries/Common/src/System/IO/Archiving.Utils.Windows.cs @@ -8,7 +8,7 @@ namespace System.IO { internal static partial class ArchivingUtils { - private static readonly IndexOfAnyValues s_illegalChars = IndexOfAnyValues.Create( + private static readonly SearchValues s_illegalChars = SearchValues.Create( "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F" + "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F" + "\"*:<>?|"); diff --git a/src/libraries/Common/src/System/Net/CaseInsensitiveAscii.cs b/src/libraries/Common/src/System/Net/CaseInsensitiveAscii.cs index 4bfdf23ca7cd84..f16b3154ede896 100644 --- a/src/libraries/Common/src/System/Net/CaseInsensitiveAscii.cs +++ b/src/libraries/Common/src/System/Net/CaseInsensitiveAscii.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; +using System.Diagnostics; +using System.Text; namespace System.Net { @@ -106,22 +108,9 @@ private static int FastGetHashCode(string myString) } if (secondString != null) { - int index = firstString.Length; - if (index == secondString.Length) - { - if (FastGetHashCode(firstString) == FastGetHashCode(secondString)) - { - while (index > 0) - { - index--; - if (AsciiToLower[firstString[index]] != AsciiToLower[secondString[index]]) - { - return false; - } - } - return true; - } - } + Debug.Assert(Ascii.IsValid(firstString) || Ascii.IsValid(secondString), "Expected at least one of the inputs to be valid ASCII"); + + return Ascii.EqualsIgnoreCase(firstString, secondString); } return false; } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/ReadMe.SharedCode.md b/src/libraries/Common/src/System/Net/Http/aspnetcore/ReadMe.SharedCode.md index 44d726b85527b0..cde2206541b1cf 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/ReadMe.SharedCode.md +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/ReadMe.SharedCode.md @@ -34,3 +34,10 @@ dotnet/aspnetcore code paths: ### Running dotnet/aspnetcore tests: - `(aspnetcore) PS D:\github\aspnetcore\src\Shared\test\Shared.Tests> dotnet test` - `(aspnetcore) PS D:\github\aspnetcore\src\servers\Kestrel\core\test> dotnet test` + +## GitHub Actions + +In dotnet/aspnetcore, the [runtime-sync](https://github.com/dotnet/aspnetcore/actions/workflows/runtime-sync.yml) GitHub action automatically creates PRs to pull in changes from dotnet/runtime. + +In dotnet/runtime, the [aspnetcore-sync](https://github.com/dotnet/runtime/actions/workflows/aspnetcore-sync.yml) GitHub action must be run **manually** to create PRs to pull in changes from dotnet/aspnetcore. +This is expected to be less common. diff --git a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs index 6dec165bbe6d00..b9961a39d86765 100644 --- a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs +++ b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs @@ -9,8 +9,8 @@ namespace System.Net.NetworkInformation { internal static class UnixCommandLinePing { - // Ubuntu has ping under /bin, OSX under /sbin, ArchLinux under /usr/bin, Android under /system/bin. - private static readonly string[] s_binFolders = { "/bin/", "/sbin/", "/usr/bin/", "/system/bin" }; + // Ubuntu has ping under /bin, OSX under /sbin, ArchLinux under /usr/bin, Android under /system/bin, NixOS under /run/current-system/sw/bin. + private static readonly string[] s_binFolders = { "/bin", "/sbin", "/usr/bin", "/system/bin", "/run/current-system/sw/bin" }; private const string s_ipv4PingFile = "ping"; private const string s_ipv6PingFile = "ping6"; diff --git a/src/libraries/Common/src/System/Net/Security/TargetHostNameHelper.cs b/src/libraries/Common/src/System/Net/Security/TargetHostNameHelper.cs new file mode 100644 index 00000000000000..f4dbaeee55b783 --- /dev/null +++ b/src/libraries/Common/src/System/Net/Security/TargetHostNameHelper.cs @@ -0,0 +1,83 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace System.Net.Security +{ + internal static class TargetHostNameHelper + { + private static readonly IdnMapping s_idnMapping = new IdnMapping(); + private static readonly SearchValues s_safeDnsChars = + SearchValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"); + + private static bool IsSafeDnsString(ReadOnlySpan name) => + name.IndexOfAnyExcept(s_safeDnsChars) < 0; + + internal static string NormalizeHostName(string? targetHost) + { + if (string.IsNullOrEmpty(targetHost)) + { + return string.Empty; + } + + // RFC 6066 section 3 says to exclude trailing dot from fully qualified DNS hostname + targetHost = targetHost.TrimEnd('.'); + + try + { + return s_idnMapping.GetAscii(targetHost); + } + catch (ArgumentException) when (IsSafeDnsString(targetHost)) + { + // Seems like name that does not confrom to IDN but apers somewhat valid according to original DNS rfc. + } + + return targetHost; + } + + // Simplified version of IPAddressParser.Parse to avoid allocations and dependencies. + // It purposely ignores scopeId as we don't really use so we do not need to map it to actual interface id. + internal static unsafe bool IsValidAddress(string? hostname) + { + if (string.IsNullOrEmpty(hostname)) + { + return false; + } + + ReadOnlySpan ipSpan = hostname.AsSpan(); + + int end = ipSpan.Length; + + if (ipSpan.Contains(':')) + { + // The address is parsed as IPv6 if and only if it contains a colon. This is valid because + // we don't support/parse a port specification at the end of an IPv4 address. + Span numbers = stackalloc ushort[IPAddressParserStatics.IPv6AddressShorts]; + + fixed (char* ipStringPtr = &MemoryMarshal.GetReference(ipSpan)) + { + return IPv6AddressHelper.IsValidStrict(ipStringPtr, 0, ref end); + } + } + else if (char.IsDigit(ipSpan[0])) + { + long tmpAddr; + + fixed (char* ipStringPtr = &MemoryMarshal.GetReference(ipSpan)) + { + tmpAddr = IPv4AddressHelper.ParseNonCanonical(ipStringPtr, 0, ref end, notImplicitFile: true); + } + + if (tmpAddr != IPv4AddressHelper.Invalid && end == ipSpan.Length) + { + return true; + } + } + + return false; + } + } +} diff --git a/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs b/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs index 3ecc779aca2235..dafe325c8c07b8 100644 --- a/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs +++ b/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs @@ -29,8 +29,8 @@ internal static partial class WebSocketValidate private const int InvalidCloseStatusCodesTo = 999; // [0x21, 0x7E] except separators "()<>@,;:\\\"/[]?={} ". - private static readonly IndexOfAnyValues s_validSubprotocolChars = - IndexOfAnyValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"); + private static readonly SearchValues s_validSubprotocolChars = + SearchValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"); internal static void ThrowIfInvalidState(WebSocketState currentState, bool isDisposed, WebSocketState[] validStates) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/IncrementalHash.netfx.cs b/src/libraries/Common/src/System/Security/Cryptography/IncrementalHash.netfx.cs new file mode 100644 index 00000000000000..b60bac3f6ede6e --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/IncrementalHash.netfx.cs @@ -0,0 +1,231 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#if !NETFRAMEWORK || NET471_OR_GREATER +#error "This implementation of IncrementalHash should only be used for .NET Framework where it is not available" +#endif + +using System.Diagnostics; + +namespace System.Security.Cryptography +{ + /// + /// Provides support for computing a hash or HMAC value incrementally across several segments. + /// + internal sealed class IncrementalHash : IDisposable + { + private const int NTE_BAD_ALGID = unchecked((int)0x80090008); + + private readonly HashAlgorithmName _algorithmName; + private HashAlgorithm _hash; + private bool _disposed; + private bool _resetPending; + + private IncrementalHash(HashAlgorithmName name, HashAlgorithm hash) + { + Debug.Assert(!string.IsNullOrEmpty(name.Name)); + Debug.Assert(hash != null); + + _algorithmName = name; + _hash = hash; + } + + /// + /// Get the name of the algorithm being performed. + /// + public HashAlgorithmName AlgorithmName + { + get { return _algorithmName; } + } + + /// + /// Append the entire contents of to the data already processed in the hash or HMAC. + /// + /// The data to process. + /// is null. + /// The object has already been disposed. + public void AppendData(byte[] data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + + AppendData(data, 0, data.Length); + } + + /// + /// Append bytes of , starting at , + /// to the data already processed in the hash or HMAC. + /// + /// The data to process. + /// The offset into the byte array from which to begin using data. + /// The number of bytes in the array to use as data. + /// is null. + /// + /// is out of range. This parameter requires a non-negative number. + /// + /// + /// is out of range. This parameter requires a non-negative number less than + /// the value of . + /// + /// + /// is greater than + /// . - . + /// + /// The object has already been disposed. + public void AppendData(byte[] data, int offset, int count) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + if (offset < 0) + throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum); + if (count < 0 || (count > data.Length)) + throw new ArgumentOutOfRangeException(nameof(count)); + if ((data.Length - count) < offset) + throw new ArgumentException(SR.Argument_InvalidOffLen); + if (_disposed) + throw new ObjectDisposedException(nameof(IncrementalHash)); + + Debug.Assert(_hash != null); + + if (_resetPending) + { + _hash.Initialize(); + _resetPending = false; + } + + _hash.TransformBlock(data, offset, count, null, 0); + } + + /// + /// Retrieve the hash or HMAC for the data accumulated from prior calls to + /// , and return to the state the object + /// was in at construction. + /// + /// The computed hash or HMAC. + /// The object has already been disposed. + public byte[] GetHashAndReset() + { + if (_disposed) + throw new ObjectDisposedException(nameof(IncrementalHash)); + + Debug.Assert(_hash != null); + + if (_resetPending) + { + // No point in setting _resetPending to false, we're about to set it to true. + _hash.Initialize(); + } + + _hash.TransformFinalBlock(Array.Empty(), 0, 0); + byte[] hashValue = _hash.Hash; + _resetPending = true; + + return hashValue; + } + + /// + /// Release all resources used by the current instance of the + /// class. + /// + public void Dispose() + { + _disposed = true; + + if (_hash != null) + { + _hash.Dispose(); + _hash = null; + } + } + + /// + /// Create an for the algorithm specified by . + /// + /// The name of the hash algorithm to perform. + /// + /// An instance ready to compute the hash algorithm specified + /// by . + /// + /// + /// . is null, or + /// the empty string. + /// + /// is not a known hash algorithm. + public static IncrementalHash CreateHash(HashAlgorithmName hashAlgorithm) + { + if (string.IsNullOrEmpty(hashAlgorithm.Name)) + throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm)); + + return new IncrementalHash(hashAlgorithm, GetHashAlgorithm(hashAlgorithm)); + } + + /// + /// Create an for the Hash-based Message Authentication Code (HMAC) + /// algorithm utilizing the hash algorithm specified by , and a + /// key specified by . + /// + /// The name of the hash algorithm to perform within the HMAC. + /// + /// The secret key for the HMAC. The key can be any length, but a key longer than the output size + /// of the hash algorithm specified by will be hashed (using the + /// algorithm specified by ) to derive a correctly-sized key. Therefore, + /// the recommended size of the secret key is the output size of the hash specified by + /// . + /// + /// + /// An instance ready to compute the hash algorithm specified + /// by . + /// + /// + /// . is null, or + /// the empty string. + /// + /// is not a known hash algorithm. + public static IncrementalHash CreateHMAC(HashAlgorithmName hashAlgorithm, byte[] key) + { + if (key == null) + throw new ArgumentNullException(nameof(key)); + if (string.IsNullOrEmpty(hashAlgorithm.Name)) + throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm)); + + return new IncrementalHash(hashAlgorithm, GetHMAC(hashAlgorithm, key)); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "MD5 is used when the user asks for it.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 is used when the user asks for it.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5354", Justification = "SHA1 is used when the user asks for it.")] + private static HashAlgorithm GetHashAlgorithm(HashAlgorithmName hashAlgorithm) + { + if (hashAlgorithm == HashAlgorithmName.MD5) + return new MD5CryptoServiceProvider(); + if (hashAlgorithm == HashAlgorithmName.SHA1) + return new SHA1CryptoServiceProvider(); + if (hashAlgorithm == HashAlgorithmName.SHA256) + return new SHA256CryptoServiceProvider(); + if (hashAlgorithm == HashAlgorithmName.SHA384) + return new SHA384CryptoServiceProvider(); + if (hashAlgorithm == HashAlgorithmName.SHA512) + return new SHA512CryptoServiceProvider(); + + throw new CryptographicException(NTE_BAD_ALGID); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "MD5 is used when the user asks for it.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 is used when the user asks for it.")] + private static HashAlgorithm GetHMAC(HashAlgorithmName hashAlgorithm, byte[] key) + { + if (hashAlgorithm == HashAlgorithmName.MD5) + return new HMACMD5(key); + if (hashAlgorithm == HashAlgorithmName.SHA1) + return new HMACSHA1(key); + if (hashAlgorithm == HashAlgorithmName.SHA256) + return new HMACSHA256(key); + if (hashAlgorithm == HashAlgorithmName.SHA384) + return new HMACSHA384(key); + if (hashAlgorithm == HashAlgorithmName.SHA512) + return new HMACSHA512(key); + + throw new CryptographicException(NTE_BAD_ALGID); + } + } +} diff --git a/src/libraries/Common/src/System/TimeProvider.cs b/src/libraries/Common/src/System/TimeProvider.cs index 7d056754dc655a..d1489826eecc40 100644 --- a/src/libraries/Common/src/System/TimeProvider.cs +++ b/src/libraries/Common/src/System/TimeProvider.cs @@ -73,7 +73,7 @@ public DateTimeOffset GetLocalNow() /// /// The default implementation returns . /// - public virtual TimeZoneInfo LocalTimeZone { get => TimeZoneInfo.Local; } + public virtual TimeZoneInfo LocalTimeZone => TimeZoneInfo.Local; /// /// Gets the frequency of of high-frequency value per second. @@ -81,7 +81,7 @@ public DateTimeOffset GetLocalNow() /// /// The default implementation returns . For a given TimeProvider instance, the value must be idempotent and remain unchanged. /// - public virtual long TimestampFrequency { get => Stopwatch.Frequency; } + public virtual long TimestampFrequency => Stopwatch.Frequency; /// /// Gets the current high-frequency value designed to measure small time intervals with high accuracy in the timer mechanism. @@ -187,14 +187,27 @@ public SystemTimeProviderTimer(TimeSpan dueTime, TimeSpan period, TimerCallback #if SYSTEM_PRIVATE_CORELIB _timer = new TimerQueueTimer(callback, state, duration, periodTime, flowExecutionContext: true); #else - // We want to ensure the timer we create will be tracked as long as it is scheduled. - // To do that, we call the constructor which track only the callback which will make the time to be tracked by the scheduler - // then we call Change on the timer to set the desired duration and period. - _timer = new Timer(_ => callback(state)); - _timer.Change(duration, periodTime); + // We need to ensure the timer roots itself. Timer created with a duration and period argument + // only roots the state object, so to root the timer we need the state object to reference the + // timer recursively. + var timerState = new TimerState(callback, state); + timerState.Timer = _timer = new Timer(static s => + { + TimerState ts = (TimerState)s!; + ts.Callback(ts.State); + }, timerState, duration, periodTime); #endif // SYSTEM_PRIVATE_CORELIB } +#if !SYSTEM_PRIVATE_CORELIB + private sealed class TimerState(TimerCallback callback, object? state) + { + public TimerCallback Callback { get; } = callback; + public object? State { get; } = state; + public Timer? Timer { get; set; } + } +#endif + public bool Change(TimeSpan dueTime, TimeSpan period) { (uint duration, uint periodTime) = CheckAndGetValues(dueTime, period); diff --git a/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs b/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs index 32551b0736fc2f..da4da49fff976b 100644 --- a/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs +++ b/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs @@ -271,7 +271,7 @@ public static async Task> RunAnalyzerAndFixer( for (int i = 0; i < count; i++) { SourceText s = await proj.FindDocument(l[i]).GetTextAsync().ConfigureAwait(false); - results.Add(Replace(s.ToString(), "\r\n", "\n")); + results.Add(ReplaceLineEndings(s.ToString())); } } else @@ -279,14 +279,14 @@ public static async Task> RunAnalyzerAndFixer( for (int i = 0; i < count; i++) { SourceText s = await proj.FindDocument($"src-{i}.cs").GetTextAsync().ConfigureAwait(false); - results.Add(Replace(s.ToString(), "\r\n", "\n")); + results.Add(ReplaceLineEndings(s.ToString())); } } if (extraFile != null) { SourceText s = await proj.FindDocument(extraFile).GetTextAsync().ConfigureAwait(false); - results.Add(Replace(s.ToString(), "\r\n", "\n")); + results.Add(ReplaceLineEndings(s.ToString())); } return results; @@ -334,12 +334,11 @@ private static async Task RecreateDocumentAsync(Document document) return document.WithText(SourceText.From(newText.ToString(), newText.Encoding, newText.ChecksumAlgorithm)); } - private static string Replace(string text, string oldText, string newText) => - text.Replace( - oldText, newText + private static string ReplaceLineEndings(string text) => #if NETCOREAPP - , StringComparison.Ordinal + text.ReplaceLineEndings("\n"); +#else + text.Replace("\r\n", "\n"); #endif - ); } } diff --git a/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs b/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs index 6150907e43d813..27da31695a697b 100644 --- a/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs +++ b/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs @@ -16,7 +16,6 @@ public partial class FunctionPointerCallingConventionTests [InlineData(true)] [InlineData(false)] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ManagedCallingConvention(bool modified) { Type t = typeof(FunctionPointerHolder).Project(); @@ -38,7 +37,6 @@ public static unsafe void ManagedCallingConvention(bool modified) [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_Param_Unmodified(string methodName) { Type t = typeof(FunctionPointerHolder).Project(); @@ -57,7 +55,6 @@ public static unsafe void UnmanagedCallConv_Param_Unmodified(string methodName) [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall), typeof(CallConvThiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall), typeof(CallConvFastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_Param_Modified(string methodName, Type callingConventionRuntime) { Type callingConvention = callingConventionRuntime.Project(); @@ -75,7 +72,6 @@ public static unsafe void UnmanagedCallConv_Param_Modified(string methodName, Ty [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConvs_Return_Unmodified() { Type t = typeof(FunctionPointerHolder).Project(); @@ -96,7 +92,6 @@ public static unsafe void UnmanagedCallConvs_Return_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConvs_Return_Modified() { Type t = typeof(FunctionPointerHolder).Project(); @@ -124,7 +119,6 @@ public static unsafe void UnmanagedCallConvs_Return_Modified() [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall_SuppressGCTransition))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall_SuppressGCTransition))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_PhysicalModifiers_Unmodified(string methodName) { Type t = typeof(FunctionPointerHolder).Project(); @@ -144,7 +138,6 @@ public static unsafe void UnmanagedCallConv_PhysicalModifiers_Unmodified(string [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall_SuppressGCTransition), typeof(CallConvThiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall_SuppressGCTransition), typeof(CallConvFastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_PhysicalModifiers_Modified(string methodName, Type callingConventionRuntime) { Type suppressGcTransitionType = typeof(CallConvSuppressGCTransition).Project(); @@ -169,7 +162,6 @@ public static unsafe void UnmanagedCallConv_PhysicalModifiers_Modified(string me [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void GenericTypeParameter() { Type holder = typeof(FunctionPointerHolder).Project(); diff --git a/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs b/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs index a916b338472fd4..47cac32cfa76a5 100644 --- a/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs +++ b/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs @@ -32,7 +32,6 @@ public static unsafe void DifferentReturnValue() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ObjectEquals_ModifiedTypes() { Type holder = typeof(FunctionPointerHolder).Project(); @@ -49,7 +48,6 @@ public static unsafe void ObjectEquals_ModifiedTypes() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ObjectEquals_OneSideModifiedType() { Type holder = typeof(FunctionPointerHolder).Project(); @@ -86,7 +84,6 @@ public static unsafe void CallingConvention_Unmodified(string methodName1, strin [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Thiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Fastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void CallingConvention_Modified(string methodName1, string methodName2) { Type t = typeof(FunctionPointerHolder).Project(); diff --git a/src/libraries/Common/tests/System/FunctionPointerTests.cs b/src/libraries/Common/tests/System/FunctionPointerTests.cs index 9b06a179dc2a89..66458be8bcad90 100644 --- a/src/libraries/Common/tests/System/FunctionPointerTests.cs +++ b/src/libraries/Common/tests/System/FunctionPointerTests.cs @@ -164,7 +164,6 @@ public static unsafe void FunctionPointerReturn() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void RequiredModifiers() { Type t = typeof(FunctionPointerHolder).Project(); @@ -190,7 +189,6 @@ public static unsafe void RequiredModifiers() "System.Double(System.String, System.Boolean*&, System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass, System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyStruct&)", "String", "Boolean*&", "MyClass", "MyStruct&")] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodInfo( string methodName, string methodToStringPostfix, @@ -219,7 +217,6 @@ public static unsafe void MethodInfo( [InlineData(nameof(FunctionPointerHolder.Prop_Int), "System.Int32()")] [InlineData(nameof(FunctionPointerHolder.Prop_MyClass), "System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass()")] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Property(string name, string expectedToString) { Type t = typeof(FunctionPointerHolder).Project(); @@ -239,7 +236,6 @@ public static unsafe void Property(string name, string expectedToString) [InlineData(nameof(FunctionPointerHolder.Field_Int), "System.Int32()")] [InlineData(nameof(FunctionPointerHolder.Field_MyClass), "System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass()")] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Field(string name, string expectedToString) { Type t = typeof(FunctionPointerHolder).Project(); diff --git a/src/libraries/Common/tests/System/ModifiedTypeTests.cs b/src/libraries/Common/tests/System/ModifiedTypeTests.cs index 86909691ac0075..c429806989b65e 100644 --- a/src/libraries/Common/tests/System/ModifiedTypeTests.cs +++ b/src/libraries/Common/tests/System/ModifiedTypeTests.cs @@ -18,7 +18,6 @@ public partial class ModifiedTypeTests [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void TypeMembers() { FieldInfo fi = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings); @@ -125,7 +124,10 @@ void UnmodifiedTypeMembers(Type t) Assert.Null(t.DeclaringType); Assert.Null(t.ReflectedType); Assert.Null(t.TypeInitializer); - Assert.True(t.MetadataToken != 0); + + if (PlatformDetection.IsMetadataTokenSupported) + Assert.True(t.MetadataToken != 0); + Assert.False(t.IsNested); Assert.True(t.IsVisible); } @@ -152,7 +154,6 @@ void ModifiedTypeMembers(Type t) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Modified() { Type volatileInt = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings).GetModifiedFieldType(); @@ -191,7 +192,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Generic_Unmodified() { Type arrayGenericFcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._arrayGenericFcnPtr), Bindings).FieldType; @@ -213,7 +213,6 @@ public static unsafe void Fields_Generic_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Generic_Modified() { Type arrayGenericFcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._arrayGenericFcnPtr), Bindings).GetModifiedFieldType(); @@ -237,7 +236,6 @@ public static unsafe void Fields_Generic_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Methods_OpenGeneric_Unmodified() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_ArrayOpenGenericFcnPtr), Bindings); @@ -261,7 +259,6 @@ public static unsafe void Methods_OpenGeneric_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Methods_OpenGeneric_Modified() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_ArrayOpenGenericFcnPtr), Bindings); @@ -287,7 +284,6 @@ public static unsafe void Methods_OpenGeneric_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Unmodified() { Type volatileInt = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings).FieldType; @@ -320,7 +316,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Parameterized_Basic() { Type ptr_ptr_int = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._ptr_ptr_int), Bindings).GetModifiedFieldType(); @@ -342,7 +337,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Parameterized_FcnPtr() { Type ptr_fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._ptr_fcnPtr), Bindings).GetModifiedFieldType(); @@ -374,7 +368,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_VerifyIdempotency() { // Call these again to ensure any backing caching strategy works. @@ -386,7 +379,6 @@ public static unsafe void Fields_VerifyIdempotency() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodParameters() { ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_P0IntOut), Bindings).GetParameters(); @@ -411,7 +403,6 @@ public static unsafe void MethodParameters() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ConstructorParameters_Unmodified() { ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetConstructors()[0].GetParameters(); @@ -425,7 +416,6 @@ public static unsafe void ConstructorParameters_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ConstructorParameters_Modified() { ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetConstructors()[0].GetParameters(); @@ -440,7 +430,6 @@ public static unsafe void ConstructorParameters_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtrP0Out), Bindings).GetModifiedFieldType(); @@ -452,7 +441,6 @@ public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtrP0Out), Bindings).FieldType; @@ -464,7 +452,6 @@ public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Out), Bindings).FieldType; @@ -478,7 +465,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Unmodifie [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Modified() { // Modified @@ -494,7 +480,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Modified( [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Ref), Bindings).FieldType; @@ -509,7 +494,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Unmodifie [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Ref), Bindings).GetModifiedFieldType(); @@ -524,7 +508,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Modified( [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrRetP0Out), Bindings).FieldType; @@ -536,7 +519,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Unmodi [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrRetP0Out), Bindings).GetModifiedFieldType(); @@ -549,7 +531,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Modifi [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_complex_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_complex), Bindings).FieldType; @@ -574,7 +555,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_complex_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_complex_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_complex), Bindings).GetModifiedFieldType(); @@ -600,7 +580,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_complex_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Property_FcnPtr_Complex_Unmodified() { Type mt = typeof(ModifiedTypeHolder).Project().GetProperty(nameof(ModifiedTypeHolder.Property_FcnPtr_Complex), Bindings).PropertyType; @@ -618,7 +597,6 @@ public static unsafe void Property_FcnPtr_Complex_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Property_FcnPtr_Complex_Modified() { Type mt = typeof(ModifiedTypeHolder).Project().GetProperty(nameof(ModifiedTypeHolder.Property_FcnPtr_Complex), Bindings).GetModifiedPropertyType(); @@ -637,7 +615,6 @@ public static unsafe void Property_FcnPtr_Complex_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodWithGenericParameter_Unmodified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.MethodWithGenericParameter), Bindings); @@ -659,7 +636,6 @@ public static unsafe void MethodWithGenericParameter_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodWithGenericParameter_Modified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.MethodWithGenericParameter), Bindings); @@ -683,7 +659,6 @@ public static unsafe void MethodWithGenericParameter_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void GenericMethod_Unmodified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.GenericMethod), Bindings); @@ -697,7 +672,6 @@ public static unsafe void GenericMethod_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void GenericMethod_Modified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.GenericMethod), Bindings); @@ -711,7 +685,6 @@ public static unsafe void GenericMethod_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static void ParameterConstraints1() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_GenericWithParameterConstraint1), Bindings); @@ -737,7 +710,6 @@ public static void ParameterConstraints1() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static void ParameterConstraints2() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_GenericWithParameterConstraint2), Bindings); diff --git a/src/libraries/Common/tests/System/Net/Capability.Security.Unix.cs b/src/libraries/Common/tests/System/Net/Capability.Security.Unix.cs index f62d68fbd28627..3e08ee08a837ab 100644 --- a/src/libraries/Common/tests/System/Net/Capability.Security.Unix.cs +++ b/src/libraries/Common/tests/System/Net/Capability.Security.Unix.cs @@ -9,7 +9,7 @@ public static bool IsNtlmInstalled() { // GSS on Linux does not work with OpenSSL 3.0. Fix was submitted to gss-ntlm but it will take a while to make to // all supported distributions. The second part of the check should be removed when it does. - return Interop.NetSecurityNative.IsNtlmInstalled() && (!PlatformDetection.IsOpenSslSupported || PlatformDetection.OpenSslVersion.Major < 3) && !PlatformDetection.IsRedHatFamily7; + return Interop.NetSecurityNative.IsNtlmInstalled() && (!PlatformDetection.IsOpenSslSupported || PlatformDetection.OpenSslVersion.Major < 3); } } } diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile index 342575d22f26ac..67f5cf0aa617bd 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04 +FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04 # Prevents dialog prompting when installing packages ARG DEBIAN_FRONTEND=noninteractive @@ -8,6 +8,27 @@ COPY ./common/krb5.conf /etc/krb5.conf RUN apt-get update && \ apt-get install -y --no-install-recommends krb5-user gss-ntlmssp iputils-ping dnsutils nano +# Enable openssl legacy provider in system openssl config +RUN fixOpensslConf=$(mktemp) && \ + printf "#!/usr/bin/env sh\n\ + sed -i '\n\ + # Append 'legacy = legacy_sect' after 'default = default_sect' under [provider_sect] + /^default = default_sect/a legacy = legacy_sect\n\ + # Search for [default_sect] + /\[default_sect\]/ {\n\ + # Go to next line + n\n\ + # Uncomment '# activate = 1' + s/# //\n\ + # Append new [legacy_sect], with 'activate = 1' + a\n\ + a [legacy_sect]\n\ + a activate = 1\n\ + }\n\ + ' /etc/ssl/openssl.cnf\n" > $fixOpensslConf && \ + sh $fixOpensslConf && \ + rm $fixOpensslConf + # Set environment variable to turn on enterprise tests ENV DOTNET_RUNTIME_ENTERPRISETESTS_ENABLED 1 diff --git a/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs b/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs index d6345d3e923141..e95598dd47a666 100644 --- a/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs +++ b/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs @@ -34,8 +34,8 @@ public static void VerifyInvokeIsUsingEmit_Constructor() private static bool IsEmitInvokeSupported() { - // Emit is only used for Invoke when RuntimeFeature.IsDynamicCodeCompiled is true. - return RuntimeFeature.IsDynamicCodeCompiled; + // Emit is only used for Invoke when RuntimeFeature.IsDynamicCodeSupported is true. + return RuntimeFeature.IsDynamicCodeSupported; } private static string InterpretedMethodName => PlatformDetection.IsMonoRuntime ? diff --git a/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs index a197da333f16d5..355c154119cc13 100644 --- a/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs +++ b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs @@ -8,7 +8,7 @@ namespace System.Reflection.Tests public class InvokeInterpretedTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoAOT))] public static void VerifyInvokeIsUsingEmit_Method() { MethodInfo method = typeof(TestClassThatThrows).GetMethod(nameof(TestClassThatThrows.Throw))!; @@ -25,7 +25,7 @@ string InterpretedMethodName() => PlatformDetection.IsMonoRuntime ? } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoAOT))] public static void VerifyInvokeIsUsingEmit_Constructor() { ConstructorInfo ctor = typeof(TestClassThatThrows).GetConstructor(Type.EmptyTypes)!; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DesTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DesTests.cs index 71f41c685a8117..87726e375bac01 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DesTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DesTests.cs @@ -22,6 +22,7 @@ public static void DesDefaultCtor() { Assert.Equal(64, des.KeySize); Assert.Equal(64, des.BlockSize); + Assert.Equal(8, des.FeedbackSize); Assert.Equal(CipherMode.CBC, des.Mode); Assert.Equal(PaddingMode.PKCS7, des.Padding); } diff --git a/src/libraries/Common/tests/System/TimeProviderTests.cs b/src/libraries/Common/tests/System/TimeProviderTests.cs index 53e88feb97d2b7..b3fe700165e2fd 100644 --- a/src/libraries/Common/tests/System/TimeProviderTests.cs +++ b/src/libraries/Common/tests/System/TimeProviderTests.cs @@ -140,7 +140,7 @@ public void TestProviderTimer(TimeProvider provider, int MaxMilliseconds) state, TimeSpan.FromMilliseconds(state.Period), TimeSpan.FromMilliseconds(state.Period)); - state.TokenSource.Token.WaitHandle.WaitOne(60000); + state.TokenSource.Token.WaitHandle.WaitOne(Timeout.InfiniteTimeSpan); state.TokenSource.Dispose(); Assert.Equal(4, state.Counter); @@ -213,33 +213,34 @@ public static void CancellationTokenSourceWithTimer(TimeProvider provider) // // Test out some int-based timeout logic // -#if NETFRAMEWORK - CancellationTokenSource cts = new CancellationTokenSource(Timeout.InfiniteTimeSpan); // should be an infinite timeout +#if TESTEXTENSIONS + CancellationTokenSource cts = provider.CreateCancellationTokenSource(Timeout.InfiniteTimeSpan); // should be an infinite timeout #else CancellationTokenSource cts = new CancellationTokenSource(Timeout.InfiniteTimeSpan, provider); // should be an infinite timeout -#endif // NETFRAMEWORK - CancellationToken token = cts.Token; +#endif // TESTEXTENSIONS ManualResetEventSlim mres = new ManualResetEventSlim(false); - CancellationTokenRegistration ctr = token.Register(() => mres.Set()); - Assert.False(token.IsCancellationRequested, + Assert.False(cts.Token.IsCancellationRequested, "CancellationTokenSourceWithTimer: Cancellation signaled on infinite timeout (int)!"); -#if NETFRAMEWORK - CancelAfter(provider, cts, TimeSpan.FromMilliseconds(1000000)); +#if TESTEXTENSIONS + cts.Dispose(); + cts = provider.CreateCancellationTokenSource(TimeSpan.FromMilliseconds(1000000)); #else cts.CancelAfter(1000000); -#endif // NETFRAMEWORK +#endif // TESTEXTENSIONS - Assert.False(token.IsCancellationRequested, + Assert.False(cts.Token.IsCancellationRequested, "CancellationTokenSourceWithTimer: Cancellation signaled on super-long timeout (int) !"); -#if NETFRAMEWORK - CancelAfter(provider, cts, TimeSpan.FromMilliseconds(1)); +#if TESTEXTENSIONS + cts.Dispose(); + cts = provider.CreateCancellationTokenSource(TimeSpan.FromMilliseconds(1)); #else cts.CancelAfter(1); -#endif // NETFRAMEWORK +#endif // TESTEXTENSIONS + CancellationTokenRegistration ctr = cts.Token.Register(() => mres.Set()); Debug.WriteLine("CancellationTokenSourceWithTimer: > About to wait on cancellation that should occur soon (int)... if we hang, something bad happened"); mres.Wait(); @@ -250,33 +251,34 @@ public static void CancellationTokenSourceWithTimer(TimeProvider provider) // Test out some TimeSpan-based timeout logic // TimeSpan prettyLong = new TimeSpan(1, 0, 0); -#if NETFRAMEWORK - cts = new CancellationTokenSource(prettyLong); +#if TESTEXTENSIONS + cts = provider.CreateCancellationTokenSource(prettyLong); #else cts = new CancellationTokenSource(prettyLong, provider); -#endif // NETFRAMEWORK +#endif // TESTEXTENSIONS - token = cts.Token; mres = new ManualResetEventSlim(false); - ctr = token.Register(() => mres.Set()); - Assert.False(token.IsCancellationRequested, + Assert.False(cts.Token.IsCancellationRequested, "CancellationTokenSourceWithTimer: Cancellation signaled on super-long timeout (TimeSpan,1)!"); -#if NETFRAMEWORK - CancelAfter(provider, cts, prettyLong); +#if TESTEXTENSIONS + cts.Dispose(); + cts = provider.CreateCancellationTokenSource(prettyLong); #else cts.CancelAfter(prettyLong); -#endif // NETFRAMEWORK +#endif // TESTEXTENSIONS - Assert.False(token.IsCancellationRequested, + Assert.False(cts.Token.IsCancellationRequested, "CancellationTokenSourceWithTimer: Cancellation signaled on super-long timeout (TimeSpan,2) !"); -#if NETFRAMEWORK - CancelAfter(provider, cts, TimeSpan.FromMilliseconds(1000)); +#if TESTEXTENSIONS + cts.Dispose(); + cts = provider.CreateCancellationTokenSource(TimeSpan.FromMilliseconds(1000)); #else cts.CancelAfter(new TimeSpan(1000)); -#endif // NETFRAMEWORK +#endif // TESTEXTENSIONS + ctr = cts.Token.Register(() => mres.Set()); Debug.WriteLine("CancellationTokenSourceWithTimer: > About to wait on cancellation that should occur soon (TimeSpan)... if we hang, something bad happened"); @@ -407,6 +409,36 @@ public static void NegativeTests() #endif // !NETFRAMEWORK } +#if TESTEXTENSIONS + [Fact] + public static void InvokeCallbackFromCreateTimer() + { + TimeProvider p = new InvokeCallbackCreateTimerProvider(); + + CancellationTokenSource cts = p.CreateCancellationTokenSource(TimeSpan.FromSeconds(0)); + Assert.True(cts.IsCancellationRequested); + + Task t = p.Delay(TimeSpan.FromSeconds(0)); + Assert.True(t.IsCompleted); + + t = new TaskCompletionSource().Task.WaitAsync(TimeSpan.FromSeconds(0), p); + Assert.True(t.IsFaulted); + } + + class InvokeCallbackCreateTimerProvider : TimeProvider + { + public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period) + { + ITimer t = base.CreateTimer(callback, state, dueTime, period); + if (dueTime != Timeout.InfiniteTimeSpan) + { + callback(state); + } + return t; + } + } +#endif + class TimerState { public TimerState() @@ -497,7 +529,14 @@ public bool Change(TimeSpan dueTime, TimeSpan period) period = new TimeSpan(period.Ticks / 2); } - return _timer.Change(dueTime, period); + try + { + return _timer.Change(dueTime, period); + } + catch (ObjectDisposedException) + { + return false; + } } public void Dispose() => _timer.Dispose(); @@ -555,5 +594,65 @@ public Task WaitAsync(Task task, TimeSpan timeout, Ti private static TestExtensionsTaskFactory extensionsTaskFactory = new(); #endif // TESTEXTENSIONS + + // A timer that get fired on demand + private class ManualTimer : ITimer + { + TimerCallback _callback; + object? _state; + + public ManualTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period) + { + _callback = callback; + _state = state; + } + + public bool Change(TimeSpan dueTime, TimeSpan period) => true; + + public void Fire() + { + _callback?.Invoke(_state); + IsFired = true; + } + + public bool IsFired { get; set; } + + public void Dispose() { } + public ValueTask DisposeAsync () { return default; } + } + + private class ManualTimeProvider : TimeProvider + { + public ManualTimer Timer { get; set; } + + public ManualTimeProvider() { } + public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period) + { + Timer = new ManualTimer(callback, state, dueTime, period); + return Timer; + } + } + + [Fact] + // 1- Creates the CTS with a delay that we control via the time provider. + // 2- Disposes the CTS. + // 3- Then fires the timer. We want to validate the process doesn't crash. + public static void TestCTSWithDelayFiringAfterCancellation() + { + ManualTimeProvider manualTimer = new ManualTimeProvider(); +#if TESTEXTENSIONS + CancellationTokenSource cts = manualTimer.CreateCancellationTokenSource(TimeSpan.FromSeconds(60)); +#else + CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(60), manualTimer); +#endif // TESTEXTENSIONS + + Assert.NotNull(manualTimer.Timer); + Assert.False(manualTimer.Timer.IsFired); + + cts.Dispose(); + + manualTimer.Timer.Fire(); + Assert.True(manualTimer.Timer.IsFired); + } } } diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index f5c03d347e4055..3f808e7eb4f6a1 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -1,6 +1,5 @@ - true true + Once this package has shipped a stable version, the following line + should be removed in order to re-enable validation. --> true - Provides support for system time abstraction primitives for .NET Framework and .NET Standard. Commonly Used Types: System.TimeProvider -System.ITimer - - +System.ITimer @@ -32,6 +30,9 @@ System.ITimer + + + diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs b/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs index 3a6fa1debbb670..9f8ba325f1d143 100644 --- a/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs +++ b/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs @@ -6,20 +6,34 @@ namespace System.Threading.Tasks /// /// Provide extensions methods for operations with . /// + /// + /// The Microsoft.Bcl.TimeProvider library interfaces are intended solely for use in building against pre-.NET 8 surface area. + /// If your code is being built against .NET 8 or higher, then this library should not be utilized. + /// public static class TimeProviderTaskExtensions { #if !NET8_0_OR_GREATER private sealed class DelayState : TaskCompletionSource { - public DelayState() : base(TaskCreationOptions.RunContinuationsAsynchronously) {} - public ITimer Timer { get; set; } + public DelayState(CancellationToken cancellationToken) : base(TaskCreationOptions.RunContinuationsAsynchronously) + { + CancellationToken = cancellationToken; + } + + public ITimer? Timer { get; set; } + public CancellationToken CancellationToken { get; } public CancellationTokenRegistration Registration { get; set; } } private sealed class WaitAsyncState : TaskCompletionSource { - public WaitAsyncState() : base(TaskCreationOptions.RunContinuationsAsynchronously) { } + public WaitAsyncState(CancellationToken cancellationToken) : base(TaskCreationOptions.RunContinuationsAsynchronously) + { + CancellationToken = cancellationToken; + } + public readonly CancellationTokenSource ContinuationCancellation = new CancellationTokenSource(); + public CancellationToken CancellationToken { get; } public CancellationTokenRegistration Registration; public ITimer? Timer; } @@ -62,34 +76,36 @@ public static Task Delay(this TimeProvider timeProvider, TimeSpan delay, Cancell return Task.FromCanceled(cancellationToken); } - DelayState state = new(); + DelayState state = new(cancellationToken); - // To prevent a race condition where the timer may fire before being assigned to s.Timer, - // we initialize it with an InfiniteTimeSpan and then set it to the state variable, followed by calling Time.Change. - state.Timer = timeProvider.CreateTimer(delayState => + state.Timer = timeProvider.CreateTimer(static delayState => { - DelayState s = (DelayState)delayState; + DelayState s = (DelayState)delayState!; s.TrySetResult(true); s.Registration.Dispose(); - s.Timer.Dispose(); - }, state, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); + s.Timer?.Dispose(); + }, state, delay, Timeout.InfiniteTimeSpan); - state.Timer.Change(delay, Timeout.InfiniteTimeSpan); - - state.Registration = cancellationToken.Register(delayState => + state.Registration = cancellationToken.Register(static delayState => { - DelayState s = (DelayState)delayState; - s.TrySetCanceled(cancellationToken); - s.Timer.Dispose(); + DelayState s = (DelayState)delayState!; + s.TrySetCanceled(s.CancellationToken); s.Registration.Dispose(); + s.Timer?.Dispose(); }, state); - // To prevent a race condition where the timer fires after we have attached the cancellation callback - // but before the registration is stored in state.Registration, we perform a subsequent check to ensure - // that the registration is not left dangling. + // There are race conditions where the timer fires after we have attached the cancellation callback but before the + // registration is stored in state.Registration, or where cancellation is requested prior to the registration being + // stored into state.Registration, or where the timer could fire after it's been createdbut before it's been stored + // in state.Timer. In such cases, the cancellation registration and/or the Timer might be stored into state after the + // callbacks and thus left undisposed. So, we do a subsequent check here. If the task isn't completed by this point, + // then the callbacks won't have called TrySetResult (the callbacks invoke TrySetResult before disposing of the fields), + // in which case it will see both the timer and registration set and be able to Dispose them. If the task is completed + // by this point, then this is guaranteed to see s.Timer as non-null because it was deterministically set above. if (state.Task.IsCompleted) { state.Registration.Dispose(); + state.Timer.Dispose(); } return state.Task; @@ -147,10 +163,8 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time return Task.FromCanceled(cancellationToken); } - var state = new WaitAsyncState(); + WaitAsyncState state = new(cancellationToken); - // To prevent a race condition where the timer may fire before being assigned to s.Timer, - // we initialize it with an InfiniteTimeSpan and then set it to the state variable, followed by calling Time.Change. state.Timer = timeProvider.CreateTimer(static s => { var state = (WaitAsyncState)s!; @@ -158,10 +172,9 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time state.TrySetException(new TimeoutException()); state.Registration.Dispose(); - state.Timer!.Dispose(); + state.Timer?.Dispose(); state.ContinuationCancellation.Cancel(); - }, state, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); - state.Timer.Change(timeout, Timeout.InfiniteTimeSpan); + }, state, timeout, Timeout.InfiniteTimeSpan); _ = task.ContinueWith(static (t, s) => { @@ -179,18 +192,17 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time { var state = (WaitAsyncState)s!; - state.TrySetCanceled(); + state.TrySetCanceled(state.CancellationToken); state.Timer?.Dispose(); state.ContinuationCancellation.Cancel(); }, state); - // To prevent a race condition where the timer fires after we have attached the cancellation callback - // but before the registration is stored in state.Registration, we perform a subsequent check to ensure - // that the registration is not left dangling. + // See explanation in Delay for this final check if (state.Task.IsCompleted) { state.Registration.Dispose(); + state.Timer.Dispose(); } return state.Task; @@ -218,5 +230,57 @@ public static async Task WaitAsync(this Task task, Ti return task.Result; } #endif // NET8_0_OR_GREATER + + /// Initializes a new instance of the class that will be canceled after the specified . + /// The with which to interpret the . + /// The time interval to wait before canceling this . + /// The is negative and not equal to or greater than maximum allowed timer duration. + /// that will be canceled after the specified . + /// + /// + /// The countdown for the delay starts during the call to the constructor. When the delay expires, + /// the constructed is canceled if it has + /// not been canceled already. + /// + /// + /// If running on .NET versions earlier than .NET 8.0, there is a constraint when invoking on the resultant object. + /// This action will not terminate the initial timer indicated by . However, this restriction does not apply on .NET 8.0 and later versions. + /// + /// + public static CancellationTokenSource CreateCancellationTokenSource(this TimeProvider timeProvider, TimeSpan delay) + { +#if NET8_0_OR_GREATER + return new CancellationTokenSource(delay, timeProvider); +#else + if (timeProvider is null) + { + throw new ArgumentNullException(nameof(timeProvider)); + } + + if (delay != Timeout.InfiniteTimeSpan && delay < TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException(nameof(delay)); + } + + if (timeProvider == TimeProvider.System) + { + return new CancellationTokenSource(delay); + } + + var cts = new CancellationTokenSource(); + + ITimer timer = timeProvider.CreateTimer(static s => + { + try + { + ((CancellationTokenSource)s!).Cancel(); + } + catch (ObjectDisposedException) { } + }, cts, delay, Timeout.InfiniteTimeSpan); + + cts.Token.Register(static t => ((ITimer)t!).Dispose(), timer); + return cts; +#endif // NET8_0_OR_GREATER + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs index f9133090ed0c0a..e203558d528995 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs @@ -102,7 +102,7 @@ private void EmitConfigureMethod() _writer.WriteBlankLine(); } - Emit_NotSupportedException_UnableToBindType(NotSupportedReason.TypeNotDetectedAsInput); + Emit_NotSupportedException_TypeNotDetectedAsInput(); _writer.WriteBlockEnd(); } @@ -135,7 +135,7 @@ private void EmitGetMethod() _writer.WriteBlankLine(); } - Emit_NotSupportedException_UnableToBindType(NotSupportedReason.TypeNotDetectedAsInput); + Emit_NotSupportedException_TypeNotDetectedAsInput(); _writer.WriteBlockEnd(); } @@ -833,8 +833,8 @@ private void EmitCastToIConfigurationSection() """); } - private void Emit_NotSupportedException_UnableToBindType(string reason, string typeDisplayString = "{typeof(T)}") => - _writer.WriteLine(@$"throw new global::System.NotSupportedException($""{string.Format(ExceptionMessages.TypeNotSupported, typeDisplayString, reason)}"");"); + private void Emit_NotSupportedException_TypeNotDetectedAsInput() => + _writer.WriteLine(@$"throw new global::System.NotSupportedException($""{string.Format(ExceptionMessages.TypeNotDetectedAsInput, "{typeof(T)}")}"");"); private void EmitCheckForNullArgument_WithBlankLine_IfRequired(bool isValueType) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs index 1dd35c4418d189..ee6331a8bbe79f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs @@ -8,15 +8,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { public sealed partial class ConfigurationBindingSourceGenerator { - private const string GeneratorProjectName = "Microsoft.Extensions.Configuration.Binder.SourceGeneration"; - - private static DiagnosticDescriptor TypeNotSupported { get; } = new DiagnosticDescriptor( - id: "SYSLIB1100", - title: new LocalizableResourceString(nameof(SR.TypeNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)), - messageFormat: new LocalizableResourceString(nameof(SR.TypeNotSupportedMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)), - category: GeneratorProjectName, - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true); + private static DiagnosticDescriptor TypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.TypeNotSupported)); + private static DiagnosticDescriptor AbstractOrInterfaceNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.AbstractOrInterfaceNotSupported)); + private static DiagnosticDescriptor NeedPublicParameterlessConstructor { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.NeedPublicParameterlessConstructor)); + private static DiagnosticDescriptor CollectionNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.CollectionNotSupported)); + private static DiagnosticDescriptor DictionaryKeyNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.DictionaryKeyNotSupported)); + private static DiagnosticDescriptor ElementTypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.ElementTypeNotSupported)); + private static DiagnosticDescriptor MultiDimArraysNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MultiDimArraysNotSupported)); + private static DiagnosticDescriptor NullableUnderlyingTypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.NullableUnderlyingTypeNotSupported)); private static DiagnosticDescriptor PropertyNotSupported { get; } = new DiagnosticDescriptor( id: "SYSLIB1101", @@ -34,18 +33,14 @@ public sealed partial class ConfigurationBindingSourceGenerator defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); - private static class NotSupportedReason - { - public const string AbstractOrInterfaceNotSupported = "Abstract or interface types are not supported"; - public const string NeedPublicParameterlessConstructor = "Only objects with public parameterless ctors are supported"; - public const string CollectionNotSupported = "The collection type is not supported"; - public const string DictionaryKeyNotSupported = "The dictionary key type is not supported"; - public const string ElementTypeNotSupported = "The collection element type is not supported"; - public const string MultiDimArraysNotSupported = "Multidimensional arrays are not supported."; - public const string NullableUnderlyingTypeNotSupported = "Nullable underlying type is not supported"; - public const string TypeNotDetectedAsInput = "Generator parser did not detect the type as input"; - public const string TypeNotSupported = "The type is not supported"; - } + private static DiagnosticDescriptor CreateTypeNotSupportedDescriptor(string nameofLocalizableMessageFormat) => + new DiagnosticDescriptor( + id: "SYSLIB1100", + title: new LocalizableResourceString(nameof(SR.TypeNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)), + messageFormat: new LocalizableResourceString(nameofLocalizableMessageFormat, SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)), + category: GeneratorProjectName, + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true); private static class Identifier { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Parser.cs index 077bf0f4f0b488..d2aa2f79ba7261 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Parser.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Runtime.InteropServices.ComTypes; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Operations; @@ -210,7 +209,7 @@ private void ProcessConfigureCall(BinderInvocationOperation binderOperation) genericType.ConstructUnboundGenericType() is INamedTypeSymbol { } unboundGeneric && unboundGeneric.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { - return TryGetTypeSpec(genericType.TypeArguments[0], NotSupportedReason.NullableUnderlyingTypeNotSupported, out TypeSpec? underlyingType) + return TryGetTypeSpec(genericType.TypeArguments[0], NullableUnderlyingTypeNotSupported, out TypeSpec? underlyingType) ? CacheSpec(new NullableSpec(type) { Location = location, UnderlyingType = underlyingType }) : null; } @@ -266,7 +265,7 @@ private void ProcessConfigureCall(BinderInvocationOperation binderOperation) return CacheSpec(spec); } - ReportUnsupportedType(type, NotSupportedReason.TypeNotSupported, location); + ReportUnsupportedType(type, TypeNotSupported, location); return null; T CacheSpec(T? s) where T : TypeSpec @@ -398,13 +397,13 @@ private bool IsParsableFromString(ITypeSymbol type, out StringParsableTypeKind t } } - private bool TryGetTypeSpec(ITypeSymbol type, string unsupportedReason, out TypeSpec? spec) + private bool TryGetTypeSpec(ITypeSymbol type, DiagnosticDescriptor descriptor, out TypeSpec? spec) { spec = GetOrCreateTypeSpec(type); if (spec == null) { - ReportUnsupportedType(type, unsupportedReason); + ReportUnsupportedType(type, descriptor); return false; } @@ -413,7 +412,7 @@ private bool TryGetTypeSpec(ITypeSymbol type, string unsupportedReason, out Type private ArraySpec? CreateArraySpec(IArrayTypeSymbol arrayType, Location? location) { - if (!TryGetTypeSpec(arrayType.ElementType, NotSupportedReason.ElementTypeNotSupported, out TypeSpec elementSpec)) + if (!TryGetTypeSpec(arrayType.ElementType, ElementTypeNotSupported, out TypeSpec elementSpec)) { return null; } @@ -441,7 +440,7 @@ private bool IsSupportedArrayType(ITypeSymbol type, Location? location, [NotNull if (arrayType.Rank > 1) { - ReportUnsupportedType(arrayType, NotSupportedReason.MultiDimArraysNotSupported, location); + ReportUnsupportedType(arrayType, MultiDimArraysNotSupported, location); elementType = null; return false; } @@ -466,15 +465,15 @@ private bool IsSupportedArrayType(ITypeSymbol type, Location? location, [NotNull private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, Location? location, ITypeSymbol keyType, ITypeSymbol elementType) { - if (!TryGetTypeSpec(keyType, NotSupportedReason.DictionaryKeyNotSupported, out TypeSpec keySpec) || - !TryGetTypeSpec(elementType, NotSupportedReason.ElementTypeNotSupported, out TypeSpec elementSpec)) + if (!TryGetTypeSpec(keyType, DictionaryKeyNotSupported, out TypeSpec keySpec) || + !TryGetTypeSpec(elementType, ElementTypeNotSupported, out TypeSpec elementSpec)) { return null; } if (keySpec.SpecKind != TypeSpecKind.ParsableFromString) { - ReportUnsupportedType(type, NotSupportedReason.DictionaryKeyNotSupported, location); + ReportUnsupportedType(type, DictionaryKeyNotSupported, location); return null; } @@ -487,7 +486,7 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, Location? loc } else if (!CanConstructObject(type, location) || !HasAddMethod(type, elementType, keyType)) { - ReportUnsupportedType(type, NotSupportedReason.CollectionNotSupported, location); + ReportUnsupportedType(type, CollectionNotSupported, location); return null; } @@ -509,7 +508,7 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, Location? loc private EnumerableSpec? CreateEnumerableSpec(INamedTypeSymbol type, Location? location, ITypeSymbol elementType) { - if (!TryGetTypeSpec(elementType, NotSupportedReason.ElementTypeNotSupported, out TypeSpec elementSpec)) + if (!TryGetTypeSpec(elementType, ElementTypeNotSupported, out TypeSpec elementSpec)) { return null; } @@ -526,7 +525,7 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, Location? loc } else if (!CanConstructObject(type, location) || !HasAddMethod(type, elementType)) { - ReportUnsupportedType(type, NotSupportedReason.CollectionNotSupported, location); + ReportUnsupportedType(type, CollectionNotSupported, location); return null; } @@ -687,12 +686,12 @@ private bool CanConstructObject(INamedTypeSymbol type, Location? location) { if (type.IsAbstract || type.TypeKind == TypeKind.Interface) { - ReportUnsupportedType(type, NotSupportedReason.AbstractOrInterfaceNotSupported, location); + ReportUnsupportedType(type, AbstractOrInterfaceNotSupported, location); return false; } else if (!HasPublicParameterlessCtor(type)) { - ReportUnsupportedType(type, NotSupportedReason.NeedPublicParameterlessConstructor, location); + ReportUnsupportedType(type, NeedPublicParameterlessConstructor, location); return false; } @@ -752,12 +751,12 @@ private static bool HasAddMethod(INamedTypeSymbol type, ITypeSymbol element, ITy private static bool IsEnum(ITypeSymbol type) => type is INamedTypeSymbol { EnumUnderlyingType: INamedTypeSymbol { } }; - private void ReportUnsupportedType(ITypeSymbol type, string reason, Location? location = null) + private void ReportUnsupportedType(ITypeSymbol type, DiagnosticDescriptor descriptor, Location? location = null) { if (!_unsupportedTypes.Contains(type)) { _context.ReportDiagnostic( - Diagnostic.Create(TypeNotSupported, location, new string[] { type.ToDisplayString(), reason })); + Diagnostic.Create(descriptor, location, new string[] { type.ToDisplayString() })); _unsupportedTypes.Add(type); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.cs index 46b4ed1789b7e5..864037a1c0e19b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.cs @@ -18,6 +18,8 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration [Generator] public sealed partial class ConfigurationBindingSourceGenerator : IIncrementalGenerator { + private const string GeneratorProjectName = "Microsoft.Extensions.Configuration.Binder.SourceGeneration"; + public void Initialize(IncrementalGeneratorInitializationContext context) { IncrementalValueProvider compilationData = diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ExceptionMessages.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ExceptionMessages.cs index d31ed9a7836621..d50f7242700fa7 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ExceptionMessages.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ExceptionMessages.cs @@ -6,7 +6,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration // Runtime exception messages; not localized so we keep them in source. internal static class ExceptionMessages { - public const string TypeNotSupported = "Unable to bind to type '{0}': '{1}'"; + public const string TypeNotDetectedAsInput = "Unable to bind to type '{0}': generator did not detect the type as input."; public const string FailedBinding = "Failed to convert configuration value at '{0}' to type '{1}'."; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj index 5b9340c1d16223..d9bac84eb7aa6d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj @@ -21,23 +21,22 @@ - - - - - - - - - - + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/PopulationStrategy.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/PopulationStrategy.cs deleted file mode 100644 index 05ba9e9cd0e945..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/PopulationStrategy.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. - -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration -{ - internal enum PopulationStrategy - { - NotApplicable = 0, - Indexer = 1, - Add = 2, - Push = 3, - Enqueue = 4, - } -} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx index 7ea9c596dd90de..9bfb27cfa2030f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx @@ -117,20 +117,41 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Abstract or interface types are not supported: '{0}'. + + + The collection type is not supported: '{0}'. + + + The dictionary key type is not supported: '{0}'. + + + The collection element type is not supported: '{0}'. + The project's language version has to be at least 'C# 11'. Language version is required to be at least C# 11 + + Multidimensional arrays are not supported: '{0}'. + + + Only objects with public parameterless constructors are supported: '{0}'. + + + Nullable underlying type is not supported: '{0}'. + Property '{0}' on type '{1}' is not supported. Did not generate binding logic for a property on a type - - Type '{0}' is not supported: {1}. + + The type is not supported: '{0}'. Did not generate binding logic for a type diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf index c2a1d5dd9a934e..3cfe859b25076a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. Jazyková verze projektu musí být alespoň C# 11 @@ -12,6 +32,21 @@ Verze jazyka musí být alespoň C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. Vlastnost „{0}“ u typu „{1}“ se nepodporuje. @@ -22,9 +57,9 @@ Negenerovala se logika vazby pro vlastnost typu - - Type '{0}' is not supported: {1}. - Typ „{0}“ se nepodporuje: {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf index 806c78c7142cfe..fb7274ed494b91 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. Die Sprachversion des Projekts muss mindestens „C# 11“ sein @@ -12,6 +32,21 @@ Die Sprachversion muss mindestens C# 11 sein + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. Die Eigenschaft „{0}“ für den Typ „{1}“ wird nicht unterstützt. @@ -22,9 +57,9 @@ Für eine Eigenschaft eines Typs wurde keine Bindungslogik generiert - - Type '{0}' is not supported: {1}. - Der Typ „{0}“ wird nicht unterstützt: {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf index c93076fabceb11..b4c2cffb8501dc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. La versión del lenguaje del proyecto debe ser al menos "C# 11". @@ -12,6 +32,21 @@ La versión del lenguaje debe ser al menos C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. La propiedad '{0}' en el tipo '{1}' no se admite. @@ -22,9 +57,9 @@ No se ha generado la lógica de enlace para una propiedad en un tipo. - - Type '{0}' is not supported: {1}. - El tipo '{0}' no se admite: {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf index 178e5bedc42774..5c60230567a970 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. La version de langage du projet doit être au moins « C# 11 ». @@ -12,6 +32,21 @@ La version du langage doit être au moins C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. La propriété '{0}' sur le type '{1}' n’est pas prise en charge. @@ -22,9 +57,9 @@ La logique de liaison n’a pas été généré pour une propriété sur un type - - Type '{0}' is not supported: {1}. - Le type '{0}' n’est pas pris en charge : {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf index aec05f57f9fd2c..7b1ad520477f19 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. La versione del linguaggio del progetto deve essere almeno 'C# 11'. @@ -12,6 +32,21 @@ La versione del linguaggio deve essere almeno C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. La proprietà '{0}' nel tipo '{1}' non è supportata. @@ -22,9 +57,9 @@ Non è stata generata la logica di binding per una proprietà in un tipo - - Type '{0}' is not supported: {1}. - Il tipo '{0}' non è supportato: {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf index cf0ed49380f3ec..a9bbbf3b34b2ac 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. プロジェクトの言語バージョンは少なくとも 'C# 11' である必要があります。 @@ -12,6 +32,21 @@ 言語バージョンは少なくとも C# 11 である必要があります + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. 型 '{1}' のプロパティ '{0}' はサポートされていません。 @@ -22,9 +57,9 @@ 型のプロパティのバインディング ロジックを生成しませんでした - - Type '{0}' is not supported: {1}. - 型 '{0}' はサポートされていません: {1}。 + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf index 832f244d02505c..720a859a1cbada 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. 프로젝트의 언어 버전은 'C# 11' 이상이어야 합니다. @@ -12,6 +32,21 @@ 언어 버전은 C# 11 이상이어야 합니다. + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. '{1}' 형식의 속성 '{0}'은(는) 지원되지 않습니다. @@ -22,9 +57,9 @@ 형식의 속성에 대한 바인딩 논리를 생성하지 않았습니다. - - Type '{0}' is not supported: {1}. - '{0}' 형식은 지원되지 않습니다. {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf index 471337318f873a..9a3d58f0600c21 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. Wersja językowa projektu musi mieć wartość co najmniej „C# 11”. @@ -12,6 +32,21 @@ Wymagana jest wersja językowa co najmniej C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. Właściwość „{0}” w typie „{1}” nie jest obsługiwana. @@ -22,9 +57,9 @@ Nie wygenerowano logiki powiązania dla właściwości w typie - - Type '{0}' is not supported: {1}. - Typ „{0}” nie jest obsługiwany: {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf index f45365bd58ee4d..3f8430df07fefc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. A versão do idioma do projeto deve ser no mínimo 'C# 11'. @@ -12,6 +32,21 @@ A versão do idioma deve ser pelo menos C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. Não há suporte para a propriedade '{0}' no tipo '{1}'. @@ -22,9 +57,9 @@ Não gerou lógica de ligação para uma propriedade em um tipo - - Type '{0}' is not supported: {1}. - Não há suporte para o tipo '{0}': {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf index 28401e9e9acd29..36809578fd03e4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. Версия языка проекта должна быть не ниже "C# 11". @@ -12,6 +32,21 @@ Версия языка должна быть не ниже C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. Свойство "{0}" типа "{1}" не поддерживается. @@ -22,9 +57,9 @@ Не создана логика привязки для свойства типа - - Type '{0}' is not supported: {1}. - Тип "{0}" не поддерживается: {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf index 24ce4b5933ac75..aa91ffdf1440f7 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. Projenin dil sürümü en az 'C# 11' olmalıdır. @@ -12,6 +32,21 @@ Dil sürümünün en az C# 11 olması gerekir + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. '{1}' türündeki '{0}' özelliği desteklenmiyor. @@ -22,9 +57,9 @@ Türdeki bir özellik için bağlama mantığı oluşturulmadı - - Type '{0}' is not supported: {1}. - '{0}' türü desteklenmiyor: {1}. + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf index 7521008371b5e4..a3d4c35b548bee 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. 项目的语言版本必须至少为 "C# 11"。 @@ -12,6 +32,21 @@ 语言版本必须至少为 C# 11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. 类型“{1}”中的属性“{0}”不受支持。 @@ -22,9 +57,9 @@ 没有为类型中的属性生成绑定逻辑 - - Type '{0}' is not supported: {1}. - 类型“{0}”不受支持:{1}。 + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf index 6a49ca9498fc05..07aa56d28c2b3a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -2,6 +2,26 @@ + + Abstract or interface types are not supported: '{0}'. + Abstract or interface types are not supported: '{0}'. + + + + The collection type is not supported: '{0}'. + The collection type is not supported: '{0}'. + + + + The dictionary key type is not supported: '{0}'. + The dictionary key type is not supported: '{0}'. + + + + The collection element type is not supported: '{0}'. + The collection element type is not supported: '{0}'. + + The project's language version has to be at least 'C# 11'. 專案的語言版本必須至少為 'C# 11'。 @@ -12,6 +32,21 @@ 語言版本要求至少為 C#11 + + Multidimensional arrays are not supported: '{0}'. + Multidimensional arrays are not supported: '{0}'. + + + + Only objects with public parameterless constructors are supported: '{0}'. + Only objects with public parameterless constructors are supported: '{0}'. + + + + Nullable underlying type is not supported: '{0}'. + Nullable underlying type is not supported: '{0}'. + + Property '{0}' on type '{1}' is not supported. 不支援類型 '{1}' 的屬性 '{0}'。 @@ -22,9 +57,9 @@ 未在類型上產生屬性的繫結邏輯 - - Type '{0}' is not supported: {1}. - 不支援類型 '{0}': {1}。 + + The type is not supported: '{0}'. + The type is not supported: '{0}'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/SourceGenerationSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/SourceGenerationSpec.cs index f4964c5ba99932..79ab04a5da8091 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/SourceGenerationSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/SourceGenerationSpec.cs @@ -2,11 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using Microsoft.CodeAnalysis; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record SourceGenerationSpec( Dictionary> RootConfigTypes, MethodSpecifier MethodsToGen, diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/CollectionSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/CollectionSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/CollectionSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/CollectionSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationSectionTypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ConfigurationSectionTypeSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationSectionTypeSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ConfigurationSectionTypeSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConstructionStrategy.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ConstructionStrategy.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConstructionStrategy.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ConstructionStrategy.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/NullableSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/NullableSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/NullableSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/NullableSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ObjectSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ObjectSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ObjectSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ObjectSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ParsableFromStringTypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ParsableFromStringTypeSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ParsableFromStringTypeSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/ParsableFromStringTypeSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/PropertySpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/PropertySpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/PropertySpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/PropertySpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/TypeSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/TypeSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeSpecKind.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/TypeSpecKind.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeSpecKind.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/TypeGraph/TypeSpecKind.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt index 735f5247fedd7d..a612cb0f046b09 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt @@ -23,7 +23,7 @@ internal static class GeneratedConfigurationBinder }); } - throw new global::System.NotSupportedException($"Unable to bind to type '{typeof(T)}': 'Generator parser did not detect the type as input'"); + throw new global::System.NotSupportedException($"Unable to bind to type '{typeof(T)}': generator did not detect the type as input."); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt index bdb48ea091890d..3875d08ca5f0db 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt @@ -22,7 +22,7 @@ internal static class GeneratedConfigurationBinder return (T)(object)obj; } - throw new global::System.NotSupportedException($"Unable to bind to type '{typeof(T)}': 'Generator parser did not detect the type as input'"); + throw new global::System.NotSupportedException($"Unable to bind to type '{typeof(T)}': generator did not detect the type as input."); } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs index 21b4646713bae5..953cc27850506b 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs @@ -129,10 +129,14 @@ public static ObjectFactory CreateFactory( Type[] argumentTypes) { #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP - if (!RuntimeFeature.IsDynamicCodeSupported) + if (!RuntimeFeature.IsDynamicCodeCompiled) { - // Create a reflection-based factory when dynamic code isn't supported, e.g. app is published with NativeAOT. - // Reflection-based factory is faster than interpreted expressions and doesn't pull in System.Linq.Expressions dependency. + // Create a reflection-based factory when dynamic code is not compiled\jitted as would be the case with + // NativeAOT, iOS or WASM. + // For NativeAOT and iOS, using the reflection-based factory is faster than reflection-fallback interpreted + // expressions and also doesn't pull in the large System.Linq.Expressions dependency. + // For WASM, although it has the ability to use expressions (with dynamic code) and interpet the dynamic code + // efficiently, the size savings of not using System.Linq.Expressions is more important than CPU perf. return CreateFactoryReflection(instanceType, argumentTypes); } #endif @@ -163,10 +167,9 @@ public static ObjectFactory Type[] argumentTypes) { #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP - if (!RuntimeFeature.IsDynamicCodeSupported) + if (!RuntimeFeature.IsDynamicCodeCompiled) { - // Create a reflection-based factory when dynamic code isn't supported, e.g. app is published with NativeAOT. - // Reflection-based factory is faster than interpreted expressions and doesn't pull in System.Linq.Expressions dependency. + // See the comment above in the non-generic CreateFactory() for why we use 'IsDynamicCodeCompiled' here. var factory = CreateFactoryReflection(typeof(T), argumentTypes); return (serviceProvider, arguments) => (T)factory(serviceProvider, arguments); } @@ -311,6 +314,11 @@ private static ObjectFactory CreateFactoryReflection( return (IServiceProvider serviceProvider, object?[]? arguments) => { + if (serviceProvider is null) + { + throw new ArgumentNullException(nameof(serviceProvider)); + } + object?[] constructorArguments = new object?[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs index c143e90a94301e..4c065b61bb2856 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs @@ -204,12 +204,12 @@ public void CreateFactory_CreatesFactoryMethod() #if NETCOREAPP [InlineData(false)] #endif - public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool isDynamicCodeSupported) + public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool useDynamicCode) { var options = new RemoteInvokeOptions(); - if (!isDynamicCodeSupported) + if (!useDynamicCode) { - options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + DisableDynamicCode(options); } using var remoteHandle = RemoteExecutor.Invoke(static () => @@ -238,12 +238,12 @@ public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool isDynamicCode #if NETCOREAPP [InlineData(false)] #endif - public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool isDynamicCodeSupported) + public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool useDynamicCode) { var options = new RemoteInvokeOptions(); - if (!isDynamicCodeSupported) + if (!useDynamicCode) { - options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + DisableDynamicCode(options); } using var remoteHandle = RemoteExecutor.Invoke(static () => @@ -261,12 +261,12 @@ public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool isDynamicCode #if NETCOREAPP [InlineData(false)] #endif - public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool isDynamicCodeSupported) + public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool useDynamicCode) { var options = new RemoteInvokeOptions(); - if (!isDynamicCodeSupported) + if (!useDynamicCode) { - options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + DisableDynamicCode(options); } using var remoteHandle = RemoteExecutor.Invoke(static () => @@ -285,12 +285,12 @@ public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool is #if NETCOREAPP [InlineData(false)] #endif - public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool isDynamicCodeSupported) + public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool useDynamicCode) { var options = new RemoteInvokeOptions(); - if (!isDynamicCodeSupported) + if (!useDynamicCode) { - options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + DisableDynamicCode(options); } using var remoteHandle = RemoteExecutor.Invoke(static () => @@ -309,12 +309,12 @@ public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool isD #if NETCOREAPP [InlineData(false)] #endif - public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool isDynamicCodeSupported) + public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool useDynamicCode) { var options = new RemoteInvokeOptions(); - if (!isDynamicCodeSupported) + if (!useDynamicCode) { - options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + DisableDynamicCode(options); } using var remoteHandle = RemoteExecutor.Invoke(static () => @@ -333,12 +333,12 @@ public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool isDyn #if NETCOREAPP [InlineData(false)] #endif - public void CreateFactory_RemoteExecutor_NoParameters_Success(bool isDynamicCodeSupported) + public void CreateFactory_RemoteExecutor_NoParameters_Success(bool useDynamicCode) { var options = new RemoteInvokeOptions(); - if (!isDynamicCodeSupported) + if (!useDynamicCode) { - options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + DisableDynamicCode(options); } using var remoteHandle = RemoteExecutor.Invoke(static () => @@ -351,6 +351,14 @@ public void CreateFactory_RemoteExecutor_NoParameters_Success(bool isDynamicCode Assert.NotNull(item); }, options); } + + private static void DisableDynamicCode(RemoteInvokeOptions options) + { + // We probably only need to set 'IsDynamicCodeCompiled' since only that is checked, + // but also set 'IsDynamicCodeSupported for correctness. + options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeCompiled", "false"); + } } internal class A { } @@ -361,8 +369,8 @@ internal class S { } internal class ClassWithABCS : ClassWithABC { public S S { get; } - public ClassWithABCS(A a, B b, C c, S s) : base (a, b, c) { S = s; } - public ClassWithABCS(A a, C c, S s) : this (a, null, c, s) { } + public ClassWithABCS(A a, B b, C c, S s) : base(a, b, c) { S = s; } + public ClassWithABCS(A a, C c, S s) : this(a, null, c, s) { } } internal class ClassWithABC_FirstConstructorWithAttribute : ClassWithABC @@ -374,9 +382,9 @@ public ClassWithABC_FirstConstructorWithAttribute(B b, C c) : this(null, b, c) { internal class ClassWithABC_LastConstructorWithAttribute : ClassWithABC { - public ClassWithABC_LastConstructorWithAttribute(B b, C c) : this(null, b, c) { } + public ClassWithABC_LastConstructorWithAttribute(B b, C c) : this(null, b, c) { } [ActivatorUtilitiesConstructor] - public ClassWithABC_LastConstructorWithAttribute(A a, B b, C c) : base(a, b , c) { } + public ClassWithABC_LastConstructorWithAttribute(A a, B b, C c) : base(a, b, c) { } } internal class FakeServiceProvider : IServiceProvider @@ -512,14 +520,14 @@ internal class ClassWithABC_DefaultConstructorFirst : ClassWithABC { public ClassWithABC_DefaultConstructorFirst() : base() { } public ClassWithABC_DefaultConstructorFirst(A a) : base(a) { } - public ClassWithABC_DefaultConstructorFirst(A a, B b) : base (a, b) { } - public ClassWithABC_DefaultConstructorFirst(A a, B b, C c) : base (a, b, c) { } + public ClassWithABC_DefaultConstructorFirst(A a, B b) : base(a, b) { } + public ClassWithABC_DefaultConstructorFirst(A a, B b, C c) : base(a, b, c) { } } internal class ClassWithABC_DefaultConstructorLast : ClassWithABC { - public ClassWithABC_DefaultConstructorLast(A a, B b, C c) : base (a, b, c) { } - public ClassWithABC_DefaultConstructorLast(A a, B b) : base (a, b) { } + public ClassWithABC_DefaultConstructorLast(A a, B b, C c) : base(a, b, c) { } + public ClassWithABC_DefaultConstructorLast(A a, B b) : base(a, b) { } public ClassWithABC_DefaultConstructorLast(A a) : base(a) { } public ClassWithABC_DefaultConstructorLast() : base() { } } @@ -533,3 +541,4 @@ public ClassWithStringDefaultValue(string text = "DEFAULT") } } } + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs index bef850f489fba1..f1abdcb46b0c21 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs @@ -939,6 +939,7 @@ Func CreateAotCompatibilityCallSiteFactory() RemoteInvokeOptions options = new RemoteInvokeOptions(); options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false"); + options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeCompiled", "false"); using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(() => { @@ -966,7 +967,7 @@ Func CreateAotCompatibilityCallSiteFactory() Assert.Equal(2, ((Struct1)callSite.Value).Value); }, options); - // Verify the above scenarios work when IsDynamicCodeSupported is not set + // Verify the above scenarios work when IsDynamicCodeSupported + IsDynamicCodeCompiled are not set Func callSiteFactory = CreateAotCompatibilityCallSiteFactory(); // Open Generics diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/EnvironmentWrapper.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/EnvironmentWrapper.cs index 47025ffb17ac32..d61aed3e622ead 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/EnvironmentWrapper.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/EnvironmentWrapper.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +#if !NETFRAMEWORK using System.Runtime.InteropServices; +#endif namespace Microsoft.Extensions.DependencyModel { @@ -14,6 +16,11 @@ internal sealed class EnvironmentWrapper : IEnvironment public object? GetAppContextData(string name) => AppDomain.CurrentDomain.GetData(name); - public bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + public bool IsWindows() => +#if NETFRAMEWORK + Environment.OSVersion.Platform == PlatformID.Win32NT; +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#endif } } diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj index 99792dd1f3a0ba..ca71ccf4d0d348 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj @@ -41,7 +41,6 @@ By default, the dependency manifest contains information about the application's - diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/Resolution/DotNetReferenceAssembliesPathResolver.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/Resolution/DotNetReferenceAssembliesPathResolver.cs index 9c78fca2b2518e..ead221a3fb30d4 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/Resolution/DotNetReferenceAssembliesPathResolver.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/Resolution/DotNetReferenceAssembliesPathResolver.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#if !NETFRAMEWORK using System.Runtime.InteropServices; +#endif namespace Microsoft.Extensions.DependencyModel.Resolution { @@ -27,12 +29,21 @@ public class DotNetReferenceAssembliesPathResolver private static string? GetDefaultDotNetReferenceAssembliesPath(IFileSystem fileSystem) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if ( +#if NETFRAMEWORK + System.Environment.OSVersion.Platform == System.PlatformID.Win32NT +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { return null; } - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && + if ( +#if !NETFRAMEWORK + RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && +#endif fileSystem.Directory.Exists("/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks")) { return "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks"; diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs index 2e8cd78618f3c3..6321adbfc72f16 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Buffers; using System.IO; using System.Linq; using Microsoft.Extensions.Primitives; @@ -9,23 +11,31 @@ namespace Microsoft.Extensions.FileProviders.Physical.Internal { internal static class PathUtils { - private static readonly char[] _invalidFileNameChars = Path.GetInvalidFileNameChars() + private static char[] GetInvalidFileNameChars() => Path.GetInvalidFileNameChars() .Where(c => c != Path.DirectorySeparatorChar && c != Path.AltDirectorySeparatorChar).ToArray(); - private static readonly char[] _invalidFilterChars = _invalidFileNameChars + private static char[] GetInvalidFilterChars() => GetInvalidFileNameChars() .Where(c => c != '*' && c != '|' && c != '?').ToArray(); +#if NET8_0_OR_GREATER + private static readonly SearchValues _invalidFileNameChars = SearchValues.Create(GetInvalidFileNameChars()); + private static readonly SearchValues _invalidFilterChars = SearchValues.Create(GetInvalidFilterChars()); +#else + private static readonly char[] _invalidFileNameChars = GetInvalidFileNameChars(); + private static readonly char[] _invalidFilterChars = GetInvalidFilterChars(); +#endif + private static readonly char[] _pathSeparators = new[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}; internal static bool HasInvalidPathChars(string path) { - return path.IndexOfAny(_invalidFileNameChars) != -1; + return path.AsSpan().IndexOfAny(_invalidFileNameChars) >= 0; } internal static bool HasInvalidFilterChars(string path) { - return path.IndexOfAny(_invalidFilterChars) != -1; + return path.AsSpan().IndexOfAny(_invalidFilterChars) >= 0; } internal static string EnsureTrailingSlash(string path) diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj index ad62b2a7c571d1..c4bbe1418891c2 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj @@ -16,6 +16,9 @@ Link="Common\src\Extensions\NonCapturingTimer\NonCapturingTimer.cs" /> + @@ -24,8 +27,4 @@ - - - - diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx index 61a2f55a718489..64c4215b710e34 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx @@ -117,6 +117,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. + + + Non-negative number required. + The fileSystemWatcher parameter must be non-null when pollForChanges is false. @@ -126,6 +132,9 @@ Cannot modify {0} once file watcher has been initialized. + + The hash algorithm name cannot be null or empty. + Unexpected type of FileSystemInfo diff --git a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs index 7569a921263495..883be7b40f2d1a 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs @@ -19,7 +19,13 @@ public static class WindowsServiceHelpers [SupportedOSPlatformGuard("windows")] public static bool IsWindowsService() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if ( +#if NETFRAMEWORK + Environment.OSVersion.Platform != PlatformID.Win32NT +#else + !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { return false; } diff --git a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceLifetimeHostBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceLifetimeHostBuilderExtensions.cs index 90e8035cadc458..0280d8ee9c5ede 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceLifetimeHostBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceLifetimeHostBuilderExtensions.cs @@ -106,11 +106,15 @@ public static IServiceCollection AddWindowsService(this IServiceCollection servi private static void AddWindowsServiceLifetime(IServiceCollection services, Action configure) { +#if !NETFRAMEWORK Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); +#endif services.AddLogging(logging => { +#if !NETFRAMEWORK Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); +#endif logging.AddEventLog(); }); services.AddSingleton(); @@ -129,7 +133,9 @@ public EventLogSettingsSetup(IHostEnvironment environment) public void Configure(EventLogSettings settings) { +#if !NETFRAMEWORK Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); +#endif if (string.IsNullOrEmpty(settings.SourceName)) { diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs index cc9c7e205ef608..5b2f56abe6a665 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs @@ -217,7 +217,13 @@ internal static void SetDefaultContentRoot(IConfigurationBuilder hostConfigBuild // any trailing directory separator characters. I'm not even sure the casing can ever be different from these APIs, but I think it makes sense to // ignore case for Windows path comparisons given the file system is usually (always?) going to be case insensitive for the system path. string cwd = Environment.CurrentDirectory; - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !string.Equals(cwd, Environment.SystemDirectory, StringComparison.OrdinalIgnoreCase)) + if ( +#if NETFRAMEWORK + Environment.OSVersion.Platform != PlatformID.Win32NT || +#else + !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || +#endif + !string.Equals(cwd, Environment.SystemDirectory, StringComparison.OrdinalIgnoreCase)) { hostConfigBuilder.AddInMemoryCollection(new[] { @@ -270,6 +276,8 @@ internal static void AddDefaultServices(HostBuilderContext hostingContext, IServ bool isWindows = #if NETCOREAPP OperatingSystem.IsWindows(); +#elif NETFRAMEWORK + Environment.OSVersion.Platform == PlatformID.Win32NT; #else RuntimeInformation.IsOSPlatform(OSPlatform.Windows); #endif diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.cs b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.cs index 372a6146c55d25..5f23099082cbfe 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.IO; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -79,6 +80,13 @@ private void OnApplicationStarted() Logger.LogInformation("Application started. Press Ctrl+C to shut down."); Logger.LogInformation("Hosting environment: {EnvName}", Environment.EnvironmentName); Logger.LogInformation("Content root path: {ContentRoot}", Environment.ContentRootPath); + string contentRootFullPath = Path.GetFullPath(Environment.ContentRootPath); + + if (contentRootFullPath.Equals(System.Environment.CurrentDirectory, StringComparison.Ordinal) + || contentRootFullPath.Equals(AppContext.BaseDirectory, StringComparison.Ordinal)) + { + Logger.LogInformation("Current working directory is /. If Content root path is not set explicitly, then working directory is used by default."); + } } private void OnApplicationStopping() diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs index fcc55b2f5d43ec..13b18f8e3cf153 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs @@ -70,23 +70,22 @@ public async Task StartAsync(CancellationToken cancellationToken = default) if (_options.ServicesStartConcurrently) { - Task tasks = Task.WhenAll(_hostedServices.Select(async service => + List tasks = new List(); + + foreach (IHostedService hostedService in _hostedServices) { - await service.StartAsync(combinedCancellationToken).ConfigureAwait(false); + tasks.Add(Task.Run(() => StartAndTryToExecuteAsync(hostedService, combinedCancellationToken), combinedCancellationToken)); + } - if (service is BackgroundService backgroundService) - { - _ = TryExecuteBackgroundServiceAsync(backgroundService); - } - })); + Task groupedTasks = Task.WhenAll(tasks); try { - await tasks.ConfigureAwait(false); + await groupedTasks.ConfigureAwait(false); } catch (Exception ex) { - exceptions.AddRange(tasks.Exception?.InnerExceptions ?? new[] { ex }.AsEnumerable()); + exceptions.AddRange(groupedTasks.Exception?.InnerExceptions ?? new[] { ex }.AsEnumerable()); } } else @@ -96,12 +95,7 @@ public async Task StartAsync(CancellationToken cancellationToken = default) try { // Fire IHostedService.Start - await hostedService.StartAsync(combinedCancellationToken).ConfigureAwait(false); - - if (hostedService is BackgroundService backgroundService) - { - _ = TryExecuteBackgroundServiceAsync(backgroundService); - } + await StartAndTryToExecuteAsync(hostedService, combinedCancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -134,6 +128,16 @@ public async Task StartAsync(CancellationToken cancellationToken = default) _logger.Started(); } + private async Task StartAndTryToExecuteAsync(IHostedService service, CancellationToken combinedCancellationToken) + { + await service.StartAsync(combinedCancellationToken).ConfigureAwait(false); + + if (service is BackgroundService backgroundService) + { + _ = TryExecuteBackgroundServiceAsync(backgroundService); + } + } + private async Task TryExecuteBackgroundServiceAsync(BackgroundService backgroundService) { // backgroundService.ExecuteTask may not be set (e.g. if the derived class doesn't call base.StartAsync) @@ -185,15 +189,22 @@ public async Task StopAsync(CancellationToken cancellationToken = default) if (_options.ServicesStopConcurrently) { - Task tasks = Task.WhenAll(hostedServices.Select(async service => await service.StopAsync(token).ConfigureAwait(false))); + List tasks = new List(); + + foreach (IHostedService hostedService in hostedServices) + { + tasks.Add(Task.Run(() => hostedService.StopAsync(token), token)); + } + + Task groupedTasks = Task.WhenAll(tasks); try { - await tasks.ConfigureAwait(false); + await groupedTasks.ConfigureAwait(false); } catch (Exception ex) { - exceptions.AddRange(tasks.Exception?.InnerExceptions ?? new[] { ex }.AsEnumerable()); + exceptions.AddRange(groupedTasks.Exception?.InnerExceptions ?? new[] { ex }.AsEnumerable()); } } else diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index 1c372be3ff7e57..1ea45457d06272 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -54,7 +54,6 @@ - diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/DelegateHostedService.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/DelegateHostedService.cs index 6f6b319138f90b..370b4c40aa9116 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/DelegateHostedService.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/DelegateHostedService.cs @@ -7,7 +7,7 @@ namespace Microsoft.Extensions.Hosting.Unit.Tests; -internal class DelegateHostedService : IHostedService, IDisposable +internal class DelegateHostedService : IHostedService, IDisposable, IEquatable { private readonly Action _started; private readonly Action _stopping; @@ -20,6 +20,8 @@ public DelegateHostedService(Action started, Action stopping, Action disposing) _disposing = disposing; } + public int? Identifier { get; set; } + public Task StartAsync(CancellationToken token) { StartDate = DateTimeOffset.Now; @@ -37,4 +39,8 @@ public Task StopAsync(CancellationToken token) public DateTimeOffset StartDate { get; private set; } public DateTimeOffset StopDate { get; private set; } + + public bool Equals(DelegateHostedService other) => this == other; + + public override string ToString() => $"DelegateHostedService: Id={Identifier}, StartDate={StartDate}, StopDate={StopDate}"; } diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs index 4b678b8912b77e..abda9052dffd64 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs @@ -64,7 +64,7 @@ public async Task StartAsync_StopAsync_Concurrency(bool stopConcurrently, bool s { var index = i; var service = new DelegateHostedService(() => { events[index, 0] = true; }, () => { events[index, 1] = true; } , () => { }); - + service.Identifier = index; hostedServices[index] = service; } @@ -92,8 +92,11 @@ public async Task StartAsync_StopAsync_Concurrency(bool stopConcurrently, bool s Assert.False(events[i, 1]); } - // Ensures that IHostedService instances are started in FIFO order - AssertExtensions.CollectionEqual(hostedServices, hostedServices.OrderBy(h => h.StartDate), EqualityComparer.Default); + // Ensures that IHostedService instances are started in FIFO order when services are started non concurrently + if (hostedServiceCount > 0 && !startConcurrently) + { + AssertExtensions.Equal(hostedServices, hostedServices.OrderBy(h => h.StartDate).ToArray()); + } await host.StopAsync(CancellationToken.None); @@ -103,8 +106,11 @@ public async Task StartAsync_StopAsync_Concurrency(bool stopConcurrently, bool s Assert.True(events[i, 1]); } - // Ensures that IHostedService instances are stopped in LIFO order - AssertExtensions.CollectionEqual(hostedServices.Reverse(), hostedServices.OrderBy(h => h.StopDate), EqualityComparer.Default); + // Ensures that IHostedService instances are stopped in LIFO order when services are stopped non concurrently + if (hostedServiceCount > 0 && !stopConcurrently) + { + AssertExtensions.Equal(hostedServices, hostedServices.OrderByDescending(h => h.StopDate).ToArray()); + } } [Fact] diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs index 5192b75f1f1f90..a2910bf28fff79 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs @@ -45,7 +45,7 @@ public static class DiagnosticDescriptors title: new LocalizableResourceString(nameof(SR.ShouldntReuseEventIdsTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Logging.Generators.SR)), messageFormat: new LocalizableResourceString(nameof(SR.ShouldntReuseEventIdsMessage), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Logging.Generators.SR)), category: "LoggingGenerator", - DiagnosticSeverity.Warning, + DiagnosticSeverity.Info, isEnabledByDefault: true); public static DiagnosticDescriptor LoggingMethodMustReturnVoid { get; } = new DiagnosticDescriptor( diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs index 397a8dcbf1595c..7c9bf4d38a2116 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs @@ -254,10 +254,10 @@ private void GenCases(LoggerMethod lm, string nestedIndentation) { // this is related to https://github.com/serilog/serilog-extensions-logging/issues/197 string name = p.CodeName; - if (lm.TemplateMap.ContainsKey(name)) + if (lm.TemplateMap.TryGetValue(name, out string value)) { // take the letter casing from the template - name = lm.TemplateMap[name]; + name = value; } _builder.AppendLine($" {nestedIndentation}{index++} => new global::System.Collections.Generic.KeyValuePair(\"{name}\", this.{NormalizeSpecialSymbol(p.CodeName)}),"); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs index ff48c3880c418c..8426f51c17d601 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs @@ -165,7 +165,7 @@ public bool TryDequeue(out LogMessageEntry item) Monitor.Wait(_messageQueue); } - if (_messageQueue.Count > 0 && !_isAddingCompleted) + if (_messageQueue.Count > 0) { item = _messageQueue.Dequeue(); if (_messageQueue.Count == MaxQueueLength - 1) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index b85273d0bfd6df..f1f96fd6611424 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -68,7 +68,13 @@ public ConsoleLoggerProvider(IOptionsMonitor options, IEnu [UnsupportedOSPlatformGuard("windows")] private static bool DoesConsoleSupportAnsi() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if ( +#if NETFRAMEWORK + Environment.OSVersion.Platform != PlatformID.Win32NT +#else + !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { return true; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index dffe8084cc561c..ed78c7dce5f782 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -64,8 +64,6 @@ - - diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerProcessorTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerProcessorTests.cs index bbed15f5d1c0fa..dfc7eaae8fe24c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerProcessorTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerProcessorTests.cs @@ -36,6 +36,32 @@ public void LogAfterDisposeWritesLog() Assert.Equal(2, sink.Writes.Count); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void LogsFlushedAfterDispose() + { + // Arrange + var sink = new ConsoleSink(); + var console = new TestConsole(sink); + var processor = new ConsoleLoggerProcessor(console, null!, ConsoleLoggerQueueFullMode.Wait, 1024); + + var logger = new ConsoleLogger(_loggerName, loggerProcessor: processor, + new SimpleConsoleFormatter(new TestFormatterOptionsMonitor(new SimpleConsoleFormatterOptions())), + null, new ConsoleLoggerOptions()); + Assert.Null(logger.Options.FormatterName); + UpdateFormatterOptions(logger.Formatter, logger.Options); + + // Act + const int repetitions = 1000; + for (int i = 0; i < repetitions; i++) + { + logger.LogInformation("Message #{i}", i); + } + processor.Dispose(); + + // Assert + Assert.Equal(2*repetitions, sink.Writes.Count); // 2 writes per message (category and msg) + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(-1)] [InlineData(0)] @@ -120,7 +146,6 @@ public void Write(string message) [OuterLoop] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71242")] public void ThrowDuringProcessLog_ShutsDownGracefully() { var console = new TimesWriteCalledConsole(); @@ -147,8 +172,10 @@ public void ThrowDuringProcessLog_ShutsDownGracefully() while (console.TimesWriteCalled != 2); // wait until the logs are processed Assert.Equal(2, console.TimesWriteCalled); logger.LogError("Causing exception to throw in {ClassName} using {DesiredConsole}", nameof(ConsoleLoggerProcessor), nameof(WriteThrowingConsole)); - logger.LogInformation("After the write logic threw exception, {ClassName} stopped gracefully, no longer processing next logs", nameof(ConsoleLoggerProcessor)); - Assert.Equal(2, console.TimesWriteCalled); + logger.LogInformation("After the write logic threw exception, {ClassName} stopped gracefully, finish processing queued logs", nameof(ConsoleLoggerProcessor)); + // disposing makes sure that all queued messages are flushed + processor.Dispose(); + Assert.Equal(3, console.TimesWriteCalled); } private static void UpdateFormatterOptions(ConsoleFormatter formatter, ConsoleLoggerOptions deprecatedFromOptions) diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs index bb9e96e81d680d..aef043fd8a090f 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs @@ -1257,3 +1257,11 @@ public static partial class ImmutableArrayExtensions public static System.Collections.Generic.IEnumerable Where(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } } } +namespace System.Runtime.InteropServices +{ + public static partial class ImmutableCollectionsMarshal + { + public static System.Collections.Immutable.ImmutableArray AsImmutableArray(T[]? array) { throw null; } + public static T[]? AsArray(System.Collections.Immutable.ImmutableArray array) { throw null; } + } +} diff --git a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj index 64b075b1503902..8ec05a3b5e4b36 100644 --- a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj +++ b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj @@ -24,7 +24,6 @@ The System.Collections.Immutable library is built-in as part of the shared frame - @@ -141,6 +140,7 @@ The System.Collections.Immutable library is built-in as part of the shared frame + diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs index a1e5016027f4f2..607284e2ac72b2 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs @@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Collections.Frozen { @@ -338,7 +339,7 @@ public abstract class FrozenDictionary : IDictionary /// /// The order of the keys in the dictionary is unspecified, but it is the same order as the associated values returned by the property. /// - public ImmutableArray Keys => ImmutableArrayFactory.Create(KeysCore); + public ImmutableArray Keys => ImmutableCollectionsMarshal.AsImmutableArray(KeysCore); /// private protected abstract TKey[] KeysCore { get; } @@ -360,7 +361,7 @@ public abstract class FrozenDictionary : IDictionary /// /// The order of the values in the dictionary is unspecified, but it is the same order as the associated keys returned by the property. /// - public ImmutableArray Values => ImmutableArrayFactory.Create(ValuesCore); + public ImmutableArray Values => ImmutableCollectionsMarshal.AsImmutableArray(ValuesCore); /// private protected abstract TValue[] ValuesCore { get; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs index df867322e3df7e..7237e792709cf0 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs @@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Numerics; +using System.Runtime.InteropServices; namespace System.Collections.Frozen { @@ -274,7 +275,7 @@ public abstract class FrozenSet : ISet, /// Gets a collection containing the values in the set. /// The order of the values in the set is unspecified. - public ImmutableArray Items => ImmutableArrayFactory.Create(ItemsCore); + public ImmutableArray Items => ImmutableCollectionsMarshal.AsImmutableArray(ItemsCore); /// private protected abstract T[] ItemsCore { get; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/ImmutableArrayFactory.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/ImmutableArrayFactory.cs deleted file mode 100644 index a1ad3b274f970b..00000000000000 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/ImmutableArrayFactory.cs +++ /dev/null @@ -1,19 +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.Collections.Immutable; - -namespace System.Collections.Frozen -{ - /// - /// Stubs to isolate the frozen collection code from the internal details of ImmutableArray - /// - /// - /// This is intended to make it easier to use the frozen collections in environments/conditions - /// when only the public API of ImmutableArray is available. - /// - internal static class ImmutableArrayFactory - { - public static ImmutableArray Create(T[] array) => new ImmutableArray(array); - } -} diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs index f554b01ff92a74..1060df258e6b40 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs @@ -137,10 +137,11 @@ private static void UseFullString(ReadOnlySpan uniqueStrings, bool ignor results = new(allAscii, ignoreCase, 0, 0, 0, 0); } - // TODO https://github.com/dotnet/runtime/issues/28230: - // Replace this once Ascii.IsValid exists. internal static unsafe bool IsAllAscii(ReadOnlySpan s) { +#if NET8_0_OR_GREATER + return System.Text.Ascii.IsValid(s); +#else fixed (char* src = s) { uint* ptrUInt32 = (uint*)src; @@ -172,6 +173,7 @@ internal static unsafe bool IsAllAscii(ReadOnlySpan s) [MethodImpl(MethodImplOptions.AggressiveInlining)] static bool AllCharsInUInt32AreAscii(uint value) => (value & ~0x007F_007Fu) == 0; +#endif } private static double GetUniquenessFactor(HashSet set, ReadOnlySpan uniqueStrings) diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs index d0a9da1de230d2..780a43ca5be632 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs @@ -1183,6 +1183,13 @@ void IList.Clear() throw new NotSupportedException(); } + private static bool IsCompatibleObject(object? value) + { + // Non-null values are fine. Only accept nulls if T is a class or Nullable. + // Note that default(T) is not equal to null for value types except when T is Nullable. + return (value is T) || (default(T) == null && value == null); + } + /// /// Determines whether the contains a specific value. /// @@ -1192,9 +1199,13 @@ void IList.Clear() /// bool IList.Contains(object? value) { - ImmutableArray self = this; - self.ThrowInvalidOperationIfNotInitialized(); - return self.Contains((T)value!); + if (IsCompatibleObject(value)) + { + ImmutableArray self = this; + self.ThrowInvalidOperationIfNotInitialized(); + return self.Contains((T)value!); + } + return false; } /// @@ -1206,9 +1217,13 @@ bool IList.Contains(object? value) /// int IList.IndexOf(object? value) { - ImmutableArray self = this; - self.ThrowInvalidOperationIfNotInitialized(); - return self.IndexOf((T)value!); + if (IsCompatibleObject(value)) + { + ImmutableArray self = this; + self.ThrowInvalidOperationIfNotInitialized(); + return self.IndexOf((T)value!); + } + return -1; } /// diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs index 860d1c850c607c..9d0d342f3d2375 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs @@ -1123,7 +1123,7 @@ private static bool IsCompatibleObject(object? value) { // Non-null values are fine. Only accept nulls if T is a class or Nullable. // Note that default(T) is not equal to null for value types except when T is Nullable. - return ((value is T) || (value == null && default(T) == null)); + return (value is T) || (default(T) == null && value == null); } /// diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs index 1eb2b639615081..ba832877714757 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -840,6 +839,13 @@ void IList.Clear() throw new NotSupportedException(); } + private static bool IsCompatibleObject(object? value) + { + // Non-null values are fine. Only accept nulls if T is a class or Nullable. + // Note that default(T) is not equal to null for value types except when T is Nullable. + return (value is T) || (default(T) == null && value == null); + } + /// /// Determines whether the contains a specific value. /// @@ -849,7 +855,11 @@ void IList.Clear() /// bool IList.Contains(object? value) { - return this.Contains((T)value!); + if (IsCompatibleObject(value)) + { + return this.Contains((T)value!); + } + return false; } /// @@ -861,7 +871,11 @@ bool IList.Contains(object? value) /// int IList.IndexOf(object? value) { - return this.IndexOf((T)value!); + if (IsCompatibleObject(value)) + { + return this.IndexOf((T)value!); + } + return -1; } /// diff --git a/src/libraries/System.Collections.Immutable/src/System/Runtime.InteropServices/ImmutableCollectionsMarshal.cs b/src/libraries/System.Collections.Immutable/src/System/Runtime.InteropServices/ImmutableCollectionsMarshal.cs new file mode 100644 index 00000000000000..737a3a862a2d47 --- /dev/null +++ b/src/libraries/System.Collections.Immutable/src/System/Runtime.InteropServices/ImmutableCollectionsMarshal.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Immutable; + +namespace System.Runtime.InteropServices +{ + /// + /// An unsafe class that provides a set of methods to access the underlying data representations of immutable collections. + /// + public static class ImmutableCollectionsMarshal + { + /// + /// Gets an value wrapping the input array. + /// + /// The type of elements in the input array. + /// The input array to wrap in the returned value. + /// An value wrapping . + /// + /// + /// When using this method, callers should take extra care to ensure that they're the sole owners of the input + /// array, and that it won't be modified once the returned value starts being + /// used. Doing so might cause undefined behavior in code paths which don't expect the contents of a given + /// values to change after its creation. + /// + /// + /// If is , the returned value + /// will be uninitialized (ie. its property will be ). + /// + /// + public static ImmutableArray AsImmutableArray(T[]? array) + { + return new(array); + } + + /// + /// Gets the underlying array for an input value. + /// + /// The type of elements in the input value. + /// The input value to get the underlying array from. + /// The underlying array for , if present. + /// + /// + /// When using this method, callers should make sure to not pass the resulting underlying array to methods that + /// might mutate it. Doing so might cause undefined behavior in code paths using which + /// don't expect the contents of the value to change. + /// + /// + /// If is uninitialized (ie. its property is + /// ), the resulting array will be . + /// + /// + public static T[]? AsArray(ImmutableArray array) + { + return array.array; + } + } +} diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs index 2b3490e0f8407b..75988fee38ba40 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs @@ -206,7 +206,7 @@ public void ToFrozenDictionary_KeySelectorAndValueSelector_ResultsAreUsed() } public static IEnumerable LookupItems_AllItemsFoundAsExpected_MemberData() => - from size in new[] { 0, 1, 2, 10, 999, 1024 } + from size in new[] { 0, 1, 2, 10, 99 } from comparer in new IEqualityComparer[] { null, EqualityComparer.Default, NonDefaultEqualityComparer.Instance } from specifySameComparer in new[] { false, true } select new object[] { size, comparer, specifySameComparer }; diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs index 925a45edf44a40..1a7c7586e38c1b 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs @@ -169,7 +169,7 @@ public void ToFrozenSet_BoolArg_UsesDefaultComparer() } public static IEnumerable LookupItems_AllItemsFoundAsExpected_MemberData() => - from size in new[] { 0, 1, 2, 10, 999, 1024 } + from size in new[] { 0, 1, 2, 10, 99 } from comparer in new IEqualityComparer[] { null, EqualityComparer.Default, NonDefaultEqualityComparer.Instance } from specifySameComparer in new[] { false, true } select new object[] { size, comparer, specifySameComparer }; diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableCollectionsMarshal.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableCollectionsMarshal.cs new file mode 100644 index 00000000000000..76ed476ee571ef --- /dev/null +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableCollectionsMarshal.cs @@ -0,0 +1,156 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Xunit; + +namespace System.Collections.Immutable.Tests +{ + public class ImmutableCollectionsMarshalTest + { + [Fact] + public void AsImmutableArrayFromNullArray() + { + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(null).IsDefault); + } + + [Fact] + public void AsImmutableArrayFromEmptyArray() + { + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + Assert.True(ImmutableCollectionsMarshal.AsImmutableArray(Array.Empty()).IsEmpty); + } + + [Fact] + public void AsImmutableArrayFromExistingArray() + { + static void Test() + { + T[] array = new T[17]; + ImmutableArray immutableArray = ImmutableCollectionsMarshal.AsImmutableArray(array); + + Assert.False(immutableArray.IsDefault); + Assert.Equal(17, immutableArray.Length); + + ref T expectedRef = ref array[0]; + ref T actualRef = ref Unsafe.AsRef(in immutableArray.ItemRef(0)); + + Assert.True(Unsafe.AreSame(ref expectedRef, ref actualRef)); + } + + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + } + + [Fact] + public void AsArrayFromDefaultImmutableArray() + { + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + Assert.Null(ImmutableCollectionsMarshal.AsArray(default)); + } + + [Fact] + public void AsArrayFromEmptyImmutableArray() + { + static void Test() + { + T[]? array = ImmutableCollectionsMarshal.AsArray(ImmutableArray.Empty); + + Assert.NotNull(array); + Assert.Empty(array); + } + + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + } + + [Fact] + public void AsArrayFromConstructedImmutableArray() + { + static void Test() + { + ImmutableArray immutableArray = ImmutableArray.Create(new T[17]); + T[]? array = ImmutableCollectionsMarshal.AsArray(immutableArray); + + Assert.NotNull(array); + Assert.Equal(17, array.Length); + + ref T expectedRef = ref Unsafe.AsRef(in immutableArray.ItemRef(0)); + ref T actualRef = ref array[0]; + + Assert.True(Unsafe.AreSame(ref expectedRef, ref actualRef)); + } + + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + Test(); + } + + public class CustomClass + { + public object Foo; + public Guid Bar; + } + + public struct ManagedCustomStruct + { + public object Foo; + public Guid Bar; + } + + public struct UnmanagedCustomStruct + { + public Guid Foo; + public int Bar; + } + } +} diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableListTestBase.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableListTestBase.cs index 7fc27620ad48a3..1144529e790762 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableListTestBase.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableListTestBase.cs @@ -419,7 +419,6 @@ public void BinarySearch() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/85012", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))] public void BinarySearchPartialSortedList() { ImmutableArray reverseSorted = ImmutableArray.CreateRange(Enumerable.Range(1, 150).Select(n => n * 2).Reverse()); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs index c08c91d3d5a019..6b90b2a354b8b9 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs @@ -321,6 +321,7 @@ public void IListMethods() Assert.Equal("b", list[1]); Assert.Equal(0, list.IndexOf("a")); Assert.Equal(1, list.IndexOf("b")); + Assert.Equal(-1, list.IndexOf(null)); Assert.Throws(() => list.Add("b")); Assert.Throws(() => list[3] = "c"); Assert.Throws(() => list.Clear()); @@ -329,6 +330,10 @@ public void IListMethods() Assert.Throws(() => list.RemoveAt(0)); Assert.True(list.IsFixedSize); Assert.True(list.IsReadOnly); + + list = ImmutableSortedSet.Create(1, 2, 3); + Assert.Equal(-1, list.IndexOf(null)); + Assert.Equal(-1, list.IndexOf("a")); } [Fact] diff --git a/src/libraries/System.Collections.Immutable/tests/IndexOfTests.cs b/src/libraries/System.Collections.Immutable/tests/IndexOfTests.cs index 2af011e54ac75e..a9597abd53e97d 100644 --- a/src/libraries/System.Collections.Immutable/tests/IndexOfTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/IndexOfTests.cs @@ -44,6 +44,8 @@ public static void IndexOfTest( if (factory(list) is IList) { Assert.Equal(-1, ((IList)factory(list)).IndexOf(6)); + Assert.Equal(-1, ((IList)factory(list)).IndexOf(null)); + Assert.Equal(-1, ((IList)factory(list)).IndexOf("a")); } for (int idx = 0; idx < list.Count; idx++) diff --git a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj index de57ee0ab75e01..307c682fa908e4 100644 --- a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj +++ b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj @@ -4,6 +4,13 @@ $(NetCoreAppCurrent);$(NetFrameworkMinimum) true + + + --setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot + + 01:15:00 + + @@ -14,6 +21,7 @@ + diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateOnlyConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateOnlyConverter.cs index 5bfe8223a86000..098aab56f2debd 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateOnlyConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateOnlyConverter.cs @@ -4,7 +4,6 @@ using System.ComponentModel.Design.Serialization; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Reflection; namespace System.ComponentModel { @@ -86,16 +85,12 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen( culture ??= CultureInfo.CurrentCulture; - DateTimeFormatInfo? formatInfo = (DateTimeFormatInfo?)culture.GetFormat(typeof(DateTimeFormatInfo)); - if (culture == CultureInfo.InvariantCulture) { return dateOnly.ToString("yyyy-MM-dd", culture); } - string format = formatInfo!.ShortDatePattern; - - return dateOnly.ToString(format, CultureInfo.CurrentCulture); + return dateOnly.ToString(culture.DateTimeFormat.ShortDatePattern, culture); } if (destinationType == typeof(InstanceDescriptor) && value is DateOnly date) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeConverter.cs index 9eeffb9940ee37..8f94f445e68646 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeConverter.cs @@ -114,7 +114,7 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen( format = formatInfo!.ShortDatePattern + " " + formatInfo.ShortTimePattern; } - return dt.ToString(format, CultureInfo.CurrentCulture); + return dt.ToString(format, culture); } if (destinationType == typeof(InstanceDescriptor) && value is DateTime) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeOffsetConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeOffsetConverter.cs index 7ac65b5f70ff6d..3c7608b0b58933 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeOffsetConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateTimeOffsetConverter.cs @@ -126,7 +126,7 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen( format = formatInfo!.ShortDatePattern + " " + formatInfo.ShortTimePattern + " zzz"; } - return dto.ToString(format, CultureInfo.CurrentCulture); + return dto.ToString(format, culture); } if (destinationType == typeof(InstanceDescriptor) && value is DateTimeOffset) { diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/MaskedTextProvider.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/MaskedTextProvider.cs index 16d21e863042ff..5ca0b381632713 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/MaskedTextProvider.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/MaskedTextProvider.cs @@ -117,9 +117,6 @@ public override string ToString() => private static readonly int s_RESET_ON_LITERALS = BitVector32.CreateMask(s_RESET_ON_PROMPT); private static readonly int s_SKIP_SPACE = BitVector32.CreateMask(s_RESET_ON_LITERALS); - // Type cached to speed up cloning of this object. - private static readonly Type s_maskTextProviderType = typeof(MaskedTextProvider); - //// Instance data. // Bit vector to represent bool variables. @@ -460,9 +457,8 @@ private void Initialize() public object Clone() { MaskedTextProvider clonedProvider; - Type providerType = GetType(); - if (providerType == s_maskTextProviderType) + if (GetType() == typeof(MaskedTextProvider)) { clonedProvider = new MaskedTextProvider( Mask, @@ -484,7 +480,7 @@ public object Clone() AsciiOnly }; - clonedProvider = (Activator.CreateInstance(providerType, parameters) as MaskedTextProvider)!; + clonedProvider = (Activator.CreateInstance(GetType(), parameters) as MaskedTextProvider)!; } clonedProvider.ResetOnPrompt = false; diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TimeOnlyConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TimeOnlyConverter.cs index 4180508d2cc99a..4995940799ba88 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TimeOnlyConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TimeOnlyConverter.cs @@ -4,7 +4,6 @@ using System.ComponentModel.Design.Serialization; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Reflection; namespace System.ComponentModel { @@ -86,9 +85,7 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen( culture ??= CultureInfo.CurrentCulture; - DateTimeFormatInfo formatInfo = (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo))!; - - return timeOnly.ToString(formatInfo.ShortTimePattern, CultureInfo.CurrentCulture); + return timeOnly.ToString(culture.DateTimeFormat.ShortTimePattern, culture); } if (destinationType == typeof(InstanceDescriptor) && value is TimeOnly time) diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DateOnlyConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/DateOnlyConverterTests.cs index 8759db9cbb29f3..55d7414914cc92 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/DateOnlyConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/DateOnlyConverterTests.cs @@ -4,8 +4,6 @@ using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Globalization; -using System.Reflection; -using Microsoft.DotNet.RemoteExecutor; using Xunit; namespace System.ComponentModel.Tests @@ -31,12 +29,19 @@ public override IEnumerable ConvertFromTestData() public override IEnumerable ConvertToTestData() { + CultureInfo frenchCulture = new CultureInfo("fr-FR"); CultureInfo polandCulture = new CultureInfo("pl-PL"); DateTimeFormatInfo formatInfo = CultureInfo.CurrentCulture.DateTimeFormat; DateOnly dateOnly = new DateOnly(1998, 12, 5); yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(formatInfo.ShortDatePattern)); - yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(polandCulture.DateTimeFormat.ShortDatePattern, polandCulture.DateTimeFormat)) + yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(frenchCulture.DateTimeFormat.ShortDatePattern, frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(frenchCulture); + yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(frenchCulture.DateTimeFormat.ShortDatePattern, frenchCulture.DateTimeFormat), frenchCulture) .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(polandCulture.DateTimeFormat.ShortDatePattern, polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(polandCulture.DateTimeFormat.ShortDatePattern, polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(frenchCulture); yield return ConvertTest.Valid(dateOnly, "1998-12-05", CultureInfo.InvariantCulture) .WithRemoteInvokeCulture(polandCulture); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeConverterTests.cs index 0b4da49218de98..076e50bcf55e05 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeConverterTests.cs @@ -4,8 +4,6 @@ using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Globalization; -using System.Reflection; -using Microsoft.DotNet.RemoteExecutor; using Xunit; namespace System.ComponentModel.Tests @@ -31,19 +29,32 @@ public override IEnumerable ConvertFromTestData() public override IEnumerable ConvertToTestData() { + CultureInfo frenchCulture = new CultureInfo("fr-FR"); CultureInfo polandCulture = new CultureInfo("pl-PL"); DateTimeFormatInfo formatInfo = CultureInfo.CurrentCulture.DateTimeFormat; DateTime date = new DateTime(1998, 12, 5); yield return ConvertTest.Valid(date, date.ToString(formatInfo.ShortDatePattern)); - yield return ConvertTest.Valid(date, date.ToString(polandCulture.DateTimeFormat.ShortDatePattern, polandCulture.DateTimeFormat)) + yield return ConvertTest.Valid(date, date.ToString(frenchCulture.DateTimeFormat.ShortDatePattern, frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(frenchCulture); + yield return ConvertTest.Valid(date, date.ToString(frenchCulture.DateTimeFormat.ShortDatePattern, frenchCulture.DateTimeFormat), frenchCulture) .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(date, date.ToString(polandCulture.DateTimeFormat.ShortDatePattern, polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(date, date.ToString(polandCulture.DateTimeFormat.ShortDatePattern, polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(frenchCulture); yield return ConvertTest.Valid(date, "1998-12-05", CultureInfo.InvariantCulture) .WithRemoteInvokeCulture(polandCulture); DateTime dateWithTime = new DateTime(1998, 12, 5, 22, 30, 30); yield return ConvertTest.Valid(dateWithTime, dateWithTime.ToString(formatInfo.ShortDatePattern + " " + formatInfo.ShortTimePattern)); - yield return ConvertTest.Valid(dateWithTime, dateWithTime.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " " + polandCulture.DateTimeFormat.ShortTimePattern, polandCulture.DateTimeFormat)) + yield return ConvertTest.Valid(dateWithTime, dateWithTime.ToString(frenchCulture.DateTimeFormat.ShortDatePattern + " " + frenchCulture.DateTimeFormat.ShortTimePattern, frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(frenchCulture); + yield return ConvertTest.Valid(dateWithTime, dateWithTime.ToString(frenchCulture.DateTimeFormat.ShortDatePattern + " " + frenchCulture.DateTimeFormat.ShortTimePattern, frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(dateWithTime, dateWithTime.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " " + polandCulture.DateTimeFormat.ShortTimePattern, polandCulture.DateTimeFormat), polandCulture) .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(dateWithTime, dateWithTime.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " " + polandCulture.DateTimeFormat.ShortTimePattern, polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(frenchCulture); yield return ConvertTest.Valid(dateWithTime, "12/05/1998 22:30:30", CultureInfo.InvariantCulture) .WithRemoteInvokeCulture(polandCulture); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeOffsetConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeOffsetConverterTests.cs index 9ff1db0d16e6eb..52727ffe2fdef5 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeOffsetConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/DateTimeOffsetConverterTests.cs @@ -29,19 +29,32 @@ public override IEnumerable ConvertFromTestData() public override IEnumerable ConvertToTestData() { + CultureInfo frenchCulture = new CultureInfo("fr-FR"); CultureInfo polandCulture = new CultureInfo("pl-PL"); DateTimeFormatInfo formatInfo = CultureInfo.CurrentCulture.DateTimeFormat; DateTimeOffset offset = new DateTimeOffset(new DateTime(1998, 12, 5)); yield return ConvertTest.Valid(offset, offset.ToString(formatInfo.ShortDatePattern + " zzz")); - yield return ConvertTest.Valid(offset, offset.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " zzz", polandCulture.DateTimeFormat)) - .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(offset, offset.ToString(frenchCulture.DateTimeFormat.ShortDatePattern + " zzz", frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(frenchCulture); + yield return ConvertTest.Valid(offset, offset.ToString(frenchCulture.DateTimeFormat.ShortDatePattern + " zzz", frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(offset, offset.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " zzz", polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(offset, offset.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " zzz", polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(frenchCulture); yield return ConvertTest.Valid(offset, offset.ToString("yyyy-MM-dd zzz", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture) .WithRemoteInvokeCulture(polandCulture); DateTimeOffset offsetWithTime = new DateTimeOffset(new DateTime(1998, 12, 5, 22, 30, 30)); yield return ConvertTest.Valid(offsetWithTime, offsetWithTime.ToString(formatInfo.ShortDatePattern + " " + formatInfo.ShortTimePattern + " zzz")); - yield return ConvertTest.Valid(offsetWithTime, offsetWithTime.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " " + polandCulture.DateTimeFormat.ShortTimePattern + " zzz", polandCulture.DateTimeFormat)) + yield return ConvertTest.Valid(offsetWithTime, offsetWithTime.ToString(frenchCulture.DateTimeFormat.ShortDatePattern + " " + frenchCulture.DateTimeFormat.ShortTimePattern + " zzz", frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(frenchCulture); + yield return ConvertTest.Valid(offsetWithTime, offsetWithTime.ToString(frenchCulture.DateTimeFormat.ShortDatePattern + " " + frenchCulture.DateTimeFormat.ShortTimePattern + " zzz", frenchCulture.DateTimeFormat), frenchCulture) + .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(offsetWithTime, offsetWithTime.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " " + polandCulture.DateTimeFormat.ShortTimePattern + " zzz", polandCulture.DateTimeFormat), polandCulture) .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(offsetWithTime, offsetWithTime.ToString(polandCulture.DateTimeFormat.ShortDatePattern + " " + polandCulture.DateTimeFormat.ShortTimePattern + " zzz", polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(frenchCulture); yield return ConvertTest.Valid(offsetWithTime, offsetWithTime.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture) .WithRemoteInvokeCulture(polandCulture); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TimeOnlyConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TimeOnlyConverterTests.cs index 15cf43e4c6d4b7..c9d032e11b452c 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/TimeOnlyConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TimeOnlyConverterTests.cs @@ -4,8 +4,6 @@ using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Globalization; -using System.Reflection; -using Microsoft.DotNet.RemoteExecutor; using Xunit; namespace System.ComponentModel.Tests @@ -37,18 +35,30 @@ public override IEnumerable ConvertFromTestData() public override IEnumerable ConvertToTestData() { + CultureInfo egyptCulture = new CultureInfo("ar-EG"); CultureInfo polandCulture = new CultureInfo("pl-PL"); DateTimeFormatInfo formatInfo = CultureInfo.CurrentCulture.DateTimeFormat; TimeOnly timeOnly = new TimeOnly(10, 30, 50); + TimeOnly timeOnlyWithMultipleRepresentation = new TimeOnly(13, 14, 15); yield return ConvertTest.Valid(timeOnly, timeOnly.ToString(formatInfo.ShortTimePattern)); yield return ConvertTest.Valid(timeOnly, timeOnly.ToString(polandCulture.DateTimeFormat.ShortTimePattern, polandCulture.DateTimeFormat)) .WithRemoteInvokeCulture(polandCulture); + yield return ConvertTest.Valid(timeOnly, timeOnly.ToString(polandCulture.DateTimeFormat.ShortTimePattern, polandCulture.DateTimeFormat), polandCulture) + .WithRemoteInvokeCulture(egyptCulture); + yield return ConvertTest.Valid(timeOnly, "10:30", CultureInfo.InvariantCulture); + yield return ConvertTest.Valid(timeOnlyWithMultipleRepresentation, timeOnlyWithMultipleRepresentation.ToString(egyptCulture.DateTimeFormat.ShortTimePattern, egyptCulture.DateTimeFormat), egyptCulture) + .WithRemoteInvokeCulture(egyptCulture); + + yield return ConvertTest.Valid(timeOnlyWithMultipleRepresentation, timeOnlyWithMultipleRepresentation.ToString(egyptCulture.DateTimeFormat.ShortTimePattern, egyptCulture.DateTimeFormat), egyptCulture) + .WithRemoteInvokeCulture(polandCulture); + + yield return ConvertTest.Valid(TimeOnly.MinValue, string.Empty); yield return ConvertTest.Valid( diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeConverterTestBase.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeConverterTestBase.cs index 527739375837d0..ce84f05f5bbf46 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeConverterTestBase.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeConverterTestBase.cs @@ -3,15 +3,13 @@ using System.Collections.Generic; using System.ComponentModel.Design.Serialization; -using System.Diagnostics; using System.Globalization; -using System.Linq; using System.IO; +using System.Linq; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; -using Microsoft.DotNet.RemoteExecutor; -using Xunit; using System.Tests; +using Xunit; namespace System.ComponentModel.Tests { diff --git a/src/libraries/System.Data.Common/src/System/Data/DataSetUtil.cs b/src/libraries/System.Data.Common/src/System/Data/DataSetUtil.cs index 0fff3918a0e244..7e82e9f5aab656 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataSetUtil.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataSetUtil.cs @@ -82,24 +82,17 @@ internal static ArgumentOutOfRangeException InvalidLoadOption(LoadOption value) return InvalidEnumerationValue(typeof(LoadOption), (int)value); } - // only StackOverflowException & ThreadAbortException are sealed classes - private static readonly Type s_stackOverflowType = typeof(StackOverflowException); - private static readonly Type s_outOfMemoryType = typeof(OutOfMemoryException); - private static readonly Type s_threadAbortType = typeof(System.Threading.ThreadAbortException); - private static readonly Type s_nullReferenceType = typeof(NullReferenceException); - private static readonly Type s_accessViolationType = typeof(AccessViolationException); - private static readonly Type s_securityType = typeof(System.Security.SecurityException); internal static bool IsCatchableExceptionType(Exception e) { // a 'catchable' exception is defined by what it is not. - Type type = e.GetType(); + // only StackOverflowException & ThreadAbortException are sealed classes - return ((type != s_stackOverflowType) && - (type != s_outOfMemoryType) && - (type != s_threadAbortType) && - (type != s_nullReferenceType) && - (type != s_accessViolationType) && - !s_securityType.IsAssignableFrom(type)); + return ((e.GetType() != typeof(StackOverflowException)) && + (e.GetType() != typeof(OutOfMemoryException)) && + (e.GetType() != typeof(System.Threading.ThreadAbortException)) && + (e.GetType() != typeof(NullReferenceException)) && + (e.GetType() != typeof(System.Security.SecurityException)) && + !typeof(System.Security.SecurityException).IsAssignableFrom(e.GetType())); } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Aggregator.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Aggregator.cs index 37807616807de3..0d6434e15468b0 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Aggregator.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Aggregator.cs @@ -30,12 +30,16 @@ public QuantileValue(double quantile, double value) internal sealed class HistogramStatistics : IAggregationStatistics { - internal HistogramStatistics(QuantileValue[] quantiles) + internal HistogramStatistics(QuantileValue[] quantiles, int count, double sum) { Quantiles = quantiles; + Count = count; + Sum = sum; } public QuantileValue[] Quantiles { get; } + public int Count { get; } + public double Sum { get; } } internal sealed class LabeledAggregationStatistics diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/ExponentialHistogramAggregator.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/ExponentialHistogramAggregator.cs index 678cf6ea890ac5..80a2924f22fb49 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/ExponentialHistogramAggregator.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/ExponentialHistogramAggregator.cs @@ -43,10 +43,13 @@ internal sealed class ExponentialHistogramAggregator : Aggregator private const int ExponentArraySize = 4096; private const int ExponentShift = 52; private const double MinRelativeError = 0.0001; + private const int PositiveIntAndNan = ExponentArraySize / 2 - 1; + private const int NegativeIntAndNan = ExponentArraySize - 1; private readonly QuantileAggregation _config; private int[]?[] _counters; private int _count; + private double _sum; private readonly int _mantissaMax; private readonly int _mantissaMask; private readonly int _mantissaShift; @@ -81,24 +84,24 @@ public override IAggregationStatistics Collect() { int[]?[] counters; int count; + double sum; lock (this) { counters = _counters; count = _count; + sum = _sum; _counters = new int[ExponentArraySize][]; _count = 0; + _sum = 0; } QuantileValue[] quantiles = new QuantileValue[_config.Quantiles.Length]; int nextQuantileIndex = 0; if (nextQuantileIndex == _config.Quantiles.Length) { - return new HistogramStatistics(quantiles); + return new HistogramStatistics(quantiles, count, sum); } - // Reduce the count if there are any NaN or +/-Infinity values that were logged - count -= GetInvalidCount(counters); - // Consider each bucket to have N entries in it, and each entry has value GetBucketCanonicalValue(). // If all these entries were inserted in a sorted array, we are trying to find the value of the entry with // index=target. @@ -116,36 +119,14 @@ public override IAggregationStatistics Collect() nextQuantileIndex++; if (nextQuantileIndex == _config.Quantiles.Length) { - return new HistogramStatistics(quantiles); + return new HistogramStatistics(quantiles, count, sum); } target = QuantileToRank(_config.Quantiles[nextQuantileIndex], count); } } Debug.Assert(count == 0); - return new HistogramStatistics(Array.Empty()); - } - - private static int GetInvalidCount(int[]?[] counters) - { - int[]? positiveInfAndNan = counters[ExponentArraySize / 2 - 1]; - int[]? negativeInfAndNan = counters[ExponentArraySize - 1]; - int count = 0; - if (positiveInfAndNan != null) - { - foreach (int bucketCount in positiveInfAndNan) - { - count += bucketCount; - } - } - if (negativeInfAndNan != null) - { - foreach (int bucketCount in negativeInfAndNan) - { - count += bucketCount; - } - } - return count; + return new HistogramStatistics(Array.Empty(), count, sum); } private IEnumerable IterateBuckets(int[]?[] counters) @@ -205,7 +186,13 @@ public override void Update(double measurement) ref int[]? mantissaCounts = ref _counters[exponent]; mantissaCounts ??= new int[_mantissaMax]; mantissaCounts[mantissa]++; - _count++; + + // Don't increase the count if there are any NaN or +/-Infinity values that were logged + if (exponent != PositiveIntAndNan && exponent != NegativeIntAndNan) + { + _count++; + _sum += measurement; + } } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs index 42a98185c9b0b1..245a1e6e76ba79 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs @@ -118,12 +118,12 @@ public void GaugeValuePublished(string sessionId, string meterName, string? mete WriteEvent(5, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, lastValue); } - [Event(6, Keywords = Keywords.TimeSeriesValues)] + [Event(6, Keywords = Keywords.TimeSeriesValues, Version=1)] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] - public void HistogramValuePublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string? unit, string tags, string quantiles) + public void HistogramValuePublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string? unit, string tags, string quantiles, int count, double sum) { - WriteEvent(6, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, quantiles); + WriteEvent(6, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, quantiles, count, sum); } // Sent when we begin to monitor the value of a intrument, either because new session filter arguments changed subscriptions @@ -435,7 +435,7 @@ private static void TransmitMetricValue(Instrument instrument, LabeledAggregatio } else if (stats.AggregationStatistics is HistogramStatistics histogramStats) { - Log.HistogramValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, FormatTags(stats.Labels), FormatQuantiles(histogramStats.Quantiles)); + Log.HistogramValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, FormatTags(stats.Labels), FormatQuantiles(histogramStats.Quantiles), histogramStats.Count, histogramStats.Sum); } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ExponentialHistogramTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ExponentialHistogramTests.cs index 75ceeb1ac92d59..66f153182619eb 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ExponentialHistogramTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ExponentialHistogramTests.cs @@ -31,6 +31,8 @@ public void HappyPath() Assert.Equal(3, stats.Quantiles[0].Value); Assert.Equal(0.95, stats.Quantiles[1].Quantile); Assert.Equal(5, stats.Quantiles[1].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(15, stats.Sum); } [Fact] @@ -49,6 +51,8 @@ public void MinMax() Assert.Equal(1, stats.Quantiles[0].Value); Assert.Equal(1.0, stats.Quantiles[1].Quantile); Assert.Equal(5, stats.Quantiles[1].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(15, stats.Sum); } [Fact] @@ -63,6 +67,8 @@ public void NoQuantiles() aggregator.Update(5); var stats = (HistogramStatistics)aggregator.Collect(); Assert.Equal(0, stats.Quantiles.Length); + Assert.Equal(5, stats.Count); + Assert.Equal(15, stats.Sum); } [Fact] @@ -81,6 +87,8 @@ public void OutOfBoundsQuantiles() Assert.Equal(1, stats.Quantiles[0].Value); Assert.Equal(100, stats.Quantiles[1].Quantile); Assert.Equal(5, stats.Quantiles[1].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(15, stats.Sum); } [Fact] @@ -99,6 +107,8 @@ public void UnorderedQuantiles() Assert.Equal(1, stats.Quantiles[0].Value); Assert.Equal(0.9, stats.Quantiles[1].Quantile); Assert.Equal(5, stats.Quantiles[1].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(15, stats.Sum); } [Fact] @@ -121,6 +131,8 @@ public void DifferencesLessThanErrorBound() Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(100, stats.Quantiles[0].Value); Assert.True(Math.Abs(100.01 - stats.Quantiles[0].Value) <= 100.01 * quantiles.MaxRelativeError); + Assert.Equal(10, stats.Count); + Assert.Equal(950.22, stats.Sum); } [Fact] @@ -146,6 +158,8 @@ public void DifferencesGreaterThanErrorBound() //At default error of 0.001 result of 100 would be acceptable, but with higher precision it is not Assert.True(100 < stats.Quantiles[0].Value); Assert.True(Math.Abs(100.01 - stats.Quantiles[0].Value) <= 100.01 * quantiles.MaxRelativeError); + Assert.Equal(10, stats.Count); + Assert.Equal(950.22, stats.Sum); } [Fact] @@ -157,6 +171,8 @@ public void NoUpdates() Assert.NotNull(stats); Assert.Equal(0, stats.Quantiles.Length); + Assert.Equal(0, stats.Count); + Assert.Equal(0, stats.Sum); } [Fact] @@ -171,6 +187,8 @@ public void OneUpdate() Assert.Equal(1, stats.Quantiles.Length); Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(99, stats.Quantiles[0].Value); + Assert.Equal(1, stats.Count); + Assert.Equal(99, stats.Sum); } [Fact] @@ -188,6 +206,8 @@ public void NoUpdatesInSomeIntervals() Assert.NotNull(stats); Assert.Equal(0, stats.Quantiles.Length); + Assert.Equal(0, stats.Count); + Assert.Equal(0, stats.Sum); } [Fact] @@ -198,6 +218,8 @@ public void UpdatesAfterNoUpdates() var stats = (HistogramStatistics)aggregator.Collect(); Assert.NotNull(stats); Assert.Equal(0, stats.Quantiles.Length); + Assert.Equal(0, stats.Count); + Assert.Equal(0, stats.Sum); aggregator.Update(1); aggregator.Update(2); @@ -210,6 +232,8 @@ public void UpdatesAfterNoUpdates() Assert.Equal(1, stats.Quantiles.Length); Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(3, stats.Quantiles[0].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(15, stats.Sum); } [Fact] @@ -228,6 +252,8 @@ public void IterateCollect() Assert.Equal(1, stats.Quantiles.Length); Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(3, stats.Quantiles[0].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(15, stats.Sum); aggregator.Update(9); aggregator.Update(8); @@ -240,6 +266,8 @@ public void IterateCollect() Assert.Equal(1, stats.Quantiles.Length); Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(7, stats.Quantiles[0].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(35, stats.Sum); } [Fact] @@ -259,6 +287,8 @@ public void NegativeValues() Assert.Equal(1, stats.Quantiles.Length); Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(-3, stats.Quantiles[0].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(-15, stats.Sum); } [Fact] @@ -278,6 +308,8 @@ public void ZeroValues() Assert.Equal(1, stats.Quantiles.Length); Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(0, stats.Quantiles[0].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(0, stats.Sum); } [Fact] @@ -297,6 +329,8 @@ public void MixedValues() Assert.Equal(1, stats.Quantiles.Length); Assert.Equal(0.5, stats.Quantiles[0].Quantile); Assert.Equal(-0.5, stats.Quantiles[0].Value); + Assert.Equal(5, stats.Count); + Assert.Equal(99825.1769, stats.Sum); } [Fact] @@ -318,6 +352,26 @@ public void FilterNaNAndInfinities() Assert.Equal(100, stats.Quantiles[0].Value); Assert.Equal(1, stats.Quantiles[1].Quantile); Assert.Equal(100, stats.Quantiles[1].Value); + Assert.Equal(1, stats.Count); + Assert.Equal(100, stats.Sum); + } + + [Fact] + public void FilterOnlyNaNAndInfinities() + { + QuantileAggregation quantiles = new QuantileAggregation(0, 1); + ExponentialHistogramAggregator aggregator = new ExponentialHistogramAggregator(quantiles); + + aggregator.Update(double.NaN); + aggregator.Update(-double.NaN); + aggregator.Update(double.PositiveInfinity); + aggregator.Update(double.NegativeInfinity); + var stats = (HistogramStatistics)aggregator.Collect(); + + Assert.NotNull(stats); + Assert.Equal(0, stats.Quantiles.Length); + Assert.Equal(0, stats.Count); + Assert.Equal(0, stats.Sum); } } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs index 1229706331d431..ac8da362c8d2ca 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs @@ -59,7 +59,7 @@ public void EventSourcePublishesTimeSeriesWithEmptyMetadata() AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("-33", "-33"), ("-40", "-73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "-11"), ("-11", "-22")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); @@ -100,7 +100,7 @@ public void EventSourcePublishesTimeSeriesWithMetadata() AssertCounterEventsPresent(events, meter.Name, c.Name, "", c.Unit, ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", oc.Unit, ("", "10"), ("7", "17"), ("7", "24")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", og.Unit, "9", "18", "27"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", h.Unit, "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", h.Unit, ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", udc.Unit, ("33", "33"), ("40", "73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", oudc.Unit, ("", "11"), ("11", "22"), ("11", "33")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); @@ -155,7 +155,7 @@ public void EventSourcePublishesTimeSeriesForLateMeter() AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("33", "33"), ("40", "73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "-11"), ("-11", "-22")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); @@ -211,7 +211,7 @@ public void EventSourcePublishesTimeSeriesForLateInstruments() AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("-33", "-33"), ("-40", "-73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "11"), ("11", "22")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); @@ -287,8 +287,8 @@ public void EventSourcePublishesTimeSeriesWithTags() AssertCounterEventsPresent(events, meter.Name, oc.Name, "Color=blue,Size=4", "", ("", "20"), ("14", "34")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "Color=red,Size=19", "", "9", "18"); AssertGaugeEventsPresent(events, meter.Name, og.Name, "Color=blue,Size=4", "", "18", "36"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "Size=123", "", "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "Size=124", "", "0.5=20;0.95=20;0.99=20", "0.5=27;0.95=27;0.99=27"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "Size=123", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "Size=124", "", ("0.5=20;0.95=20;0.99=20", "1", "20"), ("0.5=27;0.95=27;0.99=27", "1", "27")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "Color=red", "", ("-33", "-33"), ("40", "7")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "Color=blue", "", ("-34", "-34"), ("41", "7")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "Color=red,Size=19", "", ("", "-11"), ("-11", "-22")); @@ -441,7 +441,7 @@ public void EventSourcePublishesMissingDataPoints() AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("0", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "17"), ("0", "17"), ("14", "31"), ("0", "31")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "18", "", "36", ""); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", "0.5=19;0.95=19;0.99=19", "", "0.5=26;0.95=26;0.99=26", ""); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("", "0", "0"), ("0.5=26;0.95=26;0.99=26", "1", "26"), ("", "0", "0")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("33", "33"), ("0", "33"), ("40", "73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "22"), ("0", "22"), ("22", "44"), ("0", "44")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 5); @@ -487,7 +487,7 @@ public void EventSourceRejectsNewListener() AssertCounterEventsPresent(events, meter.Name, c.Name, "", c.Unit, ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", oc.Unit, ("", "10"), ("7", "17"), ("7", "24")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", og.Unit, "9", "18", "27"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", h.Unit, "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", h.Unit, ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", udc.Unit, ("33", "33"), ("40", "73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", oudc.Unit, ("", "11"), ("11", "22"), ("11", "33")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); @@ -535,7 +535,7 @@ public void EventSourcePublishesEndEventsOnMeterDispose() AssertCounterEventsPresent(events, meterA.Name, c.Name, "", c.Unit, ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meterA.Name, oc.Name, "", oc.Unit, ("", "10"), ("7", "17"), ("7", "24")); AssertGaugeEventsPresent(events, meterA.Name, og.Name, "", og.Unit, "9", "18", "27"); - AssertHistogramEventsPresent(events, meterB.Name, h.Name, "", h.Unit, "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26", "0.5=21;0.95=21;0.99=21"); + AssertHistogramEventsPresent(events, meterB.Name, h.Name, "", h.Unit, ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26"), ("0.5=21;0.95=21;0.99=21", "1", "21")); AssertUpDownCounterEventsPresent(events, meterA.Name, udc.Name, "", udc.Unit, ("33", "33"), ("40", "73")); AssertUpDownCounterEventsPresent(events, meterA.Name, oudc.Name, "", oudc.Unit, ("", "11"), ("11", "22"), ("11", "33")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 4); @@ -701,8 +701,8 @@ public void EventSourceEnforcesHistogramLimit() AssertBeginInstrumentReportingEventsPresent(events, h); AssertInitialEnumerationCompleteEventPresent(events); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=red", "", "0.5=5;0.95=5;0.99=5", "0.5=12;0.95=12;0.99=12"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=blue", "", "0.5=6;0.95=6;0.99=6", "0.5=13;0.95=13;0.99=13"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=red", "", ("0.5=5;0.95=5;0.99=5", "1", "5"), ("0.5=12;0.95=12;0.99=12", "1", "12")); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=blue", "", ("0.5=6;0.95=6;0.99=6", "1", "6"), ("0.5=13;0.95=13;0.99=13", "1", "13")); AssertHistogramLimitPresent(events); AssertHistogramEventsNotPresent(events, meter.Name, h.Name, "Color=green"); AssertHistogramEventsNotPresent(events, meter.Name, h.Name, "Color=yellow"); @@ -771,7 +771,7 @@ public void EventSourceWorksWithSequentialListeners() AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("33", "33"), ("40", "73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "11"), ("11", "22")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); @@ -798,7 +798,7 @@ public void EventSourceWorksWithSequentialListeners() AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17")); AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "31"), ("7", "38")); AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "36", "45"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", "0.5=19;0.95=19;0.99=19", "0.5=26;0.95=26;0.99=26"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("33", "33"), ("40", "73")); AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "44"), ("11", "55")); AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); @@ -835,8 +835,8 @@ public void EventSourceEnforcesHistogramLimitAndNotMaxTimeSeries() AssertBeginInstrumentReportingEventsPresent(events, h); AssertInitialEnumerationCompleteEventPresent(events); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=red", "", "0.5=5;0.95=5;0.99=5", "0.5=12;0.95=12;0.99=12"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=blue", "", "0.5=6;0.95=6;0.99=6", "0.5=13;0.95=13;0.99=13"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=red", "", ("0.5=5;0.95=5;0.99=5", "1", "5"), ("0.5=12;0.95=12;0.99=12", "1", "12")); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "Color=blue", "", ("0.5=6;0.95=6;0.99=6", "1", "6"), ("0.5=13;0.95=13;0.99=13", "1", "13")); AssertHistogramLimitPresent(events); AssertTimeSeriesLimitNotPresent(events); AssertHistogramEventsNotPresent(events, meter.Name, h.Name, "Color=green"); @@ -1016,7 +1016,7 @@ private void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, string met } private void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, - string expectedUnit, params string[] expectedQuantiles) + string expectedUnit, params (string, string, string)[] expected) { var counterEvents = events.Where(e => e.EventName == "HistogramValuePublished").Select(e => new @@ -1026,14 +1026,18 @@ private void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, string InstrumentName = e.Payload[3].ToString(), Unit = e.Payload[4].ToString(), Tags = e.Payload[5].ToString(), - Quantiles = (string)e.Payload[6] + Quantiles = (string)e.Payload[6], + Count = e.Payload[7].ToString(), + Sum = e.Payload[8].ToString() }).ToArray(); var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags).ToArray(); - Assert.True(filteredEvents.Length >= expectedQuantiles.Length); - for (int i = 0; i < expectedQuantiles.Length; i++) + Assert.True(filteredEvents.Length >= expected.Length); + for (int i = 0; i < expected.Length; i++) { Assert.Equal(filteredEvents[i].Unit, expectedUnit); - Assert.Equal(expectedQuantiles[i], filteredEvents[i].Quantiles); + Assert.Equal(expected[i].Item1, filteredEvents[i].Quantiles); + Assert.Equal(expected[i].Item2, filteredEvents[i].Count); + Assert.Equal(expected[i].Item3, filteredEvents[i].Sum); } } diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs index fb39a10499084d..b9556fdd285049 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs @@ -390,16 +390,19 @@ private static unsafe bool TryReadCharacterStringCore( Text.Encoding encoding, out int charsWritten) { - if (source.Length == 0) + try { - charsWritten = 0; - return true; - } +#if NET8_0_OR_GREATER + return encoding.TryGetChars(source, destination, out charsWritten); +#else + if (source.Length == 0) + { + charsWritten = 0; + return true; + } - fixed (byte* bytePtr = &MemoryMarshal.GetReference(source)) - fixed (char* charPtr = &MemoryMarshal.GetReference(destination)) - { - try + fixed (byte* bytePtr = &MemoryMarshal.GetReference(source)) + fixed (char* charPtr = &MemoryMarshal.GetReference(destination)) { int charCount = encoding.GetCharCount(bytePtr, source.Length); @@ -411,13 +414,14 @@ private static unsafe bool TryReadCharacterStringCore( charsWritten = encoding.GetChars(bytePtr, source.Length, charPtr, destination.Length); Debug.Assert(charCount == charsWritten); - } - catch (DecoderFallbackException e) - { - throw new AsnContentException(SR.ContentException_DefaultMessage, e); - } - return true; + return true; + } +#endif + } + catch (DecoderFallbackException e) + { + throw new AsnContentException(SR.ContentException_DefaultMessage, e); } } diff --git a/src/libraries/System.Formats.Asn1/tests/Reader/ReadUTF8String.cs b/src/libraries/System.Formats.Asn1/tests/Reader/ReadUTF8String.cs index db38b0b2d4f356..23ebf28c402878 100644 --- a/src/libraries/System.Formats.Asn1/tests/Reader/ReadUTF8String.cs +++ b/src/libraries/System.Formats.Asn1/tests/Reader/ReadUTF8String.cs @@ -148,8 +148,6 @@ public static void TryCopyUTF8String( if (output.Length > 0) { - output[0] = 'a'; - copied = reader.TryReadCharacterString( output.AsSpan(0, expectedValue.Length - 1), UniversalTagNumber.UTF8String, @@ -157,7 +155,6 @@ public static void TryCopyUTF8String( Assert.False(copied, "reader.TryCopyUTF8String - too short"); Assert.Equal(0, charsWritten); - Assert.Equal('a', output[0]); } copied = reader.TryReadCharacterString( diff --git a/src/libraries/System.Formats.Tar/src/Resources/Strings.resx b/src/libraries/System.Formats.Tar/src/Resources/Strings.resx index a06bdd940f846c..4da08973956330 100644 --- a/src/libraries/System.Formats.Tar/src/Resources/Strings.resx +++ b/src/libraries/System.Formats.Tar/src/Resources/Strings.resx @@ -264,4 +264,10 @@ The value of the size field for the current entry of format '{0}' is greater than the format allows. - + + The extended attribute key '{0}' contains a disallowed '{1}' character. + + + The value of the extended attribute key '{0}' contains a disallowed '{1}' character. + + \ No newline at end of file diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs index 9510746a5cab15..e51129631fc6d0 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs @@ -113,7 +113,27 @@ internal TarHeader(TarEntryFormat format, TarEntryType typeFlag, TarHeader other internal void InitializeExtendedAttributesWithExisting(IEnumerable> existing) { Debug.Assert(_ea == null); - _ea = new Dictionary(existing); + Debug.Assert(existing != null); + + using IEnumerator> enumerator = existing.GetEnumerator(); + while (enumerator.MoveNext()) + { + KeyValuePair kvp = enumerator.Current; + + int index = kvp.Key.IndexOfAny(new char[] { '=', '\n' }); + if (index >= 0) + { + throw new ArgumentException(SR.Format(SR.TarExtAttrDisallowedKeyChar, kvp.Key, kvp.Key[index] == '\n' ? "\\n" : kvp.Key[index])); + } + if (kvp.Value.Contains('\n')) + { + throw new ArgumentException(SR.Format(SR.TarExtAttrDisallowedValueChar, kvp.Key, "\\n")); + } + + _ea ??= new Dictionary(); + + _ea.Add(kvp.Key, kvp.Value); + } } private static string GetMagicForFormat(TarEntryFormat format) => format switch diff --git a/src/libraries/System.Formats.Tar/tests/TarEntry/PaxTarEntry.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarEntry/PaxTarEntry.Tests.cs index 0e8bcc952cea5d..19613acce46219 100644 --- a/src/libraries/System.Formats.Tar/tests/TarEntry/PaxTarEntry.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarEntry/PaxTarEntry.Tests.cs @@ -1,8 +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.IO; -using System.Linq; +using System.Collections.Generic; using Xunit; namespace System.Formats.Tar.Tests @@ -36,6 +35,30 @@ public void Constructor_UnsupportedEntryTypes() Assert.Throws(() => new PaxTarEntry(TarEntryType.GlobalExtendedAttributes, InitialEntryName)); } + + [Theory] + [InlineData("\n", "value")] + [InlineData("=", "value")] + [InlineData("key", "\n")] + [InlineData("\nkey", "value")] + [InlineData("k\ney", "value")] + [InlineData("key\n", "value")] + [InlineData("=key", "value")] + [InlineData("ke=y", "value")] + [InlineData("key=", "value")] + [InlineData("key", "\nvalue")] + [InlineData("key", "val\nue")] + [InlineData("key", "value\n")] + [InlineData("key=", "value\n")] + [InlineData("key\n", "value\n")] + public void Disallowed_ExtendedAttributes_SeparatorCharacters(string key, string value) + { + Dictionary extendedAttribute = new Dictionary() { { key, value } }; + + Assert.Throws(() => new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName, extendedAttribute)); + Assert.Throws(() => new PaxGlobalExtendedAttributesTarEntry(extendedAttribute)); + } + [Fact] public void SupportedEntryType_RegularFile() { diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs index 2b201696749391..02b959e0950d06 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs @@ -7,14 +7,8 @@ namespace System.Globalization.Tests { - public class CompareInfoIsPrefixTests + public class CompareInfoIsPrefixTests : CompareInfoTestsBase { - private static CompareInfo s_invariantCompare = CultureInfo.InvariantCulture.CompareInfo; - private static CompareInfo s_germanCompare = new CultureInfo("de-DE").CompareInfo; - private static CompareInfo s_hungarianCompare = new CultureInfo("hu-HU").CompareInfo; - private static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; - private static CompareInfo s_frenchCompare = new CultureInfo("fr-FR").CompareInfo; - public static IEnumerable IsPrefix_TestData() { // Empty strings @@ -31,7 +25,8 @@ public static IEnumerable IsPrefix_TestData() yield return new object[] { s_invariantCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false, 0 }; yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false, 0 }; yield return new object[] { s_invariantCompare, "dz", "d", CompareOptions.None, true, 1 }; - yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.None, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.None, false, 0 }; yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.Ordinal, true, 1 }; // Turkish @@ -56,7 +51,7 @@ public static IEnumerable IsPrefix_TestData() yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.Ordinal, false, 0 }; yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.OrdinalIgnoreCase, false, 0 }; yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false, 0 }; - yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true, 7 }; + yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", supportedIgnoreNonSpaceOption, true, 7 }; yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false, 0 }; yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, true, 1 }; yield return new object[] { s_invariantCompare, "o\u0000\u0308", "o", CompareOptions.None, true, 1 }; @@ -76,23 +71,32 @@ public static IEnumerable IsPrefix_TestData() yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true, 2 }; // Ignore symbols - yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.IgnoreSymbols, true, 6 }; - yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.None, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.IgnoreSymbols, true, 6 }; + yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.None, false, 0 }; + } // Platform differences - bool useNls = PlatformDetection.IsNlsGlobalization; - if (useNls) + // in HybridGlobalization on Browser we use TextEncoder that is not supported for v8 and the manual decoding works like NLS + bool behavesLikeNls = PlatformDetection.IsNlsGlobalization || + (PlatformDetection.IsHybridGlobalizationOnBrowser && !PlatformDetection.IsBrowserDomSupportedOrNodeJS); + if (behavesLikeNls) { - yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, true, 7 }; - yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, true, 7 }; - yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, true, 7 }; + yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, true, 7 }; + yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 }; + } yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.None, true, 1 }; yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.IgnoreCase, true, 1 }; } else { yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, false, 0 }; - yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, false, 0 }; yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, false, 0 }; yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.None, false, 0 }; yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.IgnoreCase, false, 0 }; @@ -100,18 +104,24 @@ public static IEnumerable IsPrefix_TestData() // ICU bugs // UInt16 overflow: https://unicode-org.atlassian.net/browse/ICU-20832 fixed in https://github.com/unicode-org/icu/pull/840 (ICU 65) - if (useNls || PlatformDetection.ICUVersion.Major >= 65) + if (PlatformDetection.IsNlsGlobalization || PlatformDetection.ICUVersion.Major >= 65) { yield return new object[] { s_frenchCompare, "b", new string('a', UInt16.MaxValue + 1), CompareOptions.None, false, 0 }; } // Prefixes where matched length does not equal value string length - yield return new object[] { s_invariantCompare, "dzxyz", "\u01F3", CompareOptions.IgnoreNonSpace, true, 2 }; - yield return new object[] { s_invariantCompare, "\u01F3xyz", "dz", CompareOptions.IgnoreNonSpace, true, 1 }; - yield return new object[] { s_germanCompare, "Strasse xyz", "stra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 7 }; - yield return new object[] { s_germanCompare, "Strasse xyz", "xtra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; - yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Strasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 6 }; - yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Xtrasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_invariantCompare, "dzxyz", "\u01F3", supportedIgnoreNonSpaceOption, true, 2 }; + yield return new object[] { s_invariantCompare, "\u01F3xyz", "dz", supportedIgnoreNonSpaceOption, true, 1 }; + } + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_germanCompare, "Strasse xyz", "stra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 7 }; + yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Strasse", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 6 }; + } + yield return new object[] { s_germanCompare, "Strasse xyz", "xtra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 }; + yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Xtrasse", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 }; } [Theory] @@ -140,8 +150,11 @@ public void IsPrefix(CompareInfo compareInfo, string source, string value, Compa valueBoundedMemory.MakeReadonly(); Assert.Equal(expected, compareInfo.IsPrefix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options)); - Assert.Equal(expected, compareInfo.IsPrefix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); - Assert.Equal(expectedMatchLength, actualMatchLength); + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + Assert.Equal(expected, compareInfo.IsPrefix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); + Assert.Equal(expectedMatchLength, actualMatchLength); + } } [Fact] @@ -150,7 +163,7 @@ public void IsPrefix_UnassignedUnicode() bool result = PlatformDetection.IsNlsGlobalization ? true : false; int expectedMatchLength = (result) ? 6 : 0; IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result, expectedMatchLength); - IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result, expectedMatchLength); + IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", supportedIgnoreNonSpaceOption, result, expectedMatchLength); } [Fact] diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs index edac5882b797c4..e5d8a10527c051 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs @@ -7,15 +7,8 @@ namespace System.Globalization.Tests { - public class CompareInfoIsSuffixTests + public class CompareInfoIsSuffixTests : CompareInfoTestsBase { - private static CompareInfo s_invariantCompare = CultureInfo.InvariantCulture.CompareInfo; - private static CompareInfo s_germanCompare = new CultureInfo("de-DE").CompareInfo; - private static CompareInfo s_hungarianCompare = new CultureInfo("hu-HU").CompareInfo; - private static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; - private static CompareInfo s_frenchCompare = new CultureInfo("fr-FR").CompareInfo; - private static CompareInfo s_slovakCompare = new CultureInfo("sk-SK").CompareInfo; - public static IEnumerable IsSuffix_TestData() { // Empty strings @@ -32,12 +25,16 @@ public static IEnumerable IsSuffix_TestData() yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.None, false, 0 }; yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.Ordinal, false, 0 }; yield return new object[] { s_invariantCompare, "dz", "z", CompareOptions.None, true, 1 }; - yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.None, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.None, false, 0 }; yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.Ordinal, true, 1 }; // Slovak - yield return new object[] { s_slovakCompare, "ch", "h", CompareOptions.None, false, 0 }; - yield return new object[] { s_slovakCompare, "velmi chora", "hora", CompareOptions.None, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_slovakCompare, "ch", "h", CompareOptions.None, false, 0 }; + yield return new object[] { s_slovakCompare, "velmi chora", "hora", CompareOptions.None, false, 0 }; + } yield return new object[] { s_slovakCompare, "chh", "H", CompareOptions.IgnoreCase, true, 1 }; // Turkish @@ -62,7 +59,7 @@ public static IEnumerable IsSuffix_TestData() yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.Ordinal, false, 0 }; yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.OrdinalIgnoreCase, false, 0 }; yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false, 0 }; - yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true, 7 }; + yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", supportedIgnoreNonSpaceOption, true, 7 }; yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false, 0 }; yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, false, 0 }; yield return new object[] { s_invariantCompare, "o\u0308o", "o", CompareOptions.None, true, 1 }; @@ -83,18 +80,27 @@ public static IEnumerable IsSuffix_TestData() yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true, 2 }; // Ignore symbols - yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.IgnoreSymbols, true, 6 }; - yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.None, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.IgnoreSymbols, true, 6 }; + yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.None, false, 0 }; + } // NULL character yield return new object[] { s_invariantCompare, "a\u0000b", "a\u0000b", CompareOptions.None, true, 3 }; yield return new object[] { s_invariantCompare, "a\u0000b", "b\u0000b", CompareOptions.None, false, 0 }; // Platform differences - if (PlatformDetection.IsNlsGlobalization) + // in HybridGlobalization on Browser we use TextEncoder that is not supported for v8 and the manual decoding works like NLS + bool behavesLikeNls = PlatformDetection.IsNlsGlobalization || + (PlatformDetection.IsHybridGlobalizationOnBrowser && !PlatformDetection.IsBrowserDomSupportedOrNodeJS); + if (behavesLikeNls) { - yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.None, true, 7 }; - yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.None, true, 7 }; + yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 }; + } yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.None, true, 1 }; yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.IgnoreCase, true, 1 }; } else @@ -106,12 +112,15 @@ public static IEnumerable IsSuffix_TestData() } // Suffixes where matched length does not equal value string length - yield return new object[] { s_invariantCompare, "xyzdz", "\u01F3", CompareOptions.IgnoreNonSpace, true, 2 }; - yield return new object[] { s_invariantCompare, "xyz\u01F3", "dz", CompareOptions.IgnoreNonSpace, true, 1 }; - yield return new object[] { s_germanCompare, "xyz Strasse", "stra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 7 }; - yield return new object[] { s_germanCompare, "xyz Strasse", "xtra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; - yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Strasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 6 }; - yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Xtrasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; + yield return new object[] { s_germanCompare, "xyz Strasse", "xtra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 }; + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + yield return new object[] { s_invariantCompare, "xyzdz", "\u01F3", supportedIgnoreNonSpaceOption, true, 2 }; + yield return new object[] { s_invariantCompare, "xyz\u01F3", "dz", supportedIgnoreNonSpaceOption, true, 1 }; + yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Strasse", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 6 }; + yield return new object[] { s_germanCompare, "xyz Strasse", "stra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 7 }; + } + yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Xtrasse", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 }; } [Theory] @@ -140,8 +149,11 @@ public void IsSuffix(CompareInfo compareInfo, string source, string value, Compa valueBoundedMemory.MakeReadonly(); Assert.Equal(expected, compareInfo.IsSuffix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options)); - Assert.Equal(expected, compareInfo.IsSuffix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); - Assert.Equal(expectedMatchLength, actualMatchLength); + if (!PlatformDetection.IsHybridGlobalizationOnBrowser) + { + Assert.Equal(expected, compareInfo.IsSuffix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); + Assert.Equal(expectedMatchLength, actualMatchLength); + } } [Fact] @@ -151,7 +163,7 @@ public void IsSuffix_UnassignedUnicode() int expectedMatchLength = (result) ? 6 : 0; IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result, expectedMatchLength); - IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result, expectedMatchLength); + IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", supportedIgnoreNonSpaceOption, result, expectedMatchLength); } [Fact] diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTestsBase.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTestsBase.cs index 617c13e1555ee4..01983c68651453 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTestsBase.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTestsBase.cs @@ -28,6 +28,7 @@ public class CompareInfoTestsBase protected static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; protected static CompareInfo s_japaneseCompare = new CultureInfo("ja-JP").CompareInfo; protected static CompareInfo s_slovakCompare = new CultureInfo("sk-SK").CompareInfo; + protected static CompareInfo s_frenchCompare = new CultureInfo("fr-FR").CompareInfo; protected static CompareOptions supportedIgnoreNonSpaceOption = PlatformDetection.IsHybridGlobalizationOnBrowser ? CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreKanaType : diff --git a/src/libraries/System.Globalization/tests/Hybrid/Hybrid.WASM.Tests.csproj b/src/libraries/System.Globalization/tests/Hybrid/Hybrid.WASM.Tests.csproj index a65d8448c4d70d..b8a19486362e34 100644 --- a/src/libraries/System.Globalization/tests/Hybrid/Hybrid.WASM.Tests.csproj +++ b/src/libraries/System.Globalization/tests/Hybrid/Hybrid.WASM.Tests.csproj @@ -10,5 +10,7 @@ + + diff --git a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs index 11b4dd5249843e..4fba5e19ff37d3 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs @@ -325,12 +325,14 @@ public void ToLower_Netcore(string name, string str, string expected) [Fact] public void ToLower_InvalidSurrogates() { + bool usesTextDecoder = PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsBrowserDomSupportedOrNodeJS; + // Invalid UTF-16 in a string (mismatched surrogate pairs) should be unchanged. foreach (string cultureName in new string[] { "", "en-US", "fr" }) { - ToLower(cultureName, "BE CAREFUL, \uD83C\uD83C, THIS ONE IS TRICKY", "be careful, \uD83C\uD83C, this one is tricky"); - ToLower(cultureName, "BE CAREFUL, \uDF08\uD83C, THIS ONE IS TRICKY", "be careful, \uDF08\uD83C, this one is tricky"); - ToLower(cultureName, "BE CAREFUL, \uDF08\uDF08, THIS ONE IS TRICKY", "be careful, \uDF08\uDF08, this one is tricky"); + ToLower(cultureName, "\uD83C\uD83C", usesTextDecoder ? "\uFFFD\uFFFD" : "\uD83C\uD83C"); + ToLower(cultureName, "BE CAREFUL, \uDF08\uD83C, THIS ONE IS TRICKY", usesTextDecoder ? "be careful, \uFFFD\uFFFD, this one is tricky" : "be careful, \uDF08\uD83C, this one is tricky"); + ToLower(cultureName, "BE CAREFUL, \uDF08\uDF08, THIS ONE IS TRICKY", usesTextDecoder ? "be careful, \uFFFD\uFFFD, this one is tricky" : "be careful, \uDF08\uDF08, this one is tricky"); } } @@ -452,12 +454,14 @@ public void ToUpper_netcore(string name, string str, string expected) [Fact] public void ToUpper_InvalidSurrogates() { + bool usesTextDecoder = PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsBrowserDomSupportedOrNodeJS; + // Invalid UTF-16 in a string (mismatched surrogate pairs) should be unchanged. foreach (string cultureName in new string[] { "", "en-US", "fr"}) { - ToUpper(cultureName, "be careful, \uD83C\uD83C, this one is tricky", "BE CAREFUL, \uD83C\uD83C, THIS ONE IS TRICKY"); - ToUpper(cultureName, "be careful, \uDF08\uD83C, this one is tricky", "BE CAREFUL, \uDF08\uD83C, THIS ONE IS TRICKY"); - ToUpper(cultureName, "be careful, \uDF08\uDF08, this one is tricky", "BE CAREFUL, \uDF08\uDF08, THIS ONE IS TRICKY"); + ToUpper(cultureName, "be careful, \uD83C\uD83C, this one is tricky", usesTextDecoder ? "BE CAREFUL, \uFFFD\uFFFD, THIS ONE IS TRICKY" : "BE CAREFUL, \uD83C\uD83C, THIS ONE IS TRICKY"); + ToUpper(cultureName, "be careful, \uDF08\uD83C, this one is tricky", usesTextDecoder ? "BE CAREFUL, \uFFFD\uFFFD, THIS ONE IS TRICKY" : "BE CAREFUL, \uDF08\uD83C, THIS ONE IS TRICKY"); + ToUpper(cultureName, "be careful, \uDF08\uDF08, this one is tricky", usesTextDecoder ? "BE CAREFUL, \uFFFD\uFFFD, THIS ONE IS TRICKY" : "BE CAREFUL, \uDF08\uDF08, THIS ONE IS TRICKY"); } } diff --git a/src/libraries/System.IO.Hashing/src/System.IO.Hashing.csproj b/src/libraries/System.IO.Hashing/src/System.IO.Hashing.csproj index 43f0bcf90d9c68..85072ee61e9d98 100644 --- a/src/libraries/System.IO.Hashing/src/System.IO.Hashing.csproj +++ b/src/libraries/System.IO.Hashing/src/System.IO.Hashing.csproj @@ -11,8 +11,14 @@ System.IO.Hashing.XxHash32 + + + diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Arm.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Arm.cs new file mode 100644 index 00000000000000..dae53164389da0 --- /dev/null +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Arm.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using ArmCrc = System.Runtime.Intrinsics.Arm.Crc32; + +namespace System.IO.Hashing +{ + public partial class Crc32 + { + private static uint UpdateScalarArm64(uint crc, ReadOnlySpan source) + { + Debug.Assert(ArmCrc.Arm64.IsSupported, "ARM CRC support is required."); + + // Compute in 8 byte chunks + if (source.Length >= sizeof(ulong)) + { + ref byte ptr = ref MemoryMarshal.GetReference(source); + int longLength = source.Length & ~0x7; // Exclude trailing bytes not a multiple of 8 + + for (int i = 0; i < longLength; i += sizeof(ulong)) + { + crc = ArmCrc.Arm64.ComputeCrc32(crc, + Unsafe.ReadUnaligned(ref Unsafe.Add(ref ptr, i))); + } + + source = source.Slice(longLength); + } + + // Compute remaining bytes + for (int i = 0; i < source.Length; i++) + { + crc = ArmCrc.ComputeCrc32(crc, source[i]); + } + + return crc; + } + + private static uint UpdateScalarArm32(uint crc, ReadOnlySpan source) + { + Debug.Assert(ArmCrc.IsSupported, "ARM CRC support is required."); + + // Compute in 4 byte chunks + if (source.Length >= sizeof(uint)) + { + ref byte ptr = ref MemoryMarshal.GetReference(source); + int intLength = source.Length & ~0x3; // Exclude trailing bytes not a multiple of 4 + + for (int i = 0; i < intLength; i += sizeof(uint)) + { + crc = ArmCrc.ComputeCrc32(crc, + Unsafe.ReadUnaligned(ref Unsafe.Add(ref ptr, i))); + } + + source = source.Slice(intLength); + } + + // Compute remaining bytes + for (int i = 0; i < source.Length; i++) + { + crc = ArmCrc.ComputeCrc32(crc, source[i]); + } + + return crc; + } + } +} diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs new file mode 100644 index 00000000000000..f584efa6e7d7af --- /dev/null +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs @@ -0,0 +1,216 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.Arm; +using Aes = System.Runtime.Intrinsics.Arm.Aes; + +namespace System.IO.Hashing +{ + public partial class Crc32 + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 CarrylessMultiplyLower(Vector128 left, Vector128 right) + { + if (Pclmulqdq.IsSupported) + { + return Pclmulqdq.CarrylessMultiply(left, right, 0x00); + } + + if (Aes.IsSupported) + { + return Aes.PolynomialMultiplyWideningLower(left.GetLower(), right.GetLower()); + } + + ThrowHelper.ThrowUnreachableException(); + return default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 CarrylessMultiplyUpper(Vector128 left, Vector128 right) + { + if (Pclmulqdq.IsSupported) + { + return Pclmulqdq.CarrylessMultiply(left, right, 0x11); + } + + if (Aes.IsSupported) + { + return Aes.PolynomialMultiplyWideningUpper(left, right); + } + + ThrowHelper.ThrowUnreachableException(); + return default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 CarrylessMultiplyLeftLowerRightUpper(Vector128 left, Vector128 right) + { + if (Pclmulqdq.IsSupported) + { + return Pclmulqdq.CarrylessMultiply(left, right, 0x10); + } + + if (Aes.IsSupported) + { + return Aes.PolynomialMultiplyWideningLower(left.GetLower(), right.GetUpper()); + } + + ThrowHelper.ThrowUnreachableException(); + return default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 ShiftRightBytesInVector(Vector128 operand, + [ConstantExpected(Max = (byte)15)] byte numBytesToShift) + { + if (Sse2.IsSupported) + { + return Sse2.ShiftRightLogical128BitLane(operand, numBytesToShift); + } + + if (AdvSimd.IsSupported) + { + return AdvSimd.ExtractVector128(operand.AsByte(), Vector128.Zero, numBytesToShift).AsUInt64(); + } + + ThrowHelper.ThrowUnreachableException(); + return default; + } + + // We check for little endian byte order here in case we're ever on ARM in big endian mode. + // All of these checks except the length check are elided by JIT, so the JITted implementation + // will be either a return false or a length check against a constant. This means this method + // should be inlined into the caller. + private static bool CanBeVectorized(ReadOnlySpan source) => + BitConverter.IsLittleEndian + && (Pclmulqdq.IsSupported || (Aes.IsSupported && AdvSimd.IsSupported)) + && source.Length >= Vector128.Count * 4; + + // Processes the bytes in source in 64 byte chunks using carryless/polynomial multiplication intrinsics, + // followed by processing 16 byte chunks, and then processing remaining bytes individually. Requires + // little endian byte order and support for PCLMULQDQ intrinsics on Intel architecture or AES and + // AdvSimd intrinsics on ARM architecture. Based on the algorithm put forth in the Intel paper "Fast CRC + // Computation for Generic Polynomials Using PCLMULQDQ Instruction" in December, 2009. + // https://github.com/intel/isa-l/blob/33a2d9484595c2d6516c920ce39a694c144ddf69/crc/crc32_ieee_by4.asm + // https://github.com/SixLabors/ImageSharp/blob/f4f689ce67ecbcc35cebddba5aacb603e6d1068a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs#L80 + private static uint UpdateVectorized(uint crc, ReadOnlySpan source) + { + Debug.Assert(CanBeVectorized(source), "source cannot be vectorized."); + + // Work with a reference to where we're at in the ReadOnlySpan and a local length + // to avoid extraneous range checks. + ref byte srcRef = ref MemoryMarshal.GetReference(source); + int length = source.Length; + + Vector128 x1 = Vector128.LoadUnsafe(ref srcRef).AsUInt64(); + Vector128 x2 = Vector128.LoadUnsafe(ref srcRef, 16).AsUInt64(); + Vector128 x3 = Vector128.LoadUnsafe(ref srcRef, 32).AsUInt64(); + Vector128 x4 = Vector128.LoadUnsafe(ref srcRef, 48).AsUInt64(); + Vector128 x5; + + x1 ^= Vector128.CreateScalar(crc).AsUInt64(); + Vector128 x0 = Vector128.Create(0x0154442bd4UL, 0x01c6e41596UL); // k1, k2 + + srcRef = ref Unsafe.Add(ref srcRef, Vector128.Count * 4); + length -= Vector128.Count * 4; + + // Parallel fold blocks of 64, if any. + while (length >= Vector128.Count * 4) + { + x5 = CarrylessMultiplyLower(x1, x0); + Vector128 x6 = CarrylessMultiplyLower(x2, x0); + Vector128 x7 = CarrylessMultiplyLower(x3, x0); + Vector128 x8 = CarrylessMultiplyLower(x4, x0); + + x1 = CarrylessMultiplyUpper(x1, x0); + x2 = CarrylessMultiplyUpper(x2, x0); + x3 = CarrylessMultiplyUpper(x3, x0); + x4 = CarrylessMultiplyUpper(x4, x0); + + Vector128 y5 = Vector128.LoadUnsafe(ref srcRef).AsUInt64(); + Vector128 y6 = Vector128.LoadUnsafe(ref srcRef, 16).AsUInt64(); + Vector128 y7 = Vector128.LoadUnsafe(ref srcRef, 32).AsUInt64(); + Vector128 y8 = Vector128.LoadUnsafe(ref srcRef, 48).AsUInt64(); + + x1 ^= x5; + x2 ^= x6; + x3 ^= x7; + x4 ^= x8; + + x1 ^= y5; + x2 ^= y6; + x3 ^= y7; + x4 ^= y8; + + srcRef = ref Unsafe.Add(ref srcRef, Vector128.Count * 4); + length -= Vector128.Count * 4; + } + + // Fold into 128-bits. + x0 = Vector128.Create(0x01751997d0UL, 0x00ccaa009eUL); // k3, k4 + + x5 = CarrylessMultiplyLower(x1, x0); + x1 = CarrylessMultiplyUpper(x1, x0); + x1 ^= x2; + x1 ^= x5; + + x5 = CarrylessMultiplyLower(x1, x0); + x1 = CarrylessMultiplyUpper(x1, x0); + x1 ^= x3; + x1 ^= x5; + + x5 = CarrylessMultiplyLower(x1, x0); + x1 = CarrylessMultiplyUpper(x1, x0); + x1 ^= x4; + x1 ^= x5; + + // Single fold blocks of 16, if any. + while (length >= Vector128.Count) + { + x2 = Vector128.LoadUnsafe(ref srcRef).AsUInt64(); + + x5 = CarrylessMultiplyLower(x1, x0); + x1 = CarrylessMultiplyUpper(x1, x0); + x1 ^= x2; + x1 ^= x5; + + srcRef = ref Unsafe.Add(ref srcRef, Vector128.Count); + length -= Vector128.Count; + } + + // Fold 128 bits to 64 bits. + x2 = CarrylessMultiplyLeftLowerRightUpper(x1, x0); + x3 = Vector128.Create(~0, 0, ~0, 0).AsUInt64(); + x1 = ShiftRightBytesInVector(x1, 8); + x1 ^= x2; + + x0 = Vector128.CreateScalar(0x0163cd6124UL); // k5, k0 + + x2 = ShiftRightBytesInVector(x1, 4); + x1 &= x3; + x1 = CarrylessMultiplyLower(x1, x0); + x1 ^= x2; + + // Reduce to 32 bits. + x0 = Vector128.Create(0x01db710641UL, 0x01f7011641UL); // polynomial + + x2 = x1 & x3; + x2 = CarrylessMultiplyLeftLowerRightUpper(x2, x0); + x2 &= x3; + x2 = CarrylessMultiplyLower(x2, x0); + x1 ^= x2; + + // Process the remaining bytes, if any + uint result = x1.AsUInt32().GetElement(1); + return length > 0 + ? UpdateScalar(result, MemoryMarshal.CreateReadOnlySpan(ref srcRef, length)) + : result; + } + } +} diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs index f48dc32d8a68ac..3a844a60637b07 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs @@ -169,6 +169,32 @@ public static uint HashToUInt32(ReadOnlySpan source) => private static uint Update(uint crc, ReadOnlySpan source) { +#if NET7_0_OR_GREATER + if (CanBeVectorized(source)) + { + return UpdateVectorized(crc, source); + } +#endif + + return UpdateScalar(crc, source); + } + + private static uint UpdateScalar(uint crc, ReadOnlySpan source) + { +#if NET6_0_OR_GREATER + // Use ARM intrinsics for CRC if available. This is used for the trailing bytes on the vectorized path + // and is the primary method if the vectorized path is unavailable. + if (System.Runtime.Intrinsics.Arm.Crc32.Arm64.IsSupported) + { + return UpdateScalarArm64(crc, source); + } + + if (System.Runtime.Intrinsics.Arm.Crc32.IsSupported) + { + return UpdateScalarArm32(crc, source); + } +#endif + ReadOnlySpan crcLookup = CrcLookup; for (int i = 0; i < source.Length; i++) { diff --git a/src/libraries/System.IO.Hashing/src/System/ThrowHelper.cs b/src/libraries/System.IO.Hashing/src/System/ThrowHelper.cs new file mode 100644 index 00000000000000..a7034983d33f9b --- /dev/null +++ b/src/libraries/System.IO.Hashing/src/System/ThrowHelper.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +namespace System +{ + internal static partial class ThrowHelper + { + [DoesNotReturn] + internal static void ThrowUnreachableException() => throw new UnreachableException(); + } +} diff --git a/src/libraries/System.IO.Hashing/tests/Crc32Tests.cs b/src/libraries/System.IO.Hashing/tests/Crc32Tests.cs index 217d7bfe90c8b4..f056f823f805c2 100644 --- a/src/libraries/System.IO.Hashing/tests/Crc32Tests.cs +++ b/src/libraries/System.IO.Hashing/tests/Crc32Tests.cs @@ -65,6 +65,21 @@ public static IEnumerable TestCases "The quick brown fox jumps over the lazy dog", "The quick brown fox jumps over the lazy dog"u8.ToArray(), "39A34F41"), + // Test a multiple of 64 bytes for vector optimizations + new TestCase( + "Lorem ipsum 128", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi quis iaculis nisl. Sed ornare sapien non nulla hendrerit viverra."u8.ToArray(), + "931A6737"), + // Test a multiple of 64 bytes + 16 bytes for vector optimizations + new TestCase( + "Lorem ipsum 144", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla libero est, semper in pharetra at, cursus id nulla. Class aptent taciti volutpat."u8.ToArray(), + "2B719549"), + // Test data that is > 64 bytes but not a multiple of 16 for vector optimizations + new TestCase( + "Lorem ipsum 1001", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac urna vitae nibh sagittis porttitor et vel ante. Ut molestie sit amet velit ac mattis. Sed ullamcorper nunc non neque imperdiet, vehicula bibendum sapien efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Suspendisse potenti. Duis sem dui, malesuada non pharetra at, feugiat id mi. Nulla facilisi. Fusce a scelerisque magna. Ut leo justo, auctor quis nisi et, sollicitudin pretium odio. Sed eu nibh mollis, pretium lectus nec, posuere nulla. Morbi ac euismod purus. Morbi rhoncus leo est, at volutpat nunc pretium in. Aliquam erat volutpat. Curabitur eu lacus mollis, varius lectus ut, tincidunt eros. Nullam a velit hendrerit, euismod magna id, fringilla sem. Phasellus scelerisque hendrerit est, vel imperdiet enim auctor a. Aenean vel ultricies nunc. Suspendisse ac tincidunt urna. Nulla tempor dolor ut ligula accumsan, tempus auctor massa gravida. Aenean non odio et augue pellena."u8.ToArray(), + "0464ED5F"), }; protected override NonCryptographicHashAlgorithm CreateInstance() => new Crc32(); diff --git a/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.proj b/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.proj index 81eb8e04bf39ee..1880e449969930 100644 --- a/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.proj +++ b/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.proj @@ -11,7 +11,7 @@ + They are filtered in the traversal build in oob-all.csproj based on the OutputRID. --> diff --git a/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.props b/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.props index bda41ce5319625..8ee8a9c20d8d7b 100644 --- a/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.props +++ b/src/libraries/System.IO.Ports/pkg/runtime.native.System.IO.Ports.props @@ -15,14 +15,14 @@ diff --git a/src/libraries/System.IO/tests/IndentedTextWriter.cs b/src/libraries/System.IO/tests/IndentedTextWriter.cs index 78d9a8db49d01d..67b4538aca768b 100644 --- a/src/libraries/System.IO/tests/IndentedTextWriter.cs +++ b/src/libraries/System.IO/tests/IndentedTextWriter.cs @@ -1,14 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Text; using System.CodeDom.Compiler; -using Xunit; +using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; +using System.Text; +using System.Threading; using System.Threading.Tasks; -using System.Globalization; -using System.Collections.Generic; +using Xunit; namespace System.CodeDom.Tests { @@ -243,6 +244,14 @@ public override Task FlushAsync() return result; } + public override Task FlushAsync(CancellationToken cancellationToken) + { + Task result = base.FlushAsync(); + LastCalledMethod = nameof(FlushAsync) + "Cancelable"; + + return result; + } + public override Task WriteAsync(char value) { Task result = base.WriteAsync(value); @@ -559,7 +568,6 @@ object[] CreateParameters(Func callWriteLineAsync, str private const string TabString = " "; private const string NewLine = "\n"; - [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] [Theory] [MemberData(nameof(WriteAsync_MemberData))] public async Task WriteAsync_WithoutIndents_CallsInnerWriteAsync(Func callWriteAsync, string expected) @@ -574,7 +582,6 @@ public async Task WriteAsync_WithoutIndents_CallsInnerWriteAsync(Func callWriteAsync, string expected) @@ -763,7 +770,6 @@ public void WriteLine_IsIndented_AfterWriteLine(Action callW Assert.Equal($"{prefix}{NewLine}{TabString}{expected}", indicator.GetStringBuilder().ToString()); } - [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] [Fact] public async Task FlushAsync_CallsUnderlyingFlushAsync() { @@ -775,6 +781,43 @@ public async Task FlushAsync_CallsUnderlyingFlushAsync() Assert.Equal(nameof(IndentedTextWriter.FlushAsync), indicator.LastCalledMethod); } + [Fact] + public async Task FlushAsync_Cancellation_CallsUnderlyingFlushAsync() + { + var indicator = new IndicatingTextWriter(); + var itw = new IndentedTextWriter(indicator); + + await itw.FlushAsync(new CancellationTokenSource().Token); + Assert.Equal(nameof(IndentedTextWriter.FlushAsync) + "Cancelable", indicator.LastCalledMethod); + + var cts = new CancellationTokenSource(); + cts.Cancel(); + Task t = itw.FlushAsync(cts.Token); + Assert.Equal(TaskStatus.Canceled, t.Status); + Assert.Equal(cts.Token, (await Assert.ThrowsAnyAsync(() => t)).CancellationToken); + } + + [Fact] + public async Task FlushAsync_DerivedIndentedTextWriter_NonCancelableFlushAsyncInvoked() + { + var itw = new DerivedIndentedTextWriter(TextWriter.Null); + await itw.FlushAsync(new CancellationTokenSource().Token); + Assert.True(itw.NonCancelableFlushAsyncInvoked); + } + + private sealed class DerivedIndentedTextWriter : IndentedTextWriter + { + public bool NonCancelableFlushAsyncInvoked; + + public DerivedIndentedTextWriter(TextWriter writer) : base(writer) { } + + public override Task FlushAsync() + { + NonCancelableFlushAsyncInvoked = true; + return Task.CompletedTask; + } + } + [Fact] public void Flush_CallsUnderlyingFlush() { diff --git a/src/libraries/System.IO/tests/StreamWriter/StreamWriter.FlushTests.cs b/src/libraries/System.IO/tests/StreamWriter/StreamWriter.FlushTests.cs index 92ed6d393ff668..ad79dea37efe1d 100644 --- a/src/libraries/System.IO/tests/StreamWriter/StreamWriter.FlushTests.cs +++ b/src/libraries/System.IO/tests/StreamWriter/StreamWriter.FlushTests.cs @@ -1,7 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.IO; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace System.IO.Tests @@ -30,5 +31,70 @@ public void AutoFlushSetFalse() sw2.AutoFlush = false; Assert.False(sw2.AutoFlush); } + + [Fact] + public async Task FlushAsync_Cancelable() + { + var sw = new StreamWriter(CreateStream()); + + await sw.FlushAsync(); + await sw.FlushAsync(CancellationToken.None); + await sw.FlushAsync(new CancellationTokenSource().Token); + + var cts = new CancellationTokenSource(); + cts.Cancel(); + Task t = sw.FlushAsync(cts.Token); + Assert.Equal(TaskStatus.Canceled, t.Status); + Assert.Equal(cts.Token, (await Assert.ThrowsAnyAsync(() => t)).CancellationToken); + + cts = new CancellationTokenSource(); + sw.Write("hello"); + await sw.FlushAsync(cts.Token); + + Stream s = sw.BaseStream; + s.Position = 0; + Assert.Equal("hello", new StreamReader(s).ReadToEnd()); + } + + [Fact] + public async Task FlushAsync_DerivedStreamWriter_NonCancelableFlushAsyncInvoked() + { + var sw = new DerivedStreamWriter(CreateStream()); + await sw.FlushAsync(new CancellationTokenSource().Token); + Assert.True(sw.NonCancelableFlushAsyncInvoked); + } + + [Fact] + public async Task FlushAsync_CancelsUnderlyingStreamOperation() + { + var sw = new StreamWriter(new WaitUntilCanceledWriteMemoryStream()); + sw.Write("hello"); + var cts = new CancellationTokenSource(); + Task t = sw.FlushAsync(cts.Token); + Assert.False(t.IsCompleted); + cts.Cancel(); + Assert.Equal(cts.Token, (await Assert.ThrowsAnyAsync(() => t)).CancellationToken); + } + + private sealed class DerivedStreamWriter : StreamWriter + { + public bool NonCancelableFlushAsyncInvoked; + + public DerivedStreamWriter(Stream stream) : base(stream) { } + + public override Task FlushAsync() + { + NonCancelableFlushAsyncInvoked = true; + return Task.CompletedTask; + } + } + + private sealed class WaitUntilCanceledWriteMemoryStream : MemoryStream + { + public override ValueTask WriteAsync(ReadOnlyMemory source, CancellationToken cancellationToken) + { + return new ValueTask(Task.Delay(-1, cancellationToken)); + } + } } } diff --git a/src/libraries/System.IO/tests/StringWriter/StringWriterTests.cs b/src/libraries/System.IO/tests/StringWriter/StringWriterTests.cs index 682e27b24bc900..5f85eb149d488b 100644 --- a/src/libraries/System.IO/tests/StringWriter/StringWriterTests.cs +++ b/src/libraries/System.IO/tests/StringWriter/StringWriterTests.cs @@ -242,7 +242,26 @@ public static async Task FlushAsyncWorks() sw.Write(sb.ToString()); - await sw.FlushAsync(); // I think this is a noop in this case + await sw.FlushAsync(); + + Assert.Equal(sb.ToString(), sw.GetStringBuilder().ToString()); + } + + [Fact] + public static async Task FlushAsyncWorks_Cancellation() + { + StringBuilder sb = getSb(); + StringWriter sw = new StringWriter(sb); + + sw.Write(sb.ToString()); + + var cts = new CancellationTokenSource(); + cts.Cancel(); + Task t = sw.FlushAsync(cts.Token); + Assert.Equal(TaskStatus.Canceled, t.Status); + Assert.Equal(cts.Token, (await Assert.ThrowsAnyAsync(() => t)).CancellationToken); + + await sw.FlushAsync(new CancellationTokenSource().Token); Assert.Equal(sb.ToString(), sw.GetStringBuilder().ToString()); } diff --git a/src/libraries/System.IO/tests/TextWriter/TextWriterTests.cs b/src/libraries/System.IO/tests/TextWriter/TextWriterTests.cs index bfab956af65d9c..5515b984b8266a 100644 --- a/src/libraries/System.IO/tests/TextWriter/TextWriterTests.cs +++ b/src/libraries/System.IO/tests/TextWriter/TextWriterTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Microsoft.DotNet.XUnitExtensions; using Xunit; @@ -667,6 +668,36 @@ public void DisposeAsync_ExceptionReturnedInTask() Assert.Same(e, vt.AsTask().Exception.InnerException); } + [Fact] + public async Task FlushAsync_Precanceled() + { + Assert.Equal(TaskStatus.RanToCompletion, TextWriter.Null.FlushAsync(new CancellationToken(true)).Status); + Assert.Equal(TaskStatus.Canceled, TextWriter.Synchronized(TextWriter.Null).FlushAsync(new CancellationToken(true)).Status); + + var ttw = new TrackingTextWriter(); + Assert.Equal(TaskStatus.RanToCompletion, ttw.FlushAsync(new CancellationTokenSource().Token).Status); + Assert.True(ttw.NonCancelableFlushAsyncCalled); + + var cts = new CancellationTokenSource(); + cts.Cancel(); + Task t = ttw.FlushAsync(cts.Token); + Assert.Equal(TaskStatus.Canceled, t.Status); + Assert.Equal(cts.Token, (await Assert.ThrowsAnyAsync(() => t)).CancellationToken); + } + + private sealed class TrackingTextWriter : TextWriter + { + public bool NonCancelableFlushAsyncCalled; + + public override Encoding Encoding => Encoding.UTF8; + + public override Task FlushAsync() + { + NonCancelableFlushAsyncCalled = true; + return Task.CompletedTask; + } + } + private sealed class InvokeActionOnDisposeTextWriter : TextWriter { public Action DisposeAction; diff --git a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs index 6e3b2d772609dd..029583b8f4b346 100644 --- a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs +++ b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs @@ -11,6 +11,17 @@ public static partial class Enumerable { public static IEnumerable AsEnumerable(this IEnumerable source) => source; + /// + /// Sets the 's to be + /// and returns the relevant portion of the list's backing array as a span. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span SetCountAndGetSpan(List list, int count) + { + CollectionsMarshal.SetCount(list, count); + return CollectionsMarshal.AsSpan(list); + } + /// Validates that source is not null and then tries to extract a span from the source. [MethodImpl(MethodImplOptions.AggressiveInlining)] // fast type checks that don't add a lot of overhead private static bool TryGetSpan(this IEnumerable source, out ReadOnlySpan span) diff --git a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs index c8861e176f03b0..e9cb982c2bc43c 100644 --- a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs @@ -20,12 +20,7 @@ public virtual TElement[] ToArray() } TElement[] array = new TElement[count]; - int[] map = SortedMap(buffer); - for (int i = 0; i < array.Length; i++) - { - array[i] = buffer._items[map[i]]; - } - + Fill(buffer, array); return array; } @@ -36,16 +31,21 @@ public virtual List ToList() List list = new List(count); if (count > 0) { - int[] map = SortedMap(buffer); - for (int i = 0; i != count; i++) - { - list.Add(buffer._items[map[i]]); - } + Fill(buffer, Enumerable.SetCountAndGetSpan(list, count)); } return list; } + private void Fill(Buffer buffer, Span destination) + { + int[] map = SortedMap(buffer); + for (int i = 0; i < destination.Length; i++) + { + destination[i] = buffer._items[map[i]]; + } + } + public int GetCount(bool onlyIfCheap) { if (_source is IIListProvider listProv) @@ -75,15 +75,9 @@ internal TElement[] ToArray(int minIdx, int maxIdx) return new TElement[] { GetEnumerableSorter().ElementAt(buffer._items, count, minIdx) }; } - int[] map = SortedMap(buffer, minIdx, maxIdx); TElement[] array = new TElement[maxIdx - minIdx + 1]; - int idx = 0; - while (minIdx <= maxIdx) - { - array[idx] = buffer._items[map[minIdx]]; - ++idx; - ++minIdx; - } + + Fill(minIdx, maxIdx, buffer, array); return array; } @@ -107,15 +101,21 @@ internal List ToList(int minIdx, int maxIdx) return new List(1) { GetEnumerableSorter().ElementAt(buffer._items, count, minIdx) }; } - int[] map = SortedMap(buffer, minIdx, maxIdx); List list = new List(maxIdx - minIdx + 1); + Fill(minIdx, maxIdx, buffer, Enumerable.SetCountAndGetSpan(list, maxIdx - minIdx + 1)); + return list; + } + + private void Fill(int minIdx, int maxIdx, Buffer buffer, Span destination) + { + int[] map = SortedMap(buffer, minIdx, maxIdx); + int idx = 0; while (minIdx <= maxIdx) { - list.Add(buffer._items[map[minIdx]]); + destination[idx] = buffer._items[map[minIdx]]; + ++idx; ++minIdx; } - - return list; } internal int GetCount(int minIdx, int maxIdx, bool onlyIfCheap) diff --git a/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs index 8555fa1582d298..92b1d68b612dcf 100644 --- a/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs @@ -254,11 +254,7 @@ public TSource[] ToArray() } TSource[] array = new TSource[count]; - for (int i = 0, curIdx = _minIndexInclusive; i < array.Length; ++i, ++curIdx) - { - array[i] = _source[curIdx]; - } - + Fill(_source, array, _minIndexInclusive); return array; } @@ -271,13 +267,16 @@ public List ToList() } List list = new List(count); - int end = _minIndexInclusive + count; - for (int i = _minIndexInclusive; i != end; ++i) + Fill(_source, SetCountAndGetSpan(list, count), _minIndexInclusive); + return list; + } + + private static void Fill(IList source, Span destination, int sourceIndex) + { + for (int i = 0; i < destination.Length; i++, sourceIndex++) { - list.Add(_source[i]); + destination[i] = source[sourceIndex]; } - - return list; } public int GetCount(bool onlyIfCheap) => Count; diff --git a/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs index 6704eef5dedc29..82c66eebd8c6b3 100644 --- a/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs @@ -17,25 +17,23 @@ public override IEnumerable Select(Func selector public int[] ToArray() { int[] array = new int[_end - _start]; - int cur = _start; - for (int i = 0; i < array.Length; ++i) - { - array[i] = cur; - ++cur; - } - + Fill(array, _start); return array; } public List ToList() { List list = new List(_end - _start); - for (int cur = _start; cur != _end; cur++) + Fill(SetCountAndGetSpan(list, _end - _start), _start); + return list; + } + + private static void Fill(Span destination, int value) + { + for (int i = 0; i < destination.Length; i++, value++) { - list.Add(cur); + destination[i] = value; } - - return list; } public int GetCount(bool onlyIfCheap) => unchecked(_end - _start); diff --git a/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs index 3840acd81340a5..971f70be1a5b44 100644 --- a/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs @@ -28,10 +28,7 @@ public TResult[] ToArray() public List ToList() { List list = new List(_count); - for (int i = 0; i != _count; ++i) - { - list.Add(_current); - } + SetCountAndGetSpan(list, _count).Fill(_current); return list; } diff --git a/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs index 76ee67b2dcbdb7..bfa8d83dbb9dcf 100644 --- a/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; using static System.Linq.Utilities; namespace System.Linq @@ -75,13 +75,11 @@ public TResult[] ToArray() { // See assert in constructor. // Since _source should never be empty, we don't check for 0/return Array.Empty. - Debug.Assert(_source.Length > 0); + TSource[] source = _source; + Debug.Assert(source.Length > 0); - var results = new TResult[_source.Length]; - for (int i = 0; i < results.Length; i++) - { - results[i] = _selector(_source[i]); - } + var results = new TResult[source.Length]; + Fill(source, results, _selector); return results; } @@ -89,15 +87,22 @@ public TResult[] ToArray() public List ToList() { TSource[] source = _source; + Debug.Assert(source.Length > 0); + var results = new List(source.Length); - for (int i = 0; i < source.Length; i++) - { - results.Add(_selector(source[i])); - } + Fill(source, SetCountAndGetSpan(results, source.Length), _selector); return results; } + private static void Fill(ReadOnlySpan source, Span destination, Func func) + { + for (int i = 0; i < destination.Length; i++) + { + destination[i] = func(source[i]); + } + } + public int GetCount(bool onlyIfCheap) { // In case someone uses Count() to force evaluation of @@ -202,11 +207,7 @@ public override IEnumerable Select(Func s public TResult[] ToArray() { var results = new TResult[_end - _start]; - int srcIndex = _start; - for (int i = 0; i < results.Length; i++) - { - results[i] = _selector(srcIndex++); - } + Fill(results, _start, _selector); return results; } @@ -214,14 +215,19 @@ public TResult[] ToArray() public List ToList() { var results = new List(_end - _start); - for (int i = _start; i != _end; i++) - { - results.Add(_selector(i)); - } + Fill(SetCountAndGetSpan(results, _end - _start), _start, _selector); return results; } + private static void Fill(Span results, int start, Func func) + { + for (int i = 0; i < results.Length; i++, start++) + { + results[i] = func(start); + } + } + public int GetCount(bool onlyIfCheap) { // In case someone uses Count() to force evaluation of the selector, @@ -292,33 +298,36 @@ private sealed partial class SelectListIterator : IPartition source = CollectionsMarshal.AsSpan(_source); + if (source.Length == 0) { return Array.Empty(); } - var results = new TResult[count]; - for (int i = 0; i < results.Length; i++) - { - results[i] = _selector(_source[i]); - } + var results = new TResult[source.Length]; + Fill(source, results, _selector); return results; } public List ToList() { - int count = _source.Count; - var results = new List(count); - for (int i = 0; i < count; i++) - { - results.Add(_selector(_source[i])); - } + ReadOnlySpan source = CollectionsMarshal.AsSpan(_source); + + var results = new List(source.Length); + Fill(source, SetCountAndGetSpan(results, source.Length), _selector); return results; } + private static void Fill(ReadOnlySpan source, Span destination, Func func) + { + for (int i = 0; i < destination.Length; i++) + { + destination[i] = func(source[i]); + } + } + public int GetCount(bool onlyIfCheap) { // In case someone uses Count() to force evaluation of @@ -398,26 +407,30 @@ public TResult[] ToArray() } var results = new TResult[count]; - for (int i = 0; i < results.Length; i++) - { - results[i] = _selector(_source[i]); - } + Fill(_source, results, _selector); return results; } public List ToList() { + IList source = _source; int count = _source.Count; + var results = new List(count); - for (int i = 0; i < count; i++) - { - results.Add(_selector(_source[i])); - } + Fill(source, SetCountAndGetSpan(results, count), _selector); return results; } + private static void Fill(IList source, Span results, Func func) + { + for (int i = 0; i < results.Length; i++) + { + results[i] = func(source[i]); + } + } + public int GetCount(bool onlyIfCheap) { // In case someone uses Count() to force evaluation of @@ -789,10 +802,7 @@ public TResult[] ToArray() } TResult[] array = new TResult[count]; - for (int i = 0, curIdx = _minIndexInclusive; i < array.Length; ++i, ++curIdx) - { - array[i] = _selector(_source[curIdx]); - } + Fill(_source, array, _selector, _minIndexInclusive); return array; } @@ -806,15 +816,19 @@ public List ToList() } List list = new List(count); - int end = _minIndexInclusive + count; - for (int i = _minIndexInclusive; i != end; ++i) - { - list.Add(_selector(_source[i])); - } + Fill(_source, SetCountAndGetSpan(list, count), _selector, _minIndexInclusive); return list; } + private static void Fill(IList source, Span destination, Func func, int sourceIndex) + { + for (int i = 0; i < destination.Length; i++, sourceIndex++) + { + destination[i] = func(source[sourceIndex]); + } + } + public int GetCount(bool onlyIfCheap) { // In case someone uses Count() to force evaluation of diff --git a/src/libraries/System.Linq/src/System/Linq/Select.cs b/src/libraries/System.Linq/src/System/Linq/Select.cs index 791363496f68b1..9d3dcc45b05f3b 100644 --- a/src/libraries/System.Linq/src/System/Linq/Select.cs +++ b/src/libraries/System.Linq/src/System/Linq/Select.cs @@ -178,15 +178,17 @@ public SelectArrayIterator(TSource[] source, Func selector) public override bool MoveNext() { - if (_state < 1 | _state == _source.Length + 1) + TSource[] source = _source; + int index = _state - 1; + if ((uint)index < (uint)source.Length) { - Dispose(); - return false; + _state++; + _current = _selector(source[index]); + return true; } - int index = _state++ - 1; - _current = _selector(_source[index]); - return true; + Dispose(); + return false; } public override IEnumerable Select(Func selector) => diff --git a/src/libraries/System.Linq/tests/ToArrayTests.cs b/src/libraries/System.Linq/tests/ToArrayTests.cs index b4877785112a74..67f8c385f3e39a 100644 --- a/src/libraries/System.Linq/tests/ToArrayTests.cs +++ b/src/libraries/System.Linq/tests/ToArrayTests.cs @@ -358,6 +358,7 @@ private enum Enum1 } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/85146", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public void ToArray_Cast() { Enum0[] source = { Enum0.First, Enum0.Second, Enum0.Third }; diff --git a/src/libraries/System.Memory/ref/System.Memory.cs b/src/libraries/System.Memory/ref/System.Memory.cs index 4c1f79a41ee9d5..e36ecb74617760 100644 --- a/src/libraries/System.Memory/ref/System.Memory.cs +++ b/src/libraries/System.Memory/ref/System.Memory.cs @@ -249,23 +249,23 @@ public static void CopyTo(this T[]? source, System.Span destination) { } public static System.Text.SpanRuneEnumerator EnumerateRunes(this System.Span span) { throw null; } public static bool Equals(this System.ReadOnlySpan span, System.ReadOnlySpan other, System.StringComparison comparisonType) { throw null; } public static int IndexOf(this System.ReadOnlySpan span, System.ReadOnlySpan value, System.StringComparison comparisonType) { throw null; } - public static int IndexOfAny(this System.ReadOnlySpan span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int IndexOfAny(this System.ReadOnlySpan span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int IndexOfAny(this System.ReadOnlySpan span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int IndexOfAny(this System.ReadOnlySpan span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int IndexOfAny(this System.ReadOnlySpan span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } - public static int IndexOfAny(this System.Span span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int IndexOfAny(this System.Span span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int IndexOfAny(this System.Span span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int IndexOfAny(this System.Span span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int IndexOfAny(this System.Span span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.Span span, T value) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.Span span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.Span span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } - public static int IndexOfAnyExcept(this System.Span span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int IndexOfAnyExcept(this System.Span span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.Span span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.ReadOnlySpan span, T value) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.ReadOnlySpan span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.ReadOnlySpan span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } - public static int IndexOfAnyExcept(this System.ReadOnlySpan span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int IndexOfAnyExcept(this System.ReadOnlySpan span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExcept(this System.ReadOnlySpan span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int IndexOfAnyExceptInRange(this System.ReadOnlySpan span, T lowInclusive, T highInclusive) where T : System.IComparable { throw null; } public static int IndexOfAnyExceptInRange(this System.Span span, T lowInclusive, T highInclusive) where T : System.IComparable { throw null; } @@ -277,23 +277,23 @@ public static void CopyTo(this T[]? source, System.Span destination) { } public static int IndexOfAnyInRange(this System.Span span, T lowInclusive, T highInclusive) where T : System.IComparable { throw null; } public static bool IsWhiteSpace(this System.ReadOnlySpan span) { throw null; } public static int LastIndexOf(this System.ReadOnlySpan span, System.ReadOnlySpan value, System.StringComparison comparisonType) { throw null; } - public static int LastIndexOfAny(this System.ReadOnlySpan span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int LastIndexOfAny(this System.ReadOnlySpan span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAny(this System.ReadOnlySpan span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAny(this System.ReadOnlySpan span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int LastIndexOfAny(this System.ReadOnlySpan span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } - public static int LastIndexOfAny(this System.Span span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int LastIndexOfAny(this System.Span span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAny(this System.Span span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAny(this System.Span span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int LastIndexOfAny(this System.Span span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.Span span, T value) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.Span span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.Span span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } - public static int LastIndexOfAnyExcept(this System.Span span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int LastIndexOfAnyExcept(this System.Span span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.Span span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.ReadOnlySpan span, T value) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.ReadOnlySpan span, T value0, T value1) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.ReadOnlySpan span, T value0, T value1, T value2) where T : System.IEquatable? { throw null; } - public static int LastIndexOfAnyExcept(this System.ReadOnlySpan span, System.Buffers.IndexOfAnyValues values) where T : System.IEquatable? { throw null; } + public static int LastIndexOfAnyExcept(this System.ReadOnlySpan span, System.Buffers.SearchValues values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExcept(this System.ReadOnlySpan span, System.ReadOnlySpan values) where T : System.IEquatable? { throw null; } public static int LastIndexOfAnyExceptInRange(this System.ReadOnlySpan span, T lowInclusive, T highInclusive) where T : System.IComparable { throw null; } public static int LastIndexOfAnyExceptInRange(this System.Span span, T lowInclusive, T highInclusive) where T : System.IComparable { throw null; } diff --git a/src/libraries/System.Memory/tests/MemoryMarshal/GetReference.cs b/src/libraries/System.Memory/tests/MemoryMarshal/GetReference.cs index f65ae5ba475504..d0e83a069d0b44 100644 --- a/src/libraries/System.Memory/tests/MemoryMarshal/GetReference.cs +++ b/src/libraries/System.Memory/tests/MemoryMarshal/GetReference.cs @@ -100,5 +100,17 @@ public static void ReadOnlySpanGetReferenceEmpty() Assert.True(Unsafe.AreSame(ref Unsafe.AsRef(null), ref pinnableReference)); } } + + [Fact] + public static void ReadOnlySpanGetReferenceAndReadInteger() + { + Assert.Equal(6619240, + Unsafe.As(ref Unsafe.Add(ref Unsafe.As( + ref MemoryMarshal.GetReference("hello world 1".AsSpan())), 0))); + + Assert.Equal(7998511687277765888, + Unsafe.As(ref Unsafe.Add(ref Unsafe.As( + ref MemoryMarshal.GetReference("hello world 2".AsSpan())), 1))); + } } } diff --git a/src/libraries/System.Memory/tests/Span/IndexOfAny.byte.cs b/src/libraries/System.Memory/tests/Span/IndexOfAny.byte.cs index cc2e92c8a62b40..40f2de438d88c1 100644 --- a/src/libraries/System.Memory/tests/Span/IndexOfAny.byte.cs +++ b/src/libraries/System.Memory/tests/Span/IndexOfAny.byte.cs @@ -533,28 +533,28 @@ public static void MakeSureNoChecksGoOutOfRangeMany_Byte() private static int IndexOf(Span span, byte value) { int index = span.IndexOf(value); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(stackalloc byte[] { value }))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(stackalloc byte[] { value }))); return index; } private static int IndexOfAny(Span span, byte value0, byte value1) { int index = span.IndexOfAny(value0, value1); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(stackalloc byte[] { value0, value1 }))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(stackalloc byte[] { value0, value1 }))); return index; } private static int IndexOfAny(Span span, byte value0, byte value1, byte value2) { int index = span.IndexOfAny(value0, value1, value2); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(stackalloc byte[] { value0, value1, value2 }))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(stackalloc byte[] { value0, value1, value2 }))); return index; } private static int IndexOfAny(Span span, ReadOnlySpan values) { int index = span.IndexOfAny(values); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(values))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(values))); return index; } } diff --git a/src/libraries/System.Memory/tests/Span/IndexOfAny.char.cs b/src/libraries/System.Memory/tests/Span/IndexOfAny.char.cs index 47ec7bebaa4c93..bf51860f51bf18 100644 --- a/src/libraries/System.Memory/tests/Span/IndexOfAny.char.cs +++ b/src/libraries/System.Memory/tests/Span/IndexOfAny.char.cs @@ -776,28 +776,28 @@ public static void MakeSureNoChecksGoOutOfRangeMany_Char() private static int IndexOf(Span span, char value) { int index = span.IndexOf(value); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(stackalloc char[] { value }))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(stackalloc char[] { value }))); return index; } private static int IndexOfAny(Span span, char value0, char value1) { int index = span.IndexOfAny(value0, value1); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(stackalloc char[] { value0, value1 }))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(stackalloc char[] { value0, value1 }))); return index; } private static int IndexOfAny(Span span, char value0, char value1, char value2) { int index = span.IndexOfAny(value0, value1, value2); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(stackalloc char[] { value0, value1, value2 }))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(stackalloc char[] { value0, value1, value2 }))); return index; } private static int IndexOfAny(Span span, ReadOnlySpan values) { int index = span.IndexOfAny(values); - Assert.Equal(index, span.IndexOfAny(IndexOfAnyValues.Create(values))); + Assert.Equal(index, span.IndexOfAny(SearchValues.Create(values))); return index; } } diff --git a/src/libraries/System.Memory/tests/Span/IndexOfAnyExcept.T.cs b/src/libraries/System.Memory/tests/Span/IndexOfAnyExcept.T.cs index 6d9d6fb3795e37..69ef7ec1334ea3 100644 --- a/src/libraries/System.Memory/tests/Span/IndexOfAnyExcept.T.cs +++ b/src/libraries/System.Memory/tests/Span/IndexOfAnyExcept.T.cs @@ -183,8 +183,8 @@ private static int IndexOfAnyExcept(Span span, T value) Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((ReadOnlySpan)span, value)); Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((Span)span, new[] { value })); Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((ReadOnlySpan)span, new[] { value })); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value })))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value })))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value })))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value })))); return result; } private static int IndexOfAnyExcept(Span span, T value0, T value1) @@ -193,8 +193,8 @@ private static int IndexOfAnyExcept(Span span, T value0, T value1) Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((ReadOnlySpan)span, value0, value1)); Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((Span)span, new[] { value0, value1 })); Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((ReadOnlySpan)span, new[] { value0, value1 })); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1 })))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1 })))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1 })))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1 })))); return result; } private static int IndexOfAnyExcept(Span span, T value0, T value1, T value2) @@ -203,16 +203,16 @@ private static int IndexOfAnyExcept(Span span, T value0, T value1, T value2) Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((ReadOnlySpan)span, value0, value1, value2)); Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((Span)span, new[] { value0, value1, value2 })); Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((ReadOnlySpan)span, new[] { value0, value1, value2 })); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1, value2 })))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1, value2 })))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1, value2 })))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1, value2 })))); return result; } private static int IndexOfAnyExcept(Span span, params T[] values) { int result = MemoryExtensions.IndexOfAnyExcept(span, values); Assert.Equal(result, MemoryExtensions.IndexOfAnyExcept((ReadOnlySpan)span, values)); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(values)))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(IndexOfAnyValues.Create(Cast(values)))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(values)))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).IndexOfAnyExcept(SearchValues.Create(Cast(values)))); return result; } private static int LastIndexOfAnyExcept(Span span, T value) @@ -221,8 +221,8 @@ private static int LastIndexOfAnyExcept(Span span, T value) Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((ReadOnlySpan)span, value)); Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((Span)span, new[] { value })); Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((ReadOnlySpan)span, new[] { value })); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value })))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value })))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value })))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value })))); return result; } private static int LastIndexOfAnyExcept(Span span, T value0, T value1) @@ -231,8 +231,8 @@ private static int LastIndexOfAnyExcept(Span span, T value0, T value1) Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((ReadOnlySpan)span, value0, value1)); Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((Span)span, new[] { value0, value1 })); Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((ReadOnlySpan)span, new[] { value0, value1 })); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1 })))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1 })))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1 })))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1 })))); return result; } private static int LastIndexOfAnyExcept(Span span, T value0, T value1, T value2) @@ -241,16 +241,16 @@ private static int LastIndexOfAnyExcept(Span span, T value0, T value1, T valu Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((ReadOnlySpan)span, value0, value1, value2)); Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((Span)span, new[] { value0, value1, value2 })); Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((ReadOnlySpan)span, new[] { value0, value1, value2 })); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1, value2 })))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(new T[] { value0, value1, value2 })))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1, value2 })))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(new T[] { value0, value1, value2 })))); return result; } private static int LastIndexOfAnyExcept(Span span, params T[] values) { int result = MemoryExtensions.LastIndexOfAnyExcept(span, values); Assert.Equal(result, MemoryExtensions.LastIndexOfAnyExcept((ReadOnlySpan)span, values)); - if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(values)))); - if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(IndexOfAnyValues.Create(Cast(values)))); + if (typeof(T) == typeof(byte)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(values)))); + if (typeof(T) == typeof(char)) Assert.Equal(result, Cast(span).LastIndexOfAnyExcept(SearchValues.Create(Cast(values)))); return result; } diff --git a/src/libraries/System.Memory/tests/Span/LastIndexOfAny.byte.cs b/src/libraries/System.Memory/tests/Span/LastIndexOfAny.byte.cs index 7bcb48da70d0e7..1a29a790ab7761 100644 --- a/src/libraries/System.Memory/tests/Span/LastIndexOfAny.byte.cs +++ b/src/libraries/System.Memory/tests/Span/LastIndexOfAny.byte.cs @@ -521,28 +521,28 @@ public static void MakeSureNoChecksGoOutOfRangeLastIndexOfAny_Byte_ManyByte() private static int LastIndexOf(Span span, byte value) { int index = span.LastIndexOf(value); - Assert.Equal(index, span.LastIndexOfAny(IndexOfAnyValues.Create(stackalloc byte[] { value }))); + Assert.Equal(index, span.LastIndexOfAny(SearchValues.Create(stackalloc byte[] { value }))); return index; } private static int LastIndexOfAny(Span span, byte value0, byte value1) { int index = span.LastIndexOfAny(value0, value1); - Assert.Equal(index, span.LastIndexOfAny(IndexOfAnyValues.Create(stackalloc byte[] { value0, value1 }))); + Assert.Equal(index, span.LastIndexOfAny(SearchValues.Create(stackalloc byte[] { value0, value1 }))); return index; } private static int LastIndexOfAny(Span span, byte value0, byte value1, byte value2) { int index = span.LastIndexOfAny(value0, value1, value2); - Assert.Equal(index, span.LastIndexOfAny(IndexOfAnyValues.Create(stackalloc byte[] { value0, value1, value2 }))); + Assert.Equal(index, span.LastIndexOfAny(SearchValues.Create(stackalloc byte[] { value0, value1, value2 }))); return index; } private static int LastIndexOfAny(Span span, ReadOnlySpan values) { int index = span.LastIndexOfAny(values); - Assert.Equal(index, span.LastIndexOfAny(IndexOfAnyValues.Create(values))); + Assert.Equal(index, span.LastIndexOfAny(SearchValues.Create(values))); return index; } } diff --git a/src/libraries/System.Memory/tests/Span/IndexOfAnyValues.cs b/src/libraries/System.Memory/tests/Span/SearchValues.cs similarity index 83% rename from src/libraries/System.Memory/tests/Span/IndexOfAnyValues.cs rename to src/libraries/System.Memory/tests/Span/SearchValues.cs index 44dda7358c705e..b6ab088f23c215 100644 --- a/src/libraries/System.Memory/tests/Span/IndexOfAnyValues.cs +++ b/src/libraries/System.Memory/tests/Span/SearchValues.cs @@ -15,11 +15,11 @@ namespace System.SpanTests { public static partial class SpanTests { - private static readonly Func, byte[]> s_getValuesByteMethod = - typeof(IndexOfAnyValues).GetMethod("GetValues", BindingFlags.NonPublic | BindingFlags.Instance).CreateDelegate, byte[]>>(); + private static readonly Func, byte[]> s_getValuesByteMethod = + typeof(SearchValues).GetMethod("GetValues", BindingFlags.NonPublic | BindingFlags.Instance).CreateDelegate, byte[]>>(); - private static readonly Func, char[]> s_getValuesCharMethod = - typeof(IndexOfAnyValues).GetMethod("GetValues", BindingFlags.NonPublic | BindingFlags.Instance).CreateDelegate, char[]>>(); + private static readonly Func, char[]> s_getValuesCharMethod = + typeof(SearchValues).GetMethod("GetValues", BindingFlags.NonPublic | BindingFlags.Instance).CreateDelegate, char[]>>(); public static IEnumerable Values_MemberData() { @@ -76,7 +76,7 @@ public static void AsciiNeedle_ProperlyHandlesEdgeCases_Char(bool needleContains { // There is some special handling we have to do for ASCII needles to properly filter out non-ASCII results ReadOnlySpan needleValues = needleContainsZero ? "AEIOU\0" : "AEIOU!"; - IndexOfAnyValues needle = IndexOfAnyValues.Create(needleValues); + SearchValues needle = SearchValues.Create(needleValues); ReadOnlySpan repeatingHaystack = "AaAaAaAaAaAa"; Assert.Equal(0, repeatingHaystack.IndexOfAny(needle)); @@ -142,7 +142,7 @@ public static void AsciiNeedle_ProperlyHandlesEdgeCases_Byte(bool needleContains { // There is some special handling we have to do for ASCII needles to properly filter out non-ASCII results ReadOnlySpan needleValues = needleContainsZero ? "AEIOU\0"u8 : "AEIOU!"u8; - IndexOfAnyValues needle = IndexOfAnyValues.Create(needleValues); + SearchValues needle = SearchValues.Create(needleValues); ReadOnlySpan repeatingHaystack = "AaAaAaAaAaAa"u8; Assert.Equal(0, repeatingHaystack.IndexOfAny(needle)); @@ -181,12 +181,12 @@ public static void AsciiNeedle_ProperlyHandlesEdgeCases_Byte(bool needleContains [Theory] [MemberData(nameof(Values_MemberData))] - public static void IndexOfAnyValues_Contains(string needle, byte[] byteNeedle) + public static void SearchValues_Contains(string needle, byte[] byteNeedle) { - Test(needle, IndexOfAnyValues.Create(needle)); - Test(byteNeedle, IndexOfAnyValues.Create(byteNeedle)); + Test(needle, SearchValues.Create(needle)); + Test(byteNeedle, SearchValues.Create(byteNeedle)); - static void Test(ReadOnlySpan needle, IndexOfAnyValues values) where T : struct, INumber, IMinMaxValue + static void Test(ReadOnlySpan needle, SearchValues values) where T : struct, INumber, IMinMaxValue { for (int i = int.CreateChecked(T.MaxValue); i >= 0; i--) { @@ -199,10 +199,10 @@ static void Test(ReadOnlySpan needle, IndexOfAnyValues values) where T [Theory] [MemberData(nameof(Values_MemberData))] [ActiveIssue("https://github.com/dotnet/runtime/issues/80875", TestPlatforms.iOS | TestPlatforms.tvOS)] - public static void IndexOfAnyValues_GetValues(string needle, byte[] byteNeedle) + public static void SearchValues_GetValues(string needle, byte[] byteNeedle) { - char[] charValuesActual = s_getValuesCharMethod(IndexOfAnyValues.Create(needle)); - byte[] byteValuesActual = s_getValuesByteMethod(IndexOfAnyValues.Create(byteNeedle)); + char[] charValuesActual = s_getValuesCharMethod(SearchValues.Create(needle)); + byte[] byteValuesActual = s_getValuesByteMethod(SearchValues.Create(byteNeedle)); Assert.Equal(new HashSet(needle).Order().ToArray(), new HashSet(charValuesActual).Order().ToArray()); Assert.Equal(new HashSet(byteNeedle).Order().ToArray(), new HashSet(byteValuesActual).Order().ToArray()); @@ -212,10 +212,10 @@ public static void IndexOfAnyValues_GetValues(string needle, byte[] byteNeedle) [OuterLoop("Takes about a second to execute")] public static void TestIndexOfAny_RandomInputs_Byte() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: IndexOfAnyReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.IndexOfAny(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.IndexOfAny(values)); + searchValues: (searchSpace, values) => searchSpace.IndexOfAny(values)); static int IndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -235,10 +235,10 @@ static int IndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan< [OuterLoop("Takes about a second to execute")] public static void TestIndexOfAny_RandomInputs_Char() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: IndexOfAnyReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.IndexOfAny(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.IndexOfAny(values)); + searchValues: (searchSpace, values) => searchSpace.IndexOfAny(values)); static int IndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -258,10 +258,10 @@ static int IndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan< [OuterLoop("Takes about a second to execute")] public static void TestLastIndexOfAny_RandomInputs_Byte() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: LastIndexOfAnyReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.LastIndexOfAny(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.LastIndexOfAny(values)); + searchValues: (searchSpace, values) => searchSpace.LastIndexOfAny(values)); static int LastIndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -281,10 +281,10 @@ static int LastIndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlyS [OuterLoop("Takes about a second to execute")] public static void TestLastIndexOfAny_RandomInputs_Char() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: LastIndexOfAnyReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.LastIndexOfAny(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.LastIndexOfAny(values)); + searchValues: (searchSpace, values) => searchSpace.LastIndexOfAny(values)); static int LastIndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -304,10 +304,10 @@ static int LastIndexOfAnyReferenceImpl(ReadOnlySpan searchSpace, ReadOnlyS [OuterLoop("Takes about a second to execute")] public static void TestIndexOfAnyExcept_RandomInputs_Byte() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: IndexOfAnyExceptReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.IndexOfAnyExcept(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.IndexOfAnyExcept(values)); + searchValues: (searchSpace, values) => searchSpace.IndexOfAnyExcept(values)); static int IndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -327,10 +327,10 @@ static int IndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, ReadOnl [OuterLoop("Takes about a second to execute")] public static void TestIndexOfAnyExcept_RandomInputs_Char() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: IndexOfAnyExceptReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.IndexOfAnyExcept(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.IndexOfAnyExcept(values)); + searchValues: (searchSpace, values) => searchSpace.IndexOfAnyExcept(values)); static int IndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -350,10 +350,10 @@ static int IndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, ReadOnl [OuterLoop("Takes about a second to execute")] public static void TestLastIndexOfAnyExcept_RandomInputs_Byte() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: LastIndexOfAnyExceptReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.LastIndexOfAnyExcept(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.LastIndexOfAnyExcept(values)); + searchValues: (searchSpace, values) => searchSpace.LastIndexOfAnyExcept(values)); static int LastIndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -373,10 +373,10 @@ static int LastIndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, Rea [OuterLoop("Takes about a second to execute")] public static void TestLastIndexOfAnyExcept_RandomInputs_Char() { - IndexOfAnyValuesTestHelper.TestRandomInputs( + SearchValuesTestHelper.TestRandomInputs( expected: LastIndexOfAnyExceptReferenceImpl, indexOfAny: (searchSpace, values) => searchSpace.LastIndexOfAnyExcept(values), - indexOfAnyValues: (searchSpace, values) => searchSpace.LastIndexOfAnyExcept(values)); + searchValues: (searchSpace, values) => searchSpace.LastIndexOfAnyExcept(values)); static int LastIndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, ReadOnlySpan values) { @@ -392,7 +392,7 @@ static int LastIndexOfAnyExceptReferenceImpl(ReadOnlySpan searchSpace, Rea } } - private static class IndexOfAnyValuesTestHelper + private static class SearchValuesTestHelper { private const int MaxNeedleLength = 10; private const int MaxHaystackLength = 100; @@ -403,7 +403,7 @@ private static class IndexOfAnyValuesTestHelper private static readonly byte[] s_randomAsciiBytes; private static readonly byte[] s_randomBytes; - static IndexOfAnyValuesTestHelper() + static SearchValuesTestHelper() { s_randomAsciiChars = new char[100 * 1024]; s_randomLatin1Chars = new char[100 * 1024]; @@ -431,59 +431,59 @@ static IndexOfAnyValuesTestHelper() public delegate int IndexOfAnySearchDelegate(ReadOnlySpan searchSpace, ReadOnlySpan values) where T : IEquatable?; - public delegate int IndexOfAnyValuesSearchDelegate(ReadOnlySpan searchSpace, IndexOfAnyValues values) where T : IEquatable?; + public delegate int SearchValuesSearchDelegate(ReadOnlySpan searchSpace, SearchValues values) where T : IEquatable?; - public static void TestRandomInputs(IndexOfAnySearchDelegate expected, IndexOfAnySearchDelegate indexOfAny, IndexOfAnyValuesSearchDelegate indexOfAnyValues) + public static void TestRandomInputs(IndexOfAnySearchDelegate expected, IndexOfAnySearchDelegate indexOfAny, SearchValuesSearchDelegate searchValues) { var rng = new Random(42); for (int iterations = 0; iterations < 1_000_000; iterations++) { // There are more interesting corner cases with ASCII needles, test those more. - Test(rng, s_randomBytes, s_randomAsciiBytes, expected, indexOfAny, indexOfAnyValues); + Test(rng, s_randomBytes, s_randomAsciiBytes, expected, indexOfAny, searchValues); - Test(rng, s_randomBytes, s_randomBytes, expected, indexOfAny, indexOfAnyValues); + Test(rng, s_randomBytes, s_randomBytes, expected, indexOfAny, searchValues); } } - public static void TestRandomInputs(IndexOfAnySearchDelegate expected, IndexOfAnySearchDelegate indexOfAny, IndexOfAnyValuesSearchDelegate indexOfAnyValues) + public static void TestRandomInputs(IndexOfAnySearchDelegate expected, IndexOfAnySearchDelegate indexOfAny, SearchValuesSearchDelegate searchValues) { var rng = new Random(42); for (int iterations = 0; iterations < 1_000_000; iterations++) { // There are more interesting corner cases with ASCII needles, test those more. - Test(rng, s_randomChars, s_randomAsciiChars, expected, indexOfAny, indexOfAnyValues); + Test(rng, s_randomChars, s_randomAsciiChars, expected, indexOfAny, searchValues); - Test(rng, s_randomChars, s_randomLatin1Chars, expected, indexOfAny, indexOfAnyValues); + Test(rng, s_randomChars, s_randomLatin1Chars, expected, indexOfAny, searchValues); - Test(rng, s_randomChars, s_randomChars, expected, indexOfAny, indexOfAnyValues); + Test(rng, s_randomChars, s_randomChars, expected, indexOfAny, searchValues); } } private static void Test(Random rng, ReadOnlySpan haystackRandom, ReadOnlySpan needleRandom, - IndexOfAnySearchDelegate expected, IndexOfAnySearchDelegate indexOfAny, IndexOfAnyValuesSearchDelegate indexOfAnyValues) + IndexOfAnySearchDelegate expected, IndexOfAnySearchDelegate indexOfAny, SearchValuesSearchDelegate searchValues) where T : struct, INumber, IMinMaxValue { ReadOnlySpan haystack = GetRandomSlice(rng, haystackRandom, MaxHaystackLength); ReadOnlySpan needle = GetRandomSlice(rng, needleRandom, MaxNeedleLength); - IndexOfAnyValues indexOfAnyValuesInstance = (IndexOfAnyValues)(object)(typeof(T) == typeof(byte) - ? IndexOfAnyValues.Create(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref MemoryMarshal.GetReference(needle)), needle.Length)) - : IndexOfAnyValues.Create(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref MemoryMarshal.GetReference(needle)), needle.Length))); + SearchValues searchValuesInstance = (SearchValues)(object)(typeof(T) == typeof(byte) + ? SearchValues.Create(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref MemoryMarshal.GetReference(needle)), needle.Length)) + : SearchValues.Create(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref MemoryMarshal.GetReference(needle)), needle.Length))); int expectedIndex = expected(haystack, needle); int indexOfAnyIndex = indexOfAny(haystack, needle); - int indexOfAnyValuesIndex = indexOfAnyValues(haystack, indexOfAnyValuesInstance); + int searchValuesIndex = searchValues(haystack, searchValuesInstance); if (expectedIndex != indexOfAnyIndex) { AssertionFailed(haystack, needle, expectedIndex, indexOfAnyIndex, nameof(indexOfAny)); } - if (expectedIndex != indexOfAnyValuesIndex) + if (expectedIndex != searchValuesIndex) { - AssertionFailed(haystack, needle, expectedIndex, indexOfAnyValuesIndex, nameof(indexOfAnyValues)); + AssertionFailed(haystack, needle, expectedIndex, searchValuesIndex, nameof(searchValues)); } } diff --git a/src/libraries/System.Memory/tests/System.Memory.Tests.csproj b/src/libraries/System.Memory/tests/System.Memory.Tests.csproj index e7748a30e24886..ff1fe297af74e0 100644 --- a/src/libraries/System.Memory/tests/System.Memory.Tests.csproj +++ b/src/libraries/System.Memory/tests/System.Memory.Tests.csproj @@ -87,7 +87,6 @@ - @@ -103,6 +102,7 @@ + diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index dd43a9f0dae10b..d16acb0e77196b 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -27,7 +27,6 @@ - diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayHelpers.cs b/src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayHelpers.cs deleted file mode 100644 index d6299477cf8d71..00000000000000 --- a/src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayHelpers.cs +++ /dev/null @@ -1,62 +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.Diagnostics; - -namespace System -{ - internal static class ByteArrayHelpers - { - // TODO: https://github.com/dotnet/runtime/issues/28230 - // Use Ascii.Equals* when it's available. - - internal static bool EqualsOrdinalAsciiIgnoreCase(string left, ReadOnlySpan right) - { - Debug.Assert(left != null, "Expected non-null string"); - - if (left.Length != right.Length) - { - return false; - } - - for (int i = 0; i < left.Length; i++) - { - uint charA = left[i]; - uint charB = right[i]; - - // We're only interested in ASCII characters here. - if ((charA - 'a') <= ('z' - 'a')) - charA -= ('a' - 'A'); - if ((charB - 'a') <= ('z' - 'a')) - charB -= ('a' - 'A'); - - if (charA != charB) - { - return false; - } - } - - return true; - } - - internal static bool EqualsOrdinalAscii(string left, ReadOnlySpan right) - { - Debug.Assert(left != null, "Expected non-null string"); - - if (left.Length != right.Length) - { - return false; - } - - for (int i = 0; i < left.Length; i++) - { - if (left[i] != right[i]) - { - return false; - } - } - - return true; - } - } -} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs index d04c9f4877e48e..6bb9a80a62e8ae 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs @@ -143,7 +143,7 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco { for (int i = 0; i < knownValues.Length; i++) { - if (ByteArrayHelpers.EqualsOrdinalAscii(knownValues[i], headerValue)) + if (Ascii.Equals(headerValue, knownValues[i])) { return knownValues[i]; } @@ -251,7 +251,7 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco Debug.Assert(candidate is null || candidate.Length == contentTypeValue.Length); - return candidate != null && ByteArrayHelpers.EqualsOrdinalAscii(candidate, contentTypeValue) ? + return candidate != null && Ascii.Equals(contentTypeValue, candidate) ? candidate : null; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs index f990f447b2ab11..20730990ce9a42 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs @@ -23,8 +23,8 @@ internal static class HeaderUtilities // attr-char = ALPHA / DIGIT / "!" / "#" / "$" / "&" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" // ; token except ( "*" / "'" / "%" ) - private static readonly IndexOfAnyValues s_rfc5987AttrBytes = - IndexOfAnyValues.Create("!#$&+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"u8); + private static readonly SearchValues s_rfc5987AttrBytes = + SearchValues.Create("!#$&+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"u8); internal static void SetQuality(UnvalidatedObjectCollection parameters, double? value) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs index 389174a5258afb..ac819868f77683 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs @@ -4,6 +4,7 @@ using System.Net.Http.HPack; using System.Net.Http.QPack; using System.Runtime.InteropServices; +using System.Text; namespace System.Net.Http.Headers { @@ -427,7 +428,7 @@ public BytePtrAccessor(byte* p, int length) fixed (byte* p = &MemoryMarshal.GetReference(name)) { KnownHeader? candidate = GetCandidate(new BytePtrAccessor(p, name.Length)); - if (candidate != null && ByteArrayHelpers.EqualsOrdinalAsciiIgnoreCase(candidate.Name, name)) + if (candidate != null && Ascii.EqualsIgnoreCase(name, candidate.Name)) { return candidate; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs index ab0a01afa78b32..83fd0b2dc0e872 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs @@ -11,14 +11,14 @@ internal static class HttpRuleParser { // token = 1* // CTL = - private static readonly IndexOfAnyValues s_tokenChars = - IndexOfAnyValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"); + private static readonly SearchValues s_tokenChars = + SearchValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"); - private static readonly IndexOfAnyValues s_tokenBytes = - IndexOfAnyValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"u8); + private static readonly SearchValues s_tokenBytes = + SearchValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"u8); - private static readonly IndexOfAnyValues s_hostDelimiterChars = - IndexOfAnyValues.Create("/ \t\r,"); + private static readonly SearchValues s_hostDelimiterChars = + SearchValues.Create("/ \t\r,"); private const int MaxNestedCount = 5; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs index 156abccc748e73..3f249987f08a96 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs @@ -23,8 +23,8 @@ public class MultipartContent : HttpContent, IEnumerable private const int ColonSpaceLength = 2; private const int CommaSpaceLength = 2; - private static readonly IndexOfAnyValues s_allowedBoundaryChars = - IndexOfAnyValues.Create(" '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"); + private static readonly SearchValues s_allowedBoundaryChars = + SearchValues.Create(" '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"); private readonly List _nestedContent; private readonly string _boundary; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs index ba3b895b65e239..4297f86c85a255 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs @@ -1079,7 +1079,7 @@ private static void ParseStatusLineCore(Span line, HttpResponseMessage res { ReadOnlySpan reasonBytes = line.Slice(MinStatusLineLength + 1); string? knownReasonPhrase = HttpStatusDescription.Get(response.StatusCode); - if (knownReasonPhrase != null && ByteArrayHelpers.EqualsOrdinalAscii(knownReasonPhrase, reasonBytes)) + if (knownReasonPhrase != null && Ascii.Equals(reasonBytes, knownReasonPhrase)) { response.SetReasonPhraseWithoutValidation(knownReasonPhrase); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs index 45eae0fa57649f..ee85e1d277df3f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs @@ -31,7 +31,7 @@ public string GetResponseHeaderValueWithCaching(HeaderDescriptor descriptor, Rea static string GetOrAddCachedValue([NotNull] ref string? cache, HeaderDescriptor descriptor, ReadOnlySpan value, Encoding? encoding) { string? lastValue = cache; - if (lastValue is null || !ByteArrayHelpers.EqualsOrdinalAscii(lastValue, value)) + if (lastValue is null || !Ascii.Equals(value, lastValue)) { cache = lastValue = descriptor.GetHeaderValue(value, encoding); } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index f09fad6bc278c3..e27d2bdcde2713 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -25,6 +25,9 @@ $(TestArchiveRoot)browserornodejs/ $(TestArchiveTestsRoot)$(OSPlatformConfig)/ $(DefineConstants);TARGET_BROWSER + --setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot + + 01:15:00 diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs index 9ac7d796600355..4f4cf14d47e6cb 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs @@ -21,6 +21,7 @@ public abstract class TelemetryTest : HttpClientHandlerTestBase public TelemetryTest(ITestOutputHelper output) : base(output) { } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/71877", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))] public void EventSource_ExistsWithCorrectId() { Type esType = typeof(HttpClient).Assembly.GetType("System.Net.Http.HttpTelemetry", throwOnError: true, ignoreCase: false); diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props index 9ca35839f9c1be..3ee8cbfa7ae059 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props @@ -1,17 +1,18 @@ - linux-x64 - win-x64 + linux-x64 + win-x64 $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, global.json))/ - + + $(RepositoryRoot)src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/*.cs $(RepositoryRoot)eng/targetingpacks.targets 8.0.0 net8.0 8.0 Microsoft.NETCore.App $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.ref/ - $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(OutputRid)/$(Configuration)/ + $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(OutputRID)/$(Configuration)/ - \ No newline at end of file + diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile index e56f8c80c32124..6dc83bce1895eb 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile @@ -28,6 +28,7 @@ WORKDIR /app COPY . . RUN dotnet build -c $CONFIGURATION \ + -p:MsQuicInteropIncludes="/live-runtime-artifacts/msquic-interop/*.cs" \ -p:TargetingPacksTargetsLocation=/live-runtime-artifacts/targetingpacks.targets \ -p:MicrosoftNetCoreAppRefPackDir=/live-runtime-artifacts/microsoft.netcore.app.ref/ \ -p:MicrosoftNetCoreAppRuntimePackDir=/live-runtime-artifacts/microsoft.netcore.app.runtime.linux-x64/$CONFIGURATION/ diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj index bb71d66d214c2e..b98a4bd529c76a 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj @@ -4,6 +4,8 @@ $(NetCoreAppCurrent) enable True + CA2252 + true @@ -15,6 +17,11 @@ + + + + + false diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs index a1a2769273591b..0f47ae1b232fd9 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs @@ -13,6 +13,8 @@ using System.Threading.Tasks; using System.Net; using HttpStress; +using System.Net.Quic; +using Microsoft.Quic; [assembly:SupportedOSPlatform("windows")] [assembly:SupportedOSPlatform("linux")] @@ -26,6 +28,8 @@ public static class Program { public enum ExitCode { Success = 0, StressError = 1, CliError = 2 }; + public static readonly bool IsQuicSupported = QuicListener.IsSupported && QuicConnection.IsSupported; + public static async Task Main(string[] args) { if (!TryParseCli(args, out Configuration? config)) @@ -158,6 +162,9 @@ private static async Task Run(Configuration config) string GetAssemblyInfo(Assembly assembly) => $"{assembly.Location}, modified {new FileInfo(assembly.Location).LastWriteTime}"; + Type msQuicApiType = Type.GetType("System.Net.Quic.MsQuicApi, System.Net.Quic"); + string msQuicLibraryVersion = (string)msQuicApiType.GetProperty("MsQuicLibraryVersion", BindingFlags.NonPublic | BindingFlags.Static).GetGetMethod(true).Invoke(null, Array.Empty()); + Console.WriteLine(" .NET Core: " + GetAssemblyInfo(typeof(object).Assembly)); Console.WriteLine(" ASP.NET Core: " + GetAssemblyInfo(typeof(WebHost).Assembly)); Console.WriteLine(" System.Net.Http: " + GetAssemblyInfo(typeof(System.Net.Http.HttpClient).Assembly)); @@ -169,6 +176,8 @@ private static async Task Run(Configuration config) Console.WriteLine(" Concurrency: " + config.ConcurrentRequests); Console.WriteLine(" Content Length: " + config.MaxContentLength); Console.WriteLine(" HTTP Version: " + config.HttpVersion); + Console.WriteLine(" QUIC supported: " + (IsQuicSupported ? "yes" : "no")); + Console.WriteLine(" MsQuic Version: " + msQuicLibraryVersion); Console.WriteLine(" Lifetime: " + (config.ConnectionLifetime.HasValue ? $"{config.ConnectionLifetime.Value.TotalMilliseconds}ms" : "(infinite)")); Console.WriteLine(" Operations: " + string.Join(", ", usedClientOperations.Select(o => o.name))); Console.WriteLine(" Random Seed: " + config.RandomSeed); @@ -177,6 +186,23 @@ private static async Task Run(Configuration config) Console.WriteLine("Query Parameters: " + config.MaxParameters); Console.WriteLine(); + if (config.HttpVersion == HttpVersion.Version30 && IsQuicSupported) + { + unsafe + { + // If the system gets overloaded, MsQuic has a tendency to drop incoming connections, see https://github.com/dotnet/runtime/issues/55979. + // So in case we're running H/3 stress test, we're using the same hack as for System.Net.Quic tests, which increases the time limit for pending operations in MsQuic thread pool. + object msQuicApiInstance = msQuicApiType.GetProperty("Api", BindingFlags.NonPublic | BindingFlags.Static).GetGetMethod(true).Invoke(null, Array.Empty()); + QUIC_API_TABLE* apiTable = (QUIC_API_TABLE*)(Pointer.Unbox(msQuicApiType.GetProperty("ApiTable").GetGetMethod().Invoke(msQuicApiInstance, Array.Empty()))); + QUIC_SETTINGS settings = default(QUIC_SETTINGS); + settings.IsSet.MaxWorkerQueueDelayUs = 1; + settings.MaxWorkerQueueDelayUs = 2_500_000u; // 2.5s, 10x the default + if (MsQuic.StatusFailed(apiTable->SetParam(null, MsQuic.QUIC_PARAM_GLOBAL_SETTINGS, (uint)sizeof(QUIC_SETTINGS), (byte*)&settings))) + { + Console.WriteLine($"Unable to set MsQuic MaxWorkerQueueDelayUs."); + } + } + } StressServer? server = null; if (config.RunMode.HasFlag(RunMode.server)) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 index b0509e14879d94..dbdd2e696c6344 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 @@ -14,7 +14,7 @@ if (-not ([string]::IsNullOrEmpty($args[0]))) { $LibrariesConfiguration = "Release" if (-not ([string]::IsNullOrEmpty($args[1]))) { - $LibrariesConfiguration = $args[0] + $LibrariesConfiguration = $args[1] } $TestHostRoot="$RepoRoot/artifacts/bin/testhost/net$Version-windows-$LibrariesConfiguration-x64" @@ -53,11 +53,11 @@ if (-not (Test-Path -Path "$TestHostRoot/shared/Microsoft.AspNetCore.App")) { Write-Host "Building solution." dotnet build -c $StressConfiguration -$Runscript=".\run-stress-$LibrariesConfiguration-$StressConfiguration.ps1" +$Runscript=".\run-stress-$StressConfiguration-$LibrariesConfiguration.ps1" if (-not (Test-Path $Runscript)) { Write-Host "Generating Runscript." Add-Content -Path $Runscript -Value "& '$TestHostRoot/dotnet' exec --roll-forward Major ./bin/$StressConfiguration/net$Version/HttpStress.dll `$args" } Write-Host "To run tests type:" -Write-Host "$Runscript [stress test args]" \ No newline at end of file +Write-Host "$Runscript [stress test args]" diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile index 4c4539b43fd937..b090d4eb246364 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile @@ -12,6 +12,7 @@ ARG VERSION=8.0 ARG CONFIGURATION=Release RUN dotnet build -c $env:CONFIGURATION ` + -p:MsQuicInteropIncludes="C:/live-runtime-artifacts/msquic-interop/*.cs" ` -p:TargetingPacksTargetsLocation=C:/live-runtime-artifacts/targetingpacks.targets ` -p:MicrosoftNetCoreAppRefPackDir=C:/live-runtime-artifacts/microsoft.netcore.app.ref/ ` -p:MicrosoftNetCoreAppRuntimePackDir=C:/live-runtime-artifacts/microsoft.netcore.app.runtime.win-x64/$env:CONFIGURATION/ diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index f2c2e356707c7f..64232533af16b4 100755 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -70,8 +70,6 @@ Link="ProductionCode\System\Net\Http\DelegatingHandler.cs" /> - ? p; - if (s_ipEndPoints.ContainsKey(addr)) + if (s_ipEndPoints.TryGetValue(addr, out Dictionary? value)) { - p = s_ipEndPoints[addr]; + p = value; } else { @@ -146,9 +146,9 @@ private static HttpEndPointListener GetEPListener(string host, int port, HttpLis } HttpEndPointListener? epl; - if (p.ContainsKey(port)) + if (p.TryGetValue(port, out HttpEndPointListener? epListener)) { - epl = p[port]; + epl = epListener; } else { diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs index 3a872b717b08af..a8bad6f71d62ae 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs @@ -64,7 +64,7 @@ private sealed class Context : TransportContext private Stream? _inputStream; private readonly HttpListenerContext _context; private bool _isChunked; - private static readonly IndexOfAnyValues s_validMethodChars = IndexOfAnyValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"); + private static readonly SearchValues s_validMethodChars = SearchValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"); private static readonly byte[] s_100continue = "HTTP/1.1 100 Continue\r\n\r\n"u8.ToArray(); internal HttpListenerRequest(HttpListenerContext context) diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs index cc75fb5be9413d..0df8b537c63942 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs @@ -21,13 +21,13 @@ internal static class MailBnfHelper // characters allowed inside of comments internal static readonly bool[] Ctext = CreateCharactersAllowedInComments(); - private static readonly IndexOfAnyValues s_charactersAllowedInHeaderNames = + private static readonly SearchValues s_charactersAllowedInHeaderNames = // ftext = %d33-57 / %d59-126 - IndexOfAnyValues.Create("!\"#$%&'()*+,-./0123456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); + SearchValues.Create("!\"#$%&'()*+,-./0123456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); - private static readonly IndexOfAnyValues s_charactersAllowedInTokens = + private static readonly SearchValues s_charactersAllowedInTokens = // ttext = %d33-126 except '()<>@,;:\"/[]?=' - IndexOfAnyValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"); + SearchValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"); internal const char Quote = '\"'; internal const char Space = ' '; diff --git a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs index 76d0b3c1a009fb..1908de07c31b30 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs @@ -42,10 +42,10 @@ public sealed class Cookie internal static readonly char[] PortSplitDelimiters = new char[] { ' ', ',', '\"' }; // Space (' ') should be reserved as well per RFCs, but major web browsers support it and some web sites use it - so we support it too - private static readonly IndexOfAnyValues s_reservedToNameChars = IndexOfAnyValues.Create("\t\r\n=;,"); + private static readonly SearchValues s_reservedToNameChars = SearchValues.Create("\t\r\n=;,"); - private static readonly IndexOfAnyValues s_domainChars = - IndexOfAnyValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"); + private static readonly SearchValues s_domainChars = + SearchValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"); private string m_comment = string.Empty; // Do not rename (binary serialization) private Uri? m_commentUri; // Do not rename (binary serialization) diff --git a/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs b/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs index dccd0daf4c8e34..932596828d755f 100644 --- a/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs +++ b/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs @@ -28,6 +28,7 @@ internal QuicConnection() { } public System.Net.Security.SslApplicationProtocol NegotiatedApplicationProtocol { get { throw null; } } public System.Security.Cryptography.X509Certificates.X509Certificate? RemoteCertificate { get { throw null; } } public System.Net.IPEndPoint RemoteEndPoint { get { throw null; } } + public string TargetHostName { get { throw null; } } public System.Threading.Tasks.ValueTask AcceptInboundStreamAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public System.Threading.Tasks.ValueTask CloseAsync(long errorCode, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask ConnectAsync(System.Net.Quic.QuicClientConnectionOptions options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -122,6 +123,7 @@ public override void Flush() { } public override int ReadByte() { throw null; } public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; } public override void SetLength(long value) { } + public override string ToString() { throw null; } public override void Write(byte[] buffer, int offset, int count) { } public override void Write(System.ReadOnlySpan buffer) { } public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } diff --git a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj index d3864b6c24cb70..c30e10521a02f7 100644 --- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj @@ -32,6 +32,10 @@ + + + + @@ -99,7 +103,6 @@ - @@ -109,6 +112,7 @@ + diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs index 53842f8c43ac75..778b2d72d45cbb 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs @@ -130,7 +130,7 @@ static MsQuicApi() } string? gitHash = Marshal.PtrToStringUTF8((IntPtr)libGitHash); - MsQuicLibraryVersion = $"{Interop.Libraries.MsQuic} version={version} commit={gitHash}"; + MsQuicLibraryVersion = $"{Interop.Libraries.MsQuic} {version} ({gitHash})"; if (version < s_minMsQuicVersion) { @@ -143,7 +143,7 @@ static MsQuicApi() if (NetEventSource.Log.IsEnabled()) { - NetEventSource.Info(null, $"Loaded MsQuic library version '{version}', commit '{gitHash}'."); + NetEventSource.Info(null, $"Loaded MsQuic library '{MsQuicLibraryVersion}'."); } // Assume SChannel is being used on windows and query for the actual provider from the library if querying is supported diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.cs index 84b4ea02f2a102..337884c61a5d3b 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Threading; @@ -54,7 +55,7 @@ public static MsQuicSafeHandle Create(QuicClientConnectionOptions options) { foreach (X509Certificate clientCertificate in authenticationOptions.ClientCertificates) { - if( clientCertificate.HasPrivateKey()) + if (clientCertificate.HasPrivateKey()) { certificate = clientCertificate; break; @@ -69,7 +70,7 @@ public static MsQuicSafeHandle Create(QuicClientConnectionOptions options) } } - return Create(options, flags, certificate, ReadOnlySpan.Empty, authenticationOptions.ApplicationProtocols, authenticationOptions.CipherSuitesPolicy, authenticationOptions.EncryptionPolicy); + return Create(options, flags, certificate, null, authenticationOptions.ApplicationProtocols, authenticationOptions.CipherSuitesPolicy, authenticationOptions.EncryptionPolicy); } public static MsQuicSafeHandle Create(QuicServerConnectionOptions options, string? targetHost) @@ -85,10 +86,10 @@ public static MsQuicSafeHandle Create(QuicServerConnectionOptions options, strin } X509Certificate? certificate = null; - ReadOnlySpan intermediates = default; + ReadOnlyCollection? intermediates = default; if (authenticationOptions.ServerCertificateContext is not null) { - certificate = authenticationOptions.ServerCertificateContext.Certificate; + certificate = authenticationOptions.ServerCertificateContext.TargetCertificate; intermediates = authenticationOptions.ServerCertificateContext.IntermediateCertificates; } @@ -101,7 +102,7 @@ public static MsQuicSafeHandle Create(QuicServerConnectionOptions options, strin return Create(options, flags, certificate, intermediates, authenticationOptions.ApplicationProtocols, authenticationOptions.CipherSuitesPolicy, authenticationOptions.EncryptionPolicy); } - private static unsafe MsQuicSafeHandle Create(QuicConnectionOptions options, QUIC_CREDENTIAL_FLAGS flags, X509Certificate? certificate, ReadOnlySpan intermediates, List? alpnProtocols, CipherSuitesPolicy? cipherSuitesPolicy, EncryptionPolicy encryptionPolicy) + private static unsafe MsQuicSafeHandle Create(QuicConnectionOptions options, QUIC_CREDENTIAL_FLAGS flags, X509Certificate? certificate, ReadOnlyCollection? intermediates, List? alpnProtocols, CipherSuitesPolicy? cipherSuitesPolicy, EncryptionPolicy encryptionPolicy) { // Validate options and SSL parameters. if (alpnProtocols is null || alpnProtocols.Count <= 0) @@ -171,7 +172,7 @@ private static unsafe MsQuicSafeHandle Create(QuicConnectionOptions options, QUI byte[] certificateData; - if (intermediates.Length > 0) + if (intermediates != null && intermediates.Count > 0) { X509Certificate2Collection collection = new X509Certificate2Collection(); collection.Add(certificate); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.SslConnectionOptions.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.SslConnectionOptions.cs index d376a5a3079d66..333ef433bb9937 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.SslConnectionOptions.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.SslConnectionOptions.cs @@ -28,7 +28,7 @@ private readonly struct SslConnectionOptions /// /// Host name send in SNI, set only for outbound/client connections. Configured via . /// - private readonly string? _targetHost; + private readonly string _targetHost; /// /// Always true for outbound/client connections. Configured for inbound/server ones via . /// @@ -47,8 +47,10 @@ private readonly struct SslConnectionOptions /// private readonly X509ChainPolicy? _certificateChainPolicy; + internal string TargetHost => _targetHost; + public SslConnectionOptions(QuicConnection connection, bool isClient, - string? targetHost, bool certificateRequired, X509RevocationMode + string targetHost, bool certificateRequired, X509RevocationMode revocationMode, RemoteCertificateValidationCallback? validationCallback, X509ChainPolicy? certificateChainPolicy) { @@ -118,7 +120,7 @@ public unsafe int ValidateCertificate(QUIC_BUFFER* certificatePtr, QUIC_BUFFER* if (result is not null) { bool checkCertName = !chain!.ChainPolicy!.VerificationFlags.HasFlag(X509VerificationFlags.IgnoreInvalidName); - sslPolicyErrors |= CertificateValidation.BuildChainAndVerifyProperties(chain!, result, checkCertName, !_isClient, _targetHost, certificateBuffer, certificateLength); + sslPolicyErrors |= CertificateValidation.BuildChainAndVerifyProperties(chain!, result, checkCertName, !_isClient, TargetHostNameHelper.NormalizeHostName(_targetHost), certificateBuffer, certificateLength); } else if (_certificateRequired) { diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index fdc06d31632249..eee513c94073d8 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -149,6 +149,12 @@ public static async ValueTask ConnectAsync(QuicClientConnectionO /// public IPEndPoint LocalEndPoint => _localEndPoint; + /// + /// Gets the name of the server the client is trying to connect to. That name is used for server certificate validation. It can be a DNS name or an IP address. + /// + /// The name of the server the client is trying to connect to. + public string TargetHostName => _sslConnectionOptions.TargetHost ?? string.Empty; + /// /// The certificate provided by the peer. /// For an outbound/client connection will always have the peer's (server) certificate; for an inbound/server one, only if the connection requested and the peer (client) provided one. @@ -247,7 +253,7 @@ private async ValueTask FinishConnectAsync(QuicClientConnectionOptions options, // RemoteEndPoint is DnsEndPoint containing hostname that is different from requested SNI. // --> Resolve the hostname and set the IP directly, use requested SNI in ConnectionStart. else if (host is not null && - !host.Equals(options.ClientAuthenticationOptions.TargetHost, StringComparison.InvariantCultureIgnoreCase)) + !host.Equals(options.ClientAuthenticationOptions.TargetHost, StringComparison.OrdinalIgnoreCase)) { IPAddress[] addresses = await Dns.GetHostAddressesAsync(host!, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); @@ -279,10 +285,16 @@ private async ValueTask FinishConnectAsync(QuicClientConnectionOptions options, MsQuicHelpers.SetMsQuicParameter(_handle, QUIC_PARAM_CONN_LOCAL_ADDRESS, quicAddress); } + // RFC 6066 forbids IP literals + // DNI mapping is handled by MsQuic + var hostname = TargetHostNameHelper.IsValidAddress(options.ClientAuthenticationOptions.TargetHost) + ? string.Empty + : options.ClientAuthenticationOptions.TargetHost ?? string.Empty; + _sslConnectionOptions = new SslConnectionOptions( this, isClient: true, - options.ClientAuthenticationOptions.TargetHost, + hostname, certificateRequired: true, options.ClientAuthenticationOptions.CertificateRevocationCheckMode, options.ClientAuthenticationOptions.RemoteCertificateValidationCallback, @@ -312,7 +324,7 @@ private async ValueTask FinishConnectAsync(QuicClientConnectionOptions options, await valueTask.ConfigureAwait(false); } - internal ValueTask FinishHandshakeAsync(QuicServerConnectionOptions options, string? targetHost, CancellationToken cancellationToken = default) + internal ValueTask FinishHandshakeAsync(QuicServerConnectionOptions options, string targetHost, CancellationToken cancellationToken = default) { ObjectDisposedException.ThrowIf(_disposed == 1, this); @@ -322,10 +334,16 @@ internal ValueTask FinishHandshakeAsync(QuicServerConnectionOptions options, str _defaultStreamErrorCode = options.DefaultStreamErrorCode; _defaultCloseErrorCode = options.DefaultCloseErrorCode; + // RFC 6066 forbids IP literals, avoid setting IP address here for consistency with SslStream + if (TargetHostNameHelper.IsValidAddress(targetHost)) + { + targetHost = string.Empty; + } + _sslConnectionOptions = new SslConnectionOptions( this, isClient: false, - targetHost: null, + targetHost, options.ServerAuthenticationOptions.ClientCertificateRequired, options.ServerAuthenticationOptions.CertificateRevocationCheckMode, options.ServerAuthenticationOptions.RemoteCertificateValidationCallback, diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 5812a9b69c17d1..ae105609924610 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -335,7 +335,7 @@ public async Task ConnectWithServerCertificateCallback() // TODO: the exception may change if we implement https://github.com/dotnet/runtime/issues/73152 to make server close // connections with CONNECTION_REFUSED in such cases var authEx = await Assert.ThrowsAsync(() => clientTask); - Assert.Contains("UserCanceled", authEx.Message); + Assert.Contains(TlsAlertMessage.UserCanceled.ToString(), authEx.Message); Assert.Equal(clientOptions.ClientAuthenticationOptions.TargetHost, receivedHostName); await Assert.ThrowsAsync(async () => await listener.AcceptConnectionAsync()); @@ -1204,5 +1204,58 @@ public async Task IdleTimeout_ThrowsQuicException() await AssertThrowsQuicExceptionAsync(QuicError.ConnectionIdle, async () => await acceptTask).WaitAsync(TimeSpan.FromSeconds(10)); } } + + private async Task SniTestCore(string hostname, bool shouldSendSni) + { + string expectedHostName = shouldSendSni ? hostname : string.Empty; + + using X509Certificate serverCert = Configuration.Certificates.GetSelfSignedServerCertificate(); + var listenerOptions = new QuicListenerOptions() + { + ListenEndPoint = new IPEndPoint(IPAddress.Loopback, 0), + ApplicationProtocols = new List() { ApplicationProtocol }, + ConnectionOptionsCallback = (_, _, _) => + { + var serverOptions = CreateQuicServerOptions(); + serverOptions.ServerAuthenticationOptions.ServerCertificateContext = null; + serverOptions.ServerAuthenticationOptions.ServerCertificate = null; + serverOptions.ServerAuthenticationOptions.ServerCertificateSelectionCallback = (sender, actualHostName) => + { + Assert.Equal(expectedHostName, actualHostName); + return serverCert; + }; + return ValueTask.FromResult(serverOptions); + } + }; + + // Use whatever endpoint, it'll get overwritten in CreateConnectedQuicConnection. + QuicClientConnectionOptions clientOptions = CreateQuicClientOptions(listenerOptions.ListenEndPoint); + clientOptions.ClientAuthenticationOptions.TargetHost = hostname; + clientOptions.ClientAuthenticationOptions.RemoteCertificateValidationCallback = delegate { return true; }; + + + (QuicConnection clientConnection, QuicConnection serverConnection) = await CreateConnectedQuicConnection(clientOptions, listenerOptions); + await using (clientConnection) + await using (serverConnection) + { + Assert.Equal(expectedHostName, clientConnection.TargetHostName); + Assert.Equal(expectedHostName, serverConnection.TargetHostName); + } + } + + [Theory] + [InlineData("a")] + [InlineData("test")] + [InlineData("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] // max allowed hostname length is 63 + [InlineData("\u017C\u00F3\u0142\u0107 g\u0119\u015Bl\u0105 ja\u017A\u0144. \u7EA2\u70E7. \u7167\u308A\u713C\u304D")] + public Task ClientSendsSniServerReceives_Ok(string hostname) => SniTestCore(hostname, true); + + [Theory] + [InlineData("127.0.0.1")] + [InlineData("::1")] + [InlineData("2001:11:22::1")] + [InlineData("fe80::9c3a:b64d:6249:1de8%2")] + [InlineData("fe80::9c3a:b64d:6249:1de8")] + public Task DoesNotSendIPAsSni(string target) => SniTestCore(target, false); } } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs index a12a14e8c9eb0f..f2c34ebda10b5b 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs @@ -22,7 +22,8 @@ public async Task TestConnect() { await using QuicListener listener = await CreateQuicListener(); - ValueTask connectTask = CreateQuicConnection(listener.LocalEndPoint); + var options = CreateQuicClientOptions(listener.LocalEndPoint); + ValueTask connectTask = CreateQuicConnection(options); ValueTask acceptTask = listener.AcceptConnectionAsync(); await new Task[] { connectTask.AsTask(), acceptTask.AsTask() }.WhenAllOrAnyFailed(PassingTestTimeoutMilliseconds); @@ -34,6 +35,8 @@ public async Task TestConnect() Assert.Equal(clientConnection.LocalEndPoint, serverConnection.RemoteEndPoint); Assert.Equal(ApplicationProtocol.ToString(), clientConnection.NegotiatedApplicationProtocol.ToString()); Assert.Equal(ApplicationProtocol.ToString(), serverConnection.NegotiatedApplicationProtocol.ToString()); + Assert.Equal(options.ClientAuthenticationOptions.TargetHost, clientConnection.TargetHostName); + Assert.Equal(options.ClientAuthenticationOptions.TargetHost, serverConnection.TargetHostName); } private static async Task OpenAndUseStreamAsync(QuicConnection c) diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs index 34872a740e1fbf..149ac5bc2671e3 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs @@ -13,8 +13,8 @@ using Xunit.Abstractions; using System.Diagnostics.Tracing; using System.Net.Sockets; +using System.Reflection; using Microsoft.Quic; -using static Microsoft.Quic.MsQuic; namespace System.Net.Quic.Tests { @@ -44,14 +44,20 @@ public abstract class QuicTestBase : IDisposable static unsafe QuicTestBase() { - Console.WriteLine($"MsQuic {(IsSupported ? "supported" : "not supported")} and using '{MsQuicApi.MsQuicLibraryVersion}'."); + // If any of the reflection bellow breaks due to changes in "System.Net.Quic.MsQuicApi", also check and fix HttpStress project as it uses the same hack. + Type msQuicApiType = Type.GetType("System.Net.Quic.MsQuicApi, System.Net.Quic"); + + string msQuicLibraryVersion = (string)msQuicApiType.GetProperty("MsQuicLibraryVersion", BindingFlags.NonPublic | BindingFlags.Static).GetGetMethod(true).Invoke(null, Array.Empty()); + Console.WriteLine($"MsQuic {(IsSupported ? "supported" : "not supported")} and using '{msQuicLibraryVersion}'."); if (IsSupported) { + object msQuicApiInstance = msQuicApiType.GetProperty("Api", BindingFlags.NonPublic | BindingFlags.Static).GetGetMethod(true).Invoke(null, Array.Empty()); + QUIC_API_TABLE* apiTable = (QUIC_API_TABLE*)(Pointer.Unbox(msQuicApiType.GetProperty("ApiTable").GetGetMethod().Invoke(msQuicApiInstance, Array.Empty()))); QUIC_SETTINGS settings = default(QUIC_SETTINGS); settings.IsSet.MaxWorkerQueueDelayUs = 1; settings.MaxWorkerQueueDelayUs = 2_500_000u; // 2.5s, 10x the default - if (StatusFailed(MsQuicApi.Api.ApiTable->SetParam(null, QUIC_PARAM_GLOBAL_SETTINGS, (uint)sizeof(QUIC_SETTINGS), (byte*)&settings))) + if (MsQuic.StatusFailed(apiTable->SetParam(null, MsQuic.QUIC_PARAM_GLOBAL_SETTINGS, (uint)sizeof(QUIC_SETTINGS), (byte*)&settings))) { Console.WriteLine($"Unable to set MsQuic MaxWorkerQueueDelayUs."); } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj b/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj index 2b31dee92406ba..55ddd30f86abbb 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj @@ -16,6 +16,7 @@ + @@ -31,18 +32,8 @@ - - - - - - - - - - - + diff --git a/src/libraries/System.Net.Security/ref/System.Net.Security.cs b/src/libraries/System.Net.Security/ref/System.Net.Security.cs index c6b5ad00e1904a..9fb9b379da5c82 100644 --- a/src/libraries/System.Net.Security/ref/System.Net.Security.cs +++ b/src/libraries/System.Net.Security/ref/System.Net.Security.cs @@ -19,8 +19,8 @@ protected AuthenticatedStream(System.IO.Stream innerStream, bool leaveInnerStrea protected override void Dispose(bool disposing) { } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] public sealed partial class CipherSuitesPolicy { [System.CLSCompliantAttribute(false)] @@ -216,6 +216,7 @@ public readonly partial struct SslClientHelloInfo { private readonly object _dummy; private readonly int _dummyPrimitive; + public SslClientHelloInfo(string serverName, System.Security.Authentication.SslProtocols sslProtocols) { throw null; } public string ServerName { get { throw null; } } public System.Security.Authentication.SslProtocols SslProtocols { get { throw null; } } } @@ -304,9 +305,9 @@ public override void EndWrite(System.IAsyncResult asyncResult) { } ~SslStream() { } public override void Flush() { } public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("freebsd")] [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("freebsd")] public virtual System.Threading.Tasks.Task NegotiateClientCertificateAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override int Read(byte[] buffer, int offset, int count) { throw null; } public override System.Threading.Tasks.Task ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } @@ -323,6 +324,8 @@ public override void Write(byte[] buffer, int offset, int count) { } public partial class SslStreamCertificateContext { internal SslStreamCertificateContext() { } + public System.Collections.ObjectModel.ReadOnlyCollection IntermediateCertificates { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509Certificate2 TargetCertificate { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.Net.Security.SslStreamCertificateContext Create(System.Security.Cryptography.X509Certificates.X509Certificate2 target, System.Security.Cryptography.X509Certificates.X509Certificate2Collection? additionalCertificates, bool offline) { throw null; } public static System.Net.Security.SslStreamCertificateContext Create(System.Security.Cryptography.X509Certificates.X509Certificate2 target, System.Security.Cryptography.X509Certificates.X509Certificate2Collection? additionalCertificates, bool offline = false, System.Net.Security.SslCertificateTrust? trust = null) { throw null; } @@ -674,8 +677,8 @@ namespace System.Security.Authentication public partial class AuthenticationException : System.SystemException { public AuthenticationException() { } - [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId="SYSLIB0051", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] protected AuthenticationException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { } public AuthenticationException(string? message) { } public AuthenticationException(string? message, System.Exception? innerException) { } @@ -683,8 +686,8 @@ public AuthenticationException(string? message, System.Exception? innerException public partial class InvalidCredentialException : System.Security.Authentication.AuthenticationException { public InvalidCredentialException() { } - [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId="SYSLIB0051", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] protected InvalidCredentialException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { } public InvalidCredentialException(string? message) { } public InvalidCredentialException(string? message, System.Exception? innerException) { } @@ -694,8 +697,8 @@ namespace System.Security.Authentication.ExtendedProtection { public partial class ExtendedProtectionPolicy : System.Runtime.Serialization.ISerializable { - [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId="SYSLIB0051", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] protected ExtendedProtectionPolicy(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public ExtendedProtectionPolicy(System.Security.Authentication.ExtendedProtection.PolicyEnforcement policyEnforcement) { } public ExtendedProtectionPolicy(System.Security.Authentication.ExtendedProtection.PolicyEnforcement policyEnforcement, System.Security.Authentication.ExtendedProtection.ChannelBinding customChannelBinding) { } diff --git a/src/libraries/System.Net.Security/src/CompatibilitySuppressions.xml b/src/libraries/System.Net.Security/src/CompatibilitySuppressions.xml deleted file mode 100644 index 68c7f6f58824cf..00000000000000 --- a/src/libraries/System.Net.Security/src/CompatibilitySuppressions.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - CP0002 - F:System.Net.Security.SslStreamCertificateContext.Certificate - ref/net8.0/System.Net.Security.dll - runtimes/android/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslClientHelloInfo.#ctor(System.String,System.Security.Authentication.SslProtocols) - ref/net8.0/System.Net.Security.dll - runtimes/android/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslStreamCertificateContext.get_IntermediateCertificates - ref/net8.0/System.Net.Security.dll - runtimes/android/lib/net8.0/System.Net.Security.dll - - - CP0002 - F:System.Net.Security.SslStreamCertificateContext.Certificate - ref/net8.0/System.Net.Security.dll - runtimes/freebsd/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslClientHelloInfo.#ctor(System.String,System.Security.Authentication.SslProtocols) - ref/net8.0/System.Net.Security.dll - runtimes/freebsd/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslStreamCertificateContext.get_IntermediateCertificates - ref/net8.0/System.Net.Security.dll - runtimes/freebsd/lib/net8.0/System.Net.Security.dll - - - CP0002 - F:System.Net.Security.SslStreamCertificateContext.Certificate - ref/net8.0/System.Net.Security.dll - runtimes/ios/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslClientHelloInfo.#ctor(System.String,System.Security.Authentication.SslProtocols) - ref/net8.0/System.Net.Security.dll - runtimes/ios/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslStreamCertificateContext.get_IntermediateCertificates - ref/net8.0/System.Net.Security.dll - runtimes/ios/lib/net8.0/System.Net.Security.dll - - - CP0002 - F:System.Net.Security.SslStreamCertificateContext.Certificate - ref/net8.0/System.Net.Security.dll - runtimes/linux/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslClientHelloInfo.#ctor(System.String,System.Security.Authentication.SslProtocols) - ref/net8.0/System.Net.Security.dll - runtimes/linux/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslStreamCertificateContext.get_IntermediateCertificates - ref/net8.0/System.Net.Security.dll - runtimes/linux/lib/net8.0/System.Net.Security.dll - - - CP0002 - F:System.Net.Security.SslStreamCertificateContext.Certificate - ref/net8.0/System.Net.Security.dll - runtimes/osx/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslClientHelloInfo.#ctor(System.String,System.Security.Authentication.SslProtocols) - ref/net8.0/System.Net.Security.dll - runtimes/osx/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslStreamCertificateContext.get_IntermediateCertificates - ref/net8.0/System.Net.Security.dll - runtimes/osx/lib/net8.0/System.Net.Security.dll - - - CP0002 - F:System.Net.Security.SslStreamCertificateContext.Certificate - ref/net8.0/System.Net.Security.dll - runtimes/tvos/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslClientHelloInfo.#ctor(System.String,System.Security.Authentication.SslProtocols) - ref/net8.0/System.Net.Security.dll - runtimes/tvos/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslStreamCertificateContext.get_IntermediateCertificates - ref/net8.0/System.Net.Security.dll - runtimes/tvos/lib/net8.0/System.Net.Security.dll - - - CP0002 - F:System.Net.Security.SslStreamCertificateContext.Certificate - ref/net8.0/System.Net.Security.dll - runtimes/win/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslClientHelloInfo.#ctor(System.String,System.Security.Authentication.SslProtocols) - ref/net8.0/System.Net.Security.dll - runtimes/win/lib/net8.0/System.Net.Security.dll - - - CP0002 - M:System.Net.Security.SslStreamCertificateContext.get_IntermediateCertificates - ref/net8.0/System.Net.Security.dll - runtimes/win/lib/net8.0/System.Net.Security.dll - - \ No newline at end of file diff --git a/src/libraries/System.Net.Security/src/ReferenceAssemblyExclusions.txt b/src/libraries/System.Net.Security/src/ReferenceAssemblyExclusions.txt deleted file mode 100644 index 3194936ec9bc4d..00000000000000 --- a/src/libraries/System.Net.Security/src/ReferenceAssemblyExclusions.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Used internally by System.Net.Quic -F:System.Net.Security.SslStreamCertificateContext.Certificate -F:System.Net.Security.SslStreamCertificateContext.IntermediateCertificates -C:System.Net.Security.SslClientHelloInfo.SslClientHelloInfo \ No newline at end of file diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 54f8c9feeb4d6f..2de2f39ee186bc 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -92,6 +92,8 @@ Link="Common\System\NotImplemented.cs" /> + ipSpan) - { - int end = ipSpan.Length; - - if (ipSpan.Contains(':')) - { - // The address is parsed as IPv6 if and only if it contains a colon. This is valid because - // we don't support/parse a port specification at the end of an IPv4 address. - Span numbers = stackalloc ushort[IPAddressParserStatics.IPv6AddressShorts]; - - fixed (char* ipStringPtr = &MemoryMarshal.GetReference(ipSpan)) - { - return IPv6AddressHelper.IsValidStrict(ipStringPtr, 0, ref end); - } - } - else if (char.IsDigit(ipSpan[0])) - { - long tmpAddr; - - fixed (char* ipStringPtr = &MemoryMarshal.GetReference(ipSpan)) - { - tmpAddr = IPv4AddressHelper.ParseNonCanonical(ipStringPtr, 0, ref end, notImplicitFile: true); - } - - if (tmpAddr != IPv4AddressHelper.Invalid && end == ipSpan.Length) - { - return true; - } - } - - return false; - } - - private static readonly IndexOfAnyValues s_safeDnsChars = - IndexOfAnyValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"); - - private static bool IsSafeDnsString(ReadOnlySpan name) => - name.IndexOfAnyExcept(s_safeDnsChars) < 0; - internal SslAuthenticationOptions() { TargetHost = string.Empty; @@ -93,29 +48,11 @@ internal void UpdateOptions(SslClientAuthenticationOptions sslClientAuthenticati IsServer = false; RemoteCertRequired = true; CertificateContext = sslClientAuthenticationOptions.ClientCertificateContext; - if (!string.IsNullOrEmpty(sslClientAuthenticationOptions.TargetHost)) - { - // RFC 6066 section 3 says to exclude trailing dot from fully qualified DNS hostname - string targetHost = sslClientAuthenticationOptions.TargetHost.TrimEnd('.'); - // RFC 6066 forbids IP literals - if (IsValidAddress(targetHost)) - { - TargetHost = string.Empty; - } - else - { - try - { - TargetHost = s_idnMapping.GetAscii(targetHost); - } - catch (ArgumentException) when (IsSafeDnsString(targetHost)) - { - // Seems like name that does not confrom to IDN but apers somewhat valid according to orogional DNS rfc. - TargetHost = targetHost; - } - } - } + // RFC 6066 forbids IP literals + TargetHost = TargetHostNameHelper.IsValidAddress(sslClientAuthenticationOptions.TargetHost) + ? string.Empty + : sslClientAuthenticationOptions.TargetHost ?? string.Empty; // Client specific options. CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs index 6ca7dcf5a9d951..79e655cb112226 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs @@ -44,7 +44,7 @@ internal X509Certificate? LocalServerCertificate { get { - return _sslAuthenticationOptions.CertificateContext?.Certificate; + return _sslAuthenticationOptions.CertificateContext?.TargetCertificate; } } @@ -271,9 +271,9 @@ private string[] GetRequestCertificateAuthorities() // private key, so we don't have to do any further processing. // - _selectedClientCertificate = _sslAuthenticationOptions.CertificateContext.Certificate; + _selectedClientCertificate = _sslAuthenticationOptions.CertificateContext.TargetCertificate; if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Selected cert = {_selectedClientCertificate}"); - return _sslAuthenticationOptions.CertificateContext.Certificate; + return _sslAuthenticationOptions.CertificateContext.TargetCertificate; } else if (_sslAuthenticationOptions.CertSelectionDelegate != null) { @@ -635,7 +635,7 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint) else if (_sslAuthenticationOptions.CertSelectionDelegate != null) { X509CertificateCollection tempCollection = new X509CertificateCollection(); - tempCollection.Add(_sslAuthenticationOptions.CertificateContext!.Certificate!); + tempCollection.Add(_sslAuthenticationOptions.CertificateContext!.TargetCertificate!); // We pass string.Empty here to maintain strict compatibility with .NET Framework. localCertificate = _sslAuthenticationOptions.CertSelectionDelegate(this, string.Empty, tempCollection, null, Array.Empty()); if (localCertificate == null) @@ -650,7 +650,7 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint) } else if (_sslAuthenticationOptions.CertificateContext != null) { - selectedCert = _sslAuthenticationOptions.CertificateContext.Certificate; + selectedCert = _sslAuthenticationOptions.CertificateContext.TargetCertificate; } if (selectedCert == null) @@ -733,7 +733,7 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint) static DateTime GetExpiryTimestamp(SslStreamCertificateContext certificateContext) { - DateTime expiry = certificateContext.Certificate.NotAfter; + DateTime expiry = certificateContext.TargetCertificate.NotAfter; foreach (X509Certificate2 cert in certificateContext.IntermediateCertificates) { @@ -844,10 +844,11 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte } else { + string hostName = TargetHostNameHelper.NormalizeHostName(_sslAuthenticationOptions.TargetHost); status = SslStreamPal.InitializeSecurityContext( ref _credentialsHandle!, ref _securityContext, - _sslAuthenticationOptions.TargetHost, + hostName, inputBuffer, ref result, _sslAuthenticationOptions); @@ -863,7 +864,7 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte status = SslStreamPal.InitializeSecurityContext( ref _credentialsHandle!, ref _securityContext, - _sslAuthenticationOptions.TargetHost, + hostName, ReadOnlySpan.Empty, ref result, _sslAuthenticationOptions); @@ -1059,7 +1060,7 @@ internal bool VerifyRemoteCertificate(RemoteCertificateValidationCallback? remot _remoteCertificate, _sslAuthenticationOptions.CheckCertName, _sslAuthenticationOptions.IsServer, - _sslAuthenticationOptions.TargetHost); + TargetHostNameHelper.NormalizeHostName(_sslAuthenticationOptions.TargetHost)); } if (remoteCertValidationCallback != null) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Android.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Android.cs index 79f03d189ec539..fec08b42818f32 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Android.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Android.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.ObjectModel; using System.Security.Cryptography.X509Certificates; namespace System.Net.Security @@ -9,10 +10,10 @@ public partial class SslStreamCertificateContext { private const bool TrimRootCertificate = true; - private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates, SslCertificateTrust? trust) + private SslStreamCertificateContext(X509Certificate2 target, ReadOnlyCollection intermediates, SslCertificateTrust? trust) { - _intermediateCertificates = intermediates; - Certificate = target; + IntermediateCertificates = intermediates; + TargetCertificate = target; Trust = trust; } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs index 878995d88f7a11..98380b0e84fe67 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs @@ -5,6 +5,7 @@ using System.Buffers; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Security.Authentication; using System.Security.Cryptography; @@ -29,10 +30,10 @@ public partial class SslStreamCertificateContext private List? _ocspUrls; private X509Certificate2? _ca; - private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates, SslCertificateTrust? trust) + private SslStreamCertificateContext(X509Certificate2 target, ReadOnlyCollection intermediates, SslCertificateTrust? trust) { - _intermediateCertificates = intermediates; - Certificate = target; + IntermediateCertificates = intermediates; + TargetCertificate = target; Trust = trust; SslContexts = new ConcurrentDictionary(); @@ -54,7 +55,7 @@ private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] } } - if (KeyHandle== null) + if (KeyHandle == null) { throw new NotSupportedException(SR.net_ssl_io_no_server_cert); } @@ -75,7 +76,7 @@ partial void SetNoOcspFetch(bool noOcspFetch) partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool transferredOwnership) { - if (IntermediateCertificates.Length == 0) + if (IntermediateCertificates.Count == 0) { _ca = rootCertificate; transferredOwnership = true; @@ -150,7 +151,7 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran if (_ocspUrls is null && _ca is not null) { - foreach (X509Extension ext in Certificate.Extensions) + foreach (X509Extension ext in TargetCertificate.Extensions) { if (ext is X509AuthorityInformationAccessExtension aia) { @@ -196,7 +197,7 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran Debug.Assert(_ocspUrls.Count > 0); Debug.Assert(caCert is not null); - IntPtr subject = Certificate.Handle; + IntPtr subject = TargetCertificate.Handle; IntPtr issuer = caCert.Handle; Debug.Assert(subject != 0); Debug.Assert(issuer != 0); @@ -252,7 +253,7 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran ArrayPool.Shared.Return(rentedBytes); ArrayPool.Shared.Return(rentedChars.Array!); - GC.KeepAlive(Certificate); + GC.KeepAlive(TargetCertificate); GC.KeepAlive(caCert); return ret; } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs index f98cb397b16d18..9b79e28ceb213f 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.ObjectModel; using System.Security.Cryptography.X509Certificates; namespace System.Net.Security @@ -10,10 +11,10 @@ public partial class SslStreamCertificateContext // No leaf, no root. private const bool TrimRootCertificate = true; - private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates, SslCertificateTrust? trust) + private SslStreamCertificateContext(X509Certificate2 target, ReadOnlyCollection intermediates, SslCertificateTrust? trust) { - _intermediateCertificates = intermediates; - Certificate = target; + IntermediateCertificates = intermediates; + TargetCertificate = target; Trust = trust; } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs index 8dbc2d66f379d5..33d8cd18e2d193 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.ObjectModel; using System.Security.Cryptography.X509Certificates; namespace System.Net.Security @@ -13,12 +14,12 @@ public partial class SslStreamCertificateContext internal static SslStreamCertificateContext Create(X509Certificate2 target) { // On Windows we do not need to build chain unless we are asked for it. - return new SslStreamCertificateContext(target, Array.Empty(), null); + return new SslStreamCertificateContext(target, new ReadOnlyCollection(Array.Empty()), null); } - private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates, SslCertificateTrust? trust) + private SslStreamCertificateContext(X509Certificate2 target, ReadOnlyCollection intermediates, SslCertificateTrust? trust) { - if (intermediates.Length > 0) + if (intermediates.Count > 0) { using (X509Chain chain = new X509Chain()) { @@ -74,7 +75,7 @@ private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] using (store) { // Add everything except the root - for (int index = count; index < intermediates.Length - 1; index++) + for (int index = count; index < intermediates.Count - 1; index++) { store.Add(intermediates[index]); } @@ -93,7 +94,7 @@ private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] { // Add also root to Intermediate CA store so OS can complete building chain. // (This does not make it trusted. - store.Add(intermediates[intermediates.Length - 1]); + store.Add(intermediates[intermediates.Count - 1]); } } } @@ -101,8 +102,8 @@ private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] } } - _intermediateCertificates = intermediates; - Certificate = target; + IntermediateCertificates = intermediates; + TargetCertificate = target; Trust = trust; } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs index fc7588e1a33329..dd148599f48329 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.ObjectModel; using System.ComponentModel; using System.Security.Cryptography.X509Certificates; @@ -8,12 +9,18 @@ namespace System.Net.Security { public partial class SslStreamCertificateContext { - public readonly X509Certificate2 Certificate; - public ReadOnlySpan IntermediateCertificates => _intermediateCertificates; - - private readonly X509Certificate2[] _intermediateCertificates; internal readonly SslCertificateTrust? Trust; + /// + /// Gets the target (leaf) certificate of the built chain. + /// + public X509Certificate2 TargetCertificate { get; } + + /// + /// Gets the intermediate certificates for the built chain. + /// + public ReadOnlyCollection IntermediateCertificates { get; } + [EditorBrowsable(EditorBrowsableState.Never)] public static SslStreamCertificateContext Create(X509Certificate2 target, X509Certificate2Collection? additionalCertificates, bool offline) { @@ -111,7 +118,7 @@ internal static SslStreamCertificateContext Create( } } - SslStreamCertificateContext ctx = new SslStreamCertificateContext(target, intermediates, trust); + SslStreamCertificateContext ctx = new SslStreamCertificateContext(target, new ReadOnlyCollection(intermediates), trust); // On Linux, AddRootCertificate will start a background download of an OCSP response, // unless this context was built "offline", or this came from the internal Create(X509Certificate2) @@ -133,7 +140,7 @@ internal static SslStreamCertificateContext Create( internal SslStreamCertificateContext Duplicate() { - return new SslStreamCertificateContext(new X509Certificate2(Certificate), _intermediateCertificates, Trust); + return new SslStreamCertificateContext(new X509Certificate2(TargetCertificate), IntermediateCertificates, Trust); } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index f1bd68741ed1f7..0190efeecbcb75 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -206,15 +206,15 @@ public static SafeFreeCredentials AcquireCredentialsHandle(SslAuthenticationOpti { SafeFreeCredential_SECURITY handle = (SafeFreeCredential_SECURITY)cred; // We need to create copy to avoid Disposal issue. - handle.LocalCertificate = new X509Certificate2(sslAuthenticationOptions.CertificateContext.Certificate); + handle.LocalCertificate = new X509Certificate2(sslAuthenticationOptions.CertificateContext.TargetCertificate); } return cred; } catch (Win32Exception e) when (e.NativeErrorCode == (int)Interop.SECURITY_STATUS.NoCredentials && certificateContext != null) { - Debug.Assert(certificateContext.Certificate.HasPrivateKey); - using SafeCertContextHandle safeCertContextHandle = Interop.Crypt32.CertDuplicateCertificateContext(certificateContext.Certificate.Handle); + Debug.Assert(certificateContext.TargetCertificate.HasPrivateKey); + using SafeCertContextHandle safeCertContextHandle = Interop.Crypt32.CertDuplicateCertificateContext(certificateContext.TargetCertificate.Handle); // on Windows we do not support ephemeral keys. throw new AuthenticationException(safeCertContextHandle.HasEphemeralPrivateKey ? SR.net_auth_ephemeral : SR.net_auth_SSPI, e); } @@ -249,7 +249,7 @@ private static unsafe void AttachCertificateStore(SafeFreeCredentials cred, X509 // It only supports TLS up to 1.2 public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(SslAuthenticationOptions authOptions) { - X509Certificate2? certificate = authOptions.CertificateContext?.Certificate; + X509Certificate2? certificate = authOptions.CertificateContext?.TargetCertificate; bool isServer = authOptions.IsServer; int protocolFlags = GetProtocolFlagsFromSslProtocols(authOptions.EnabledSslProtocols, isServer); Interop.SspiCli.SCHANNEL_CRED.Flags flags; @@ -311,7 +311,7 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(Ss // This function uses new crypto API to support TLS 1.3 and beyond. public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials(SslAuthenticationOptions authOptions) { - X509Certificate2? certificate = authOptions.CertificateContext?.Certificate; + X509Certificate2? certificate = authOptions.CertificateContext?.TargetCertificate; bool isServer = authOptions.IsServer; int protocolFlags = GetProtocolFlagsFromSslProtocols(authOptions.EnabledSslProtocols, isServer); Interop.SspiCli.SCH_CREDENTIALS.Flags flags; diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs index 0029de46bfc3b2..0ec5374b895c89 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs @@ -101,7 +101,6 @@ public async Task ClientOptions_ServerOptions_NotMutatedDuringAuthentication() Assert.Same(clientLocalCallback, clientOptions.LocalCertificateSelectionCallback); Assert.Same(clientRemoteCallback, clientOptions.RemoteCertificateValidationCallback); Assert.Same(clientHost, clientOptions.TargetHost); - Assert.Same(clientHost, clientOptions.TargetHost); Assert.Same(policy, clientOptions.CertificateChainPolicy); // Validate that server options are unchanged diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs index 4a0cdf41d837e3..8862f324ee2c6a 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Net.Test.Common; +using System.Net.Sockets; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading; @@ -44,6 +45,8 @@ await WithVirtualConnection(async (server, client) => await TaskTimeoutExtensions.WhenAllOrAnyFailed(new[] { clientJob, server.AuthenticateAsServerAsync(options, CancellationToken.None) }); Assert.Equal(1, timesCallbackCalled); + Assert.Equal(hostName, server.TargetHostName); + Assert.Equal(hostName, client.TargetHostName); }, (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => { @@ -200,6 +203,7 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( server.AuthenticateAsServerAsync(serverOptions, default)); Assert.Equal(string.Empty, server.TargetHostName); + Assert.Equal(string.Empty, client.TargetHostName); } [Theory] @@ -232,6 +236,49 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( } } + [Fact] + public async Task UnencodedHostName_ValidatesCertificate() + { + string rawHostname = "räksmörgås.josefsson.org"; + string punycodeHostname = "xn--rksmrgs-5wao1o.josefsson.org"; + + var (serverCert, serverChain) = TestHelper.GenerateCertificates(punycodeHostname); + try + { + SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions() + { + ServerCertificateContext = SslStreamCertificateContext.Create(serverCert, serverChain), + }; + + SslClientAuthenticationOptions clientOptions = new () + { + TargetHost = rawHostname, + CertificateChainPolicy = new X509ChainPolicy() + { + RevocationMode = X509RevocationMode.NoCheck, + TrustMode = X509ChainTrustMode.CustomRootTrust, + CustomTrustStore = { serverChain[serverChain.Count - 1] } + } + }; + + (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams(); + + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync(clientOptions, default), + server.AuthenticateAsServerAsync(serverOptions, default)); + + await TestHelper.PingPong(client, server, default); + Assert.Equal(rawHostname, server.TargetHostName); + Assert.Equal(rawHostname, client.TargetHostName); + } + finally + { + serverCert.Dispose(); + foreach (var c in serverChain) c.Dispose(); + TestHelper.CleanupCertificates(rawHostname); + } + } + [Theory] [InlineData("www-.volal.cz")] [InlineData("www-.colorhexa.com")] @@ -260,6 +307,7 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( await TestHelper.PingPong(client, server, default); Assert.Equal(name, server.TargetHostName); + Assert.Equal(name, client.TargetHostName); } } diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props index 70928e5355ab11..0183d8b3696f4e 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props @@ -1,7 +1,7 @@ - linux-x64 - win-x64 + linux-x64 + win-x64 $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, global.json))/ @@ -12,6 +12,6 @@ 8.0 Microsoft.NETCore.App $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.ref/ - $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(OutputRid)/$(Configuration)/ + $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(OutputRID)/$(Configuration)/ \ No newline at end of file diff --git a/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs b/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs index b83b8adfca2ab5..eb2b3c42b607f6 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs @@ -10,7 +10,6 @@ using System.Security.Principal; using System.Text; using System.Threading.Tasks; -using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Net.Security.Tests @@ -87,10 +86,6 @@ public void Package_Supported_NTLM() [ConditionalFact(nameof(IsNtlmUnavailable))] public void Package_Unsupported_NTLM() { - if (PlatformDetection.IsRedHatFamily7) - { - throw new SkipTestException("https://github.com/dotnet/runtime/issues/83540"); - } NegotiateAuthenticationClientOptions clientOptions = new NegotiateAuthenticationClientOptions { Package = "NTLM", Credential = s_testCredentialRight, TargetName = "HTTP/foo" }; NegotiateAuthentication negotiateAuthentication = new NegotiateAuthentication(clientOptions); NegotiateAuthenticationStatusCode statusCode; diff --git a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj index 6618a8d6fc1131..81dc725b0af91d 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj @@ -50,6 +50,8 @@ Link="Common\System\Net\Security\RC4.cs" /> + (async () => [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/83517", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri server) { string message = "Hello WebSockets!"; diff --git a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs index f45ed7fd9c14ca..18694fcd97a1a9 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs @@ -249,7 +249,7 @@ public async Task SendAsync_MultipleOutstandingSendOperations_Throws(Uri server) [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] // This will also pass when no exception is thrown. Current implementation doesn't throw. - [ActiveIssue("https://github.com/dotnet/runtime/issues/83517", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/83517", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] public async Task ReceiveAsync_MultipleOutstandingReceiveOperations_Throws(Uri server) { using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) diff --git a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj index e15f88b3c36900..a2e9e556060036 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj +++ b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj @@ -7,9 +7,6 @@ $(DefineConstants);NETSTANDARD false - - - $(WasmXHarnessMonoArgs) --no-memory-snapshot @@ -18,6 +15,10 @@ $(TestArchiveRoot)browserornodejs/ $(TestArchiveTestsRoot)$(OSPlatformConfig)/ $(DefineConstants);TARGET_BROWSER + --setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot + + + 01:15:00 diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoX86Intrinsics.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoX86Intrinsics.xml index 9ed12df60f0269..382d3d7e71dc06 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoX86Intrinsics.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoX86Intrinsics.xml @@ -60,6 +60,15 @@ + + + + + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 6865608cb14aae..929ee6132d851d 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -2392,6 +2392,18 @@ The input string '{0}' was not in a correct format. + + Input string was not in a correct format. Failure to parse near offset {0}. {1} + + + Unexpected closing brace without a corresponding opening brace. + + + Format item ends prematurely. + + + Expected an ASCII digit. + There must be at least a partial date with a year present in the input string '{0}'. @@ -4043,6 +4055,15 @@ AssemblyName.GetAssemblyName() is not supported on this platform. + + CompareOptions = {0} are not supported when HybridGlobalization=true. Disable it to load larger ICU bundle, then use this option. + + + CompareOptions = {0} are not supported for culture = {1} when HybridGlobalization=true. Disable it to load larger ICU bundle, then use this option. + + + Match length calculation is not supported when HybridGlobalization=true. Disable it to load larger ICU bundle, then use this function. + Arrays with non-zero lower bounds are not supported. diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 3c20e81baf9d4b..f4cec1a72c65b4 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -406,28 +406,28 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -646,6 +646,7 @@ + @@ -749,6 +750,7 @@ + @@ -931,6 +933,7 @@ + @@ -1068,6 +1071,7 @@ + @@ -2442,6 +2446,7 @@ + @@ -2466,6 +2471,7 @@ + @@ -2525,12 +2531,13 @@ - + - + + diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/StandardFormat.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/StandardFormat.cs index 91dca61b2415a3..9a738100d8b7b9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/StandardFormat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/StandardFormat.cs @@ -40,6 +40,9 @@ namespace System.Buffers /// public bool HasPrecision => _precision != NoPrecision; + /// Gets the precision if one was specified; otherwise, 0. + internal byte PrecisionOrZero => _precision != NoPrecision ? _precision : (byte)0; + /// /// true if the StandardFormat == default(StandardFormat) /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Decoder.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Decoder.cs index cc239d1a5e981a..2899c7d1021bfc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Decoder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Decoder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -350,6 +351,7 @@ public static unsafe OperationStatus DecodeFromUtf8InPlace(Span buffer, ou } } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe void Avx2Decode(ref byte* srcBytes, ref byte* destBytes, byte* srcEnd, int sourceLength, int destLength, byte* srcStart, byte* destStart) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Encoder.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Encoder.cs index 9a5ff88eb583f1..83fe75aef335d1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Encoder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Encoder.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -225,6 +226,7 @@ public static unsafe OperationStatus EncodeToUtf8InPlace(Span buffer, int } } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe void Avx2Encode(ref byte* srcBytes, ref byte* destBytes, byte* srcEnd, int sourceLength, int destLength, byte* srcStart, byte* destStart) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs index 303383a097e33b..0a55ad664ab270 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.CompilerServices; + namespace System.Buffers.Text { /// @@ -30,7 +32,7 @@ public static partial class Utf8Formatter /// System.FormatException if the format is not valid for this data type. /// public static bool TryFormat(byte value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + TryFormat((uint)value, destination, out bytesWritten, format); /// /// Formats an SByte as a UTF8 string. @@ -55,7 +57,7 @@ public static bool TryFormat(byte value, Span destination, out int bytesWr /// [CLSCompliant(false)] public static bool TryFormat(sbyte value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + TryFormat(value, 0xFF, destination, out bytesWritten, format); /// /// Formats a Unt16 as a UTF8 string. @@ -80,7 +82,7 @@ public static bool TryFormat(sbyte value, Span destination, out int bytesW /// [CLSCompliant(false)] public static bool TryFormat(ushort value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + TryFormat((uint)value, destination, out bytesWritten, format); /// /// Formats an Int16 as a UTF8 string. @@ -104,7 +106,7 @@ public static bool TryFormat(ushort value, Span destination, out int bytes /// System.FormatException if the format is not valid for this data type. /// public static bool TryFormat(short value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + TryFormat(value, 0xFFFF, destination, out bytesWritten, format); /// /// Formats a UInt32 as a UTF8 string. @@ -127,9 +129,38 @@ public static bool TryFormat(short value, Span destination, out int bytesW /// /// System.FormatException if the format is not valid for this data type. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] - public static bool TryFormat(uint value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + public static bool TryFormat(uint value, Span destination, out int bytesWritten, StandardFormat format = default) + { + if (format.IsDefault) + { + return Number.TryUInt32ToDecStr(value, destination, out bytesWritten); + } + + switch (format.Symbol | 0x20) + { + case 'd': + return Number.TryUInt32ToDecStr(value, format.PrecisionOrZero, destination, out bytesWritten); + + case 'x': + return Number.TryInt32ToHexStr((int)value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + + case 'n': + return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + + case 'g' or 'r': + if (format.HasPrecision) + { + ThrowGWithPrecisionNotSupported(); + } + goto case 'd'; + + default: + ThrowHelper.ThrowFormatException_BadFormatSpecifier(); + goto case 'd'; + } + } /// /// Formats an Int32 as a UTF8 string. @@ -153,7 +184,43 @@ public static bool TryFormat(uint value, Span destination, out int bytesWr /// System.FormatException if the format is not valid for this data type. /// public static bool TryFormat(int value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + TryFormat(value, ~0, destination, out bytesWritten, format); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool TryFormat(int value, int hexMask, Span destination, out int bytesWritten, StandardFormat format = default) + { + if (format.IsDefault) + { + return value >= 0 ? + Number.TryUInt32ToDecStr((uint)value, destination, out bytesWritten) : + Number.TryNegativeInt32ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + } + + switch (format.Symbol | 0x20) + { + case 'd': + return value >= 0 ? + Number.TryUInt32ToDecStr((uint)value, format.PrecisionOrZero, destination, out bytesWritten) : + Number.TryNegativeInt32ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + + case 'x': + return Number.TryInt32ToHexStr(value & hexMask, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + + case 'n': + return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + + case 'g' or 'r': + if (format.HasPrecision) + { + ThrowGWithPrecisionNotSupported(); + } + goto case 'd'; + + default: + ThrowHelper.ThrowFormatException_BadFormatSpecifier(); + goto case 'd'; + } + } /// /// Formats a UInt64 as a UTF8 string. @@ -176,9 +243,38 @@ public static bool TryFormat(int value, Span destination, out int bytesWri /// /// System.FormatException if the format is not valid for this data type. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] - public static bool TryFormat(ulong value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + public static bool TryFormat(ulong value, Span destination, out int bytesWritten, StandardFormat format = default) + { + if (format.IsDefault) + { + return Number.TryUInt64ToDecStr(value, destination, out bytesWritten); + } + + switch (format.Symbol | 0x20) + { + case 'd': + return Number.TryUInt64ToDecStr(value, format.PrecisionOrZero, destination, out bytesWritten); + + case 'x': + return Number.TryInt64ToHexStr((long)value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + + case 'n': + return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + + case 'g' or 'r': + if (format.HasPrecision) + { + ThrowGWithPrecisionNotSupported(); + } + goto case 'd'; + + default: + ThrowHelper.ThrowFormatException_BadFormatSpecifier(); + goto case 'd'; + } + } /// /// Formats an Int64 as a UTF8 string. @@ -201,7 +297,44 @@ public static bool TryFormat(ulong value, Span destination, out int bytesW /// /// System.FormatException if the format is not valid for this data type. /// - public static bool TryFormat(long value, Span destination, out int bytesWritten, StandardFormat format = default) => - FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryFormat(long value, Span destination, out int bytesWritten, StandardFormat format = default) + { + if (format.IsDefault) + { + return value >= 0 ? + Number.TryUInt64ToDecStr((ulong)value, destination, out bytesWritten) : + Number.TryNegativeInt64ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + } + + switch (format.Symbol | 0x20) + { + case 'd': + return value >= 0 ? + Number.TryUInt64ToDecStr((ulong)value, format.PrecisionOrZero, destination, out bytesWritten) : + Number.TryNegativeInt64ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + + case 'x': + return Number.TryInt64ToHexStr(value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + + case 'n': + return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); + + case 'g' or 'r': + if (format.HasPrecision) + { + ThrowGWithPrecisionNotSupported(); + } + goto case 'd'; + + default: + ThrowHelper.ThrowFormatException_BadFormatSpecifier(); + goto case 'd'; + } + } + + private static void ThrowGWithPrecisionNotSupported() => + // With a precision, 'G' can produce exponential format, even for integers. + throw new NotSupportedException(SR.Argument_GWithPrecisionNotSupported); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs b/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs index 4c0d3848a6ee84..0778294c8f1e94 100644 --- a/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs @@ -56,6 +56,17 @@ public int Indent /// public override Task FlushAsync() => _writer.FlushAsync(); + /// + /// Clears all buffers for this asynchronously and causes any buffered data to be + /// written to the underlying device. + /// + /// The to monitor for cancellation requests. + /// A representing the asynchronous flush operation. + public override Task FlushAsync(CancellationToken cancellationToken) => + cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : + GetType() != typeof(IndentedTextWriter) ? FlushAsync() : + _writer.FlushAsync(cancellationToken); + protected virtual void OutputTabs() { if (_tabsPending) diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index 0967438585c4e9..c351d4dbf303be 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -74,51 +74,9 @@ public enum Base64FormattingOptions public static partial class Convert { - // A typeof operation is fairly expensive (does a system call), so we'll cache these here - // statically. These are exactly lined up with the TypeCode, eg. ConvertType[TypeCode.Int16] - // will give you the type of an short. - internal static readonly Type[] ConvertTypes = { - typeof(System.Empty), - typeof(object), - typeof(System.DBNull), - typeof(bool), - typeof(char), - typeof(sbyte), - typeof(byte), - typeof(short), - typeof(ushort), - typeof(int), - typeof(uint), - typeof(long), - typeof(ulong), - typeof(float), - typeof(double), - typeof(decimal), - typeof(DateTime), - typeof(object), // TypeCode is discontinuous so we need a placeholder. - typeof(string) - }; - - // Need to special case Enum because typecode will be underlying type, e.g. Int32 - private static readonly Type EnumType = typeof(Enum); - private const int Base64LineBreakPosition = 76; private const int Base64VectorizationLengthThreshold = 16; -#if DEBUG - static Convert() - { - Debug.Assert(ConvertTypes != null, "[Convert.cctor]ConvertTypes!=null"); - Debug.Assert(ConvertTypes.Length == ((int)TypeCode.String + 1), "[Convert.cctor]ConvertTypes.Length == ((int)TypeCode.String + 1)"); - Debug.Assert(ConvertTypes[(int)TypeCode.Empty] == typeof(System.Empty), - "[Convert.cctor]ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty)"); - Debug.Assert(ConvertTypes[(int)TypeCode.String] == typeof(string), - "[Convert.cctor]ConvertTypes[(int)TypeCode.String]==typeof(System.String)"); - Debug.Assert(ConvertTypes[(int)TypeCode.Int32] == typeof(int), - "[Convert.cctor]ConvertTypes[(int)TypeCode.Int32]==typeof(int)"); - } -#endif - // Constant representing the database null value. This value is used in // database applications to indicate the absence of a known value. Note // that Convert.DBNull is NOT the same as a null object reference, which is @@ -223,44 +181,44 @@ internal static object DefaultToType(IConvertible value, Type targetType, IForma return value; } - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Boolean])) + if (ReferenceEquals(targetType, typeof(bool))) return value.ToBoolean(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Char])) + if (ReferenceEquals(targetType, typeof(char))) return value.ToChar(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.SByte])) + if (ReferenceEquals(targetType, typeof(sbyte))) return value.ToSByte(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Byte])) + if (ReferenceEquals(targetType, typeof(byte))) return value.ToByte(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int16])) + if (ReferenceEquals(targetType, typeof(short))) return value.ToInt16(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt16])) + if (ReferenceEquals(targetType, typeof(ushort))) return value.ToUInt16(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int32])) + if (ReferenceEquals(targetType, typeof(int))) return value.ToInt32(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt32])) + if (ReferenceEquals(targetType, typeof(uint))) return value.ToUInt32(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int64])) + if (ReferenceEquals(targetType, typeof(long))) return value.ToInt64(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt64])) + if (ReferenceEquals(targetType, typeof(ulong))) return value.ToUInt64(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Single])) + if (ReferenceEquals(targetType, typeof(float))) return value.ToSingle(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Double])) + if (ReferenceEquals(targetType, typeof(double))) return value.ToDouble(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Decimal])) + if (ReferenceEquals(targetType, typeof(decimal))) return value.ToDecimal(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DateTime])) + if (ReferenceEquals(targetType, typeof(DateTime))) return value.ToDateTime(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.String])) + if (ReferenceEquals(targetType, typeof(string))) return value.ToString(provider); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Object])) + if (ReferenceEquals(targetType, typeof(object))) return (object)value; // Need to special case Enum because typecode will be underlying type, e.g. Int32 - if (ReferenceEquals(targetType, EnumType)) + if (ReferenceEquals(targetType, typeof(Enum))) return (Enum)value; - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DBNull])) + if (ReferenceEquals(targetType, typeof(DBNull))) throw new InvalidCastException(SR.InvalidCast_DBNull); - if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Empty])) + if (ReferenceEquals(targetType, typeof(Empty))) throw new InvalidCastException(SR.InvalidCast_Empty); throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, value.GetType().FullName, targetType.FullName)); @@ -295,37 +253,37 @@ internal static object DefaultToType(IConvertible value, Type targetType, IForma throw new InvalidCastException(SR.InvalidCast_IConvertible); } - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Boolean])) + if (ReferenceEquals(conversionType, typeof(bool))) return ic.ToBoolean(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Char])) + if (ReferenceEquals(conversionType, typeof(char))) return ic.ToChar(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.SByte])) + if (ReferenceEquals(conversionType, typeof(sbyte))) return ic.ToSByte(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Byte])) + if (ReferenceEquals(conversionType, typeof(byte))) return ic.ToByte(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int16])) + if (ReferenceEquals(conversionType, typeof(short))) return ic.ToInt16(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt16])) + if (ReferenceEquals(conversionType, typeof(ushort))) return ic.ToUInt16(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int32])) + if (ReferenceEquals(conversionType, typeof(int))) return ic.ToInt32(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt32])) + if (ReferenceEquals(conversionType, typeof(uint))) return ic.ToUInt32(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int64])) + if (ReferenceEquals(conversionType, typeof(long))) return ic.ToInt64(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt64])) + if (ReferenceEquals(conversionType, typeof(ulong))) return ic.ToUInt64(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Single])) + if (ReferenceEquals(conversionType, typeof(float))) return ic.ToSingle(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Double])) + if (ReferenceEquals(conversionType, typeof(double))) return ic.ToDouble(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Decimal])) + if (ReferenceEquals(conversionType, typeof(decimal))) return ic.ToDecimal(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.DateTime])) + if (ReferenceEquals(conversionType, typeof(DateTime))) return ic.ToDateTime(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.String])) + if (ReferenceEquals(conversionType, typeof(string))) return ic.ToString(provider); - if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Object])) + if (ReferenceEquals(conversionType, typeof(object))) return (object)value; return ic.ToType(conversionType, provider); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs index d4363b3ad1670b..0496d93cae1967 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs @@ -13,8 +13,8 @@ public partial class CompareInfo { // Characters which require special handling are those in [0x00, 0x1F] and [0x7F, 0xFFFF] except \t\v\f // Matches HighCharTable below. - private static readonly IndexOfAnyValues s_nonSpecialAsciiChars = - IndexOfAnyValues.Create("\t\v\f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); + private static readonly SearchValues s_nonSpecialAsciiChars = + SearchValues.Create("\t\v\f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); [NonSerialized] private bool _isAsciiEqualityOrdinal; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs index 3ca001a9573bd4..474935f9ace316 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs @@ -8,21 +8,37 @@ namespace System.Globalization { public partial class CompareInfo { - private unsafe int JsCompareString(ReadOnlySpan string1, ReadOnlySpan string2, CompareOptions options) + private static void AssertHybridOnWasm(CompareOptions options) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert(GlobalizationMode.Hybrid); Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + } - + private static void AssertComparisonSupported(CompareOptions options, string cultureName) + { if (CompareOptionsNotSupported(options)) throw new PlatformNotSupportedException(GetPNSE(options)); - string cultureName = m_name; + if (CompareOptionsNotSupportedForCulture(options, cultureName)) + throw new PlatformNotSupportedException(GetPNSEForCulture(options, cultureName)); + } + + private static void AssertIndexingSupported(CompareOptions options, string cultureName) + { + if (IndexingOptionsNotSupported(options) || CompareOptionsNotSupported(options)) + throw new PlatformNotSupportedException(GetPNSE(options)); if (CompareOptionsNotSupportedForCulture(options, cultureName)) throw new PlatformNotSupportedException(GetPNSEForCulture(options, cultureName)); + } + + private unsafe int JsCompareString(ReadOnlySpan string1, ReadOnlySpan string2, CompareOptions options) + { + AssertHybridOnWasm(options); + string cultureName = m_name; + AssertComparisonSupported(options, cultureName); string exceptionMessage; int cmpResult; @@ -38,14 +54,57 @@ private unsafe int JsCompareString(ReadOnlySpan string1, ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) + { + AssertHybridOnWasm(options); + Debug.Assert(!prefix.IsEmpty); + string cultureName = m_name; + AssertIndexingSupported(options, cultureName); + + string exceptionMessage; + bool result; + fixed (char* pSource = &MemoryMarshal.GetReference(source)) + fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) + { + result = Interop.JsGlobalization.StartsWith(out exceptionMessage, cultureName, pSource, source.Length, pPrefix, prefix.Length, options); + } + + if (!string.IsNullOrEmpty(exceptionMessage)) + throw new Exception(exceptionMessage); + + return result; + } + + private unsafe bool JsEndsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) + { + AssertHybridOnWasm(options); + Debug.Assert(!prefix.IsEmpty); + string cultureName = m_name; + AssertIndexingSupported(options, cultureName); + + string exceptionMessage; + bool result; + fixed (char* pSource = &MemoryMarshal.GetReference(source)) + fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) + { + result = Interop.JsGlobalization.EndsWith(out exceptionMessage, cultureName, pSource, source.Length, pPrefix, prefix.Length, options); + } + + if (!string.IsNullOrEmpty(exceptionMessage)) + throw new Exception(exceptionMessage); + + return result; + } + + private static bool IndexingOptionsNotSupported(CompareOptions options) => + (options & CompareOptions.IgnoreSymbols) == CompareOptions.IgnoreSymbols; + private static bool CompareOptionsNotSupported(CompareOptions options) => (options & CompareOptions.IgnoreWidth) == CompareOptions.IgnoreWidth || ((options & CompareOptions.IgnoreNonSpace) == CompareOptions.IgnoreNonSpace && (options & CompareOptions.IgnoreKanaType) != CompareOptions.IgnoreKanaType); - private static string GetPNSE(CompareOptions options) => - $"CompareOptions = {options} are not supported when HybridGlobalization=true. Disable it to load larger ICU bundle, then use this option."; - + SR.Format(SR.PlatformNotSupported_HybridGlobalizationWithCompareOptions, options); private static bool CompareOptionsNotSupportedForCulture(CompareOptions options, string cultureName) => (options == CompareOptions.IgnoreKanaType && @@ -53,8 +112,7 @@ private static bool CompareOptionsNotSupportedForCulture(CompareOptions options, (options == CompareOptions.None && (cultureName.Split('-')[0] == "ja")); - private static string GetPNSEForCulture(CompareOptions options, string cultureName) => - $"CompareOptions = {options} are not supported for culture = {cultureName} when HybridGlobalization=true. Disable it to load larger ICU bundle, then use this option."; + SR.Format(SR.PlatformNotSupported_HybridGlobalizationWithCompareOptions, options, cultureName); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs index 3a3a5ba9553751..f205901e6d4ba3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs @@ -612,7 +612,12 @@ public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix else { // Linguistic comparison requested and we don't need to special-case any args. - +#if TARGET_BROWSER + if (GlobalizationMode.Hybrid) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); + } +#endif int tempMatchLength = 0; matched = StartsWithCore(source, prefix, options, &tempMatchLength); matchLength = tempMatchLength; @@ -624,6 +629,10 @@ public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix private unsafe bool StartsWithCore(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? NlsStartsWith(source, prefix, options, matchLengthPtr) : +#if TARGET_BROWSER + GlobalizationMode.Hybrid ? + JsStartsWith(source, prefix, options) : +#endif IcuStartsWith(source, prefix, options, matchLengthPtr); public bool IsPrefix(string source, string prefix) @@ -750,7 +759,12 @@ public unsafe bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix else { // Linguistic comparison requested and we don't need to special-case any args. - +#if TARGET_BROWSER + if (GlobalizationMode.Hybrid) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); + } +#endif int tempMatchLength = 0; matched = EndsWithCore(source, suffix, options, &tempMatchLength); matchLength = tempMatchLength; @@ -767,6 +781,10 @@ public bool IsSuffix(string source, string suffix) private unsafe bool EndsWithCore(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? NlsEndsWith(source, suffix, options, matchLengthPtr) : +#if TARGET_BROWSER + GlobalizationMode.Hybrid ? + JsEndsWith(source, suffix, options) : +#endif IcuEndsWith(source, suffix, options, matchLengthPtr); /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs index 5f539984d7b4f3..270b580e4178bf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs @@ -4354,7 +4354,7 @@ private static bool ParseByFormat( for (int i = 0; i < quotedSpan.Length; i++) { - if (quotedSpan[i] == ' ' && parseInfo.fAllowInnerWhite) + if (parseInfo.fAllowInnerWhite && char.IsWhiteSpace(quotedSpan[i])) { str.SkipWhiteSpaces(); } @@ -4430,64 +4430,41 @@ private static bool ParseByFormat( } break; default: - if (ch == ' ') + if (parseInfo.fAllowInnerWhite && char.IsWhiteSpace(ch)) { - if (parseInfo.fAllowInnerWhite) - { - // Skip whitespaces if AllowInnerWhite. - // Do nothing here. - } - else + // Skip whitespaces if AllowInnerWhite. + // Do nothing here. + } + else if (format.MatchSpecifiedWord(GMTName)) + { + format.Index += (GMTName.Length - 1); + // Found GMT string in format. This means the DateTime string + // is in GMT timezone. + result.flags |= ParseFlags.TimeZoneUsed; + result.timeZoneOffset = TimeSpan.Zero; + if (!str.Match(GMTName)) { - if (!str.Match(ch)) - { - // If the space does not match, and trailing space is allowed, we do - // one more step to see if the next format character can lead to - // successful parsing. - // This is used to deal with special case that a empty string can match - // a specific pattern. - // The example here is af-ZA, which has a time format like "hh:mm:ss tt". However, - // its AM symbol is "" (empty string). If fAllowTrailingWhite is used, and time is in - // the AM, we will trim the whitespaces at the end, which will lead to a failure - // when we are trying to match the space before "tt". - if (parseInfo.fAllowTrailingWhite) - { - if (format.GetNext()) - { - if (ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) - { - return true; - } - } - } - result.SetBadDateTimeFailure(); - return false; - } - // Found a macth. + result.SetBadDateTimeFailure(); + return false; } } - else + else if (!str.Match(ch)) { - if (format.MatchSpecifiedWord(GMTName)) + if (parseInfo.fAllowTrailingWhite && char.IsWhiteSpace(ch)) { - format.Index += (GMTName.Length - 1); - // Found GMT string in format. This means the DateTime string - // is in GMT timezone. - result.flags |= ParseFlags.TimeZoneUsed; - result.timeZoneOffset = TimeSpan.Zero; - if (!str.Match(GMTName)) + if (format.GetNext()) { - result.SetBadDateTimeFailure(); - return false; + if (ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) + { + return true; + } } } - else if (!str.Match(ch)) - { - // ch is expected. - result.SetBadDateTimeFailure(); - return false; - } + // ch is expected. + result.SetBadDateTimeFailure(); + return false; } + // Found a match. break; } // switch return true; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs index 36fa86bb048862..6a89be15731f69 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs @@ -2,10 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Text.Unicode; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Text.Unicode; namespace System.Globalization { @@ -295,7 +297,6 @@ internal static int IndexOfOrdinalIgnoreCase(ReadOnlySpan source, ReadOnly // A non-linguistic search compares chars directly against one another, so large // target strings can never be found inside small search spaces. This check also // handles empty 'source' spans. - return -1; } @@ -309,25 +310,38 @@ internal static int IndexOfOrdinalIgnoreCase(ReadOnlySpan source, ReadOnly return CompareInfo.NlsIndexOfOrdinalCore(source, value, ignoreCase: true, fromBeginning: true); } - // If value starts with an ASCII char, we can use a vectorized path + // If value doesn't start with ASCII, fall back to a non-vectorized non-ASCII friendly version. ref char valueRef = ref MemoryMarshal.GetReference(value); char valueChar = valueRef; - if (!char.IsAscii(valueChar)) { - // Fallback to a more non-ASCII friendly version return OrdinalCasing.IndexOf(source, value); } // Hoist some expressions from the loop int valueTailLength = value.Length - 1; - int searchSpaceLength = source.Length - valueTailLength; + int searchSpaceMinusValueTailLength = source.Length - valueTailLength; ref char searchSpace = ref MemoryMarshal.GetReference(source); char valueCharU = default; char valueCharL = default; nint offset = 0; bool isLetter = false; + // If the input is long enough and the value ends with ASCII, we can take a special vectorized + // path that compares both the beginning and the end at the same time. + if (Vector128.IsHardwareAccelerated && searchSpaceMinusValueTailLength >= Vector128.Count) + { + valueCharU = Unsafe.Add(ref valueRef, valueTailLength); + if (char.IsAscii(valueCharU)) + { + goto SearchTwoChars; + } + } + + // We're searching for the first character and it's known to be ASCII. If it's not a letter, + // then IgnoreCase doesn't impact what it matches and we just need to do a normal search + // for that single character. If it is a letter, then we need to search for both its upper + // and lower-case variants. if (char.IsAsciiLetter(valueChar)) { valueCharU = (char)(valueChar & ~0x20); @@ -340,16 +354,16 @@ internal static int IndexOfOrdinalIgnoreCase(ReadOnlySpan source, ReadOnly // Do a quick search for the first element of "value". int relativeIndex = isLetter ? PackedSpanHelpers.PackedIndexOfIsSupported - ? PackedSpanHelpers.IndexOfAny(ref Unsafe.Add(ref searchSpace, offset), valueCharU, valueCharL, searchSpaceLength) - : SpanHelpers.IndexOfAnyChar(ref Unsafe.Add(ref searchSpace, offset), valueCharU, valueCharL, searchSpaceLength) : - SpanHelpers.IndexOfChar(ref Unsafe.Add(ref searchSpace, offset), valueChar, searchSpaceLength); + ? PackedSpanHelpers.IndexOfAny(ref Unsafe.Add(ref searchSpace, offset), valueCharU, valueCharL, searchSpaceMinusValueTailLength) + : SpanHelpers.IndexOfAnyChar(ref Unsafe.Add(ref searchSpace, offset), valueCharU, valueCharL, searchSpaceMinusValueTailLength) : + SpanHelpers.IndexOfChar(ref Unsafe.Add(ref searchSpace, offset), valueChar, searchSpaceMinusValueTailLength); if (relativeIndex < 0) { break; } - searchSpaceLength -= relativeIndex; - if (searchSpaceLength <= 0) + searchSpaceMinusValueTailLength -= relativeIndex; + if (searchSpaceMinusValueTailLength <= 0) { break; } @@ -364,12 +378,185 @@ ref Unsafe.Add(ref valueRef, 1), valueTailLength)) return (int)offset; // The tail matched. Return a successful find. } - searchSpaceLength--; + searchSpaceMinusValueTailLength--; offset++; } - while (searchSpaceLength > 0); + while (searchSpaceMinusValueTailLength > 0); return -1; + + // Based on SpanHelpers.IndexOf(ref char, int, ref char, int), which was in turn based on + // http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd. This version has additional + // modifications to support case-insensitive searches. + SearchTwoChars: + // Both the first character in value (valueChar) and the last character in value (valueCharU) are ASCII. Get their lowercase variants. + valueChar = (char)(valueChar | 0x20); + valueCharU = (char)(valueCharU | 0x20); + + // The search is more efficient if the two characters being searched for are different. As long as they are equal, walk backwards + // from the last character in the search value until we find a character that's different. Since we're dealing with IgnoreCase, + // we compare the lowercase variants, as that's what we'll be comparing against in the main loop. + nint ch1ch2Distance = valueTailLength; + while (valueCharU == valueChar && ch1ch2Distance > 1) + { + char tmp = Unsafe.Add(ref valueRef, ch1ch2Distance - 1); + if (!char.IsAscii(tmp)) + { + break; + } + --ch1ch2Distance; + valueCharU = (char)(tmp | 0x20); + } + + // Use Vector256 if the input is long enough. + if (Vector256.IsHardwareAccelerated && searchSpaceMinusValueTailLength - Vector256.Count >= 0) + { + // Create a vector for each of the lowercase ASCII characters we're searching for. + Vector256 ch1 = Vector256.Create((ushort)valueChar); + Vector256 ch2 = Vector256.Create((ushort)valueCharU); + + nint searchSpaceMinusValueTailLengthAndVector = searchSpaceMinusValueTailLength - (nint)Vector256.Count; + do + { + // Make sure we don't go out of bounds. + Debug.Assert(offset + ch1ch2Distance + Vector256.Count <= source.Length); + + // Load a vector from the current search space offset and another from the offset plus the distance between the two characters. + // For each, | with 0x20 so that letters are lowercased, then & those together to get a mask. If the mask is all zeros, there + // was no match. If it wasn't, we have to do more work to check for a match. + Vector256 cmpCh2 = Vector256.Equals(ch2, Vector256.BitwiseOr(Vector256.LoadUnsafe(ref searchSpace, (nuint)(offset + ch1ch2Distance)), Vector256.Create((ushort)0x20))); + Vector256 cmpCh1 = Vector256.Equals(ch1, Vector256.BitwiseOr(Vector256.LoadUnsafe(ref searchSpace, (nuint)offset), Vector256.Create((ushort)0x20))); + Vector256 cmpAnd = (cmpCh1 & cmpCh2).AsByte(); + if (cmpAnd != Vector256.Zero) + { + goto CandidateFound; + } + + LoopFooter: + // No match. Advance to the next vector. + offset += Vector256.Count; + + // If we've reached the end of the search space, bail. + if (offset == searchSpaceMinusValueTailLength) + { + return -1; + } + + // If we're within a vector's length of the end of the search space, adjust the offset + // to point to the last vector so that our next iteration will process it. + if (offset > searchSpaceMinusValueTailLengthAndVector) + { + offset = searchSpaceMinusValueTailLengthAndVector; + } + + continue; + + CandidateFound: + // Possible matches at the current location. Extract the bits for each element. + // For each set bits, we'll check if it's a match at that location. + uint mask = cmpAnd.ExtractMostSignificantBits(); + do + { + // Do a full IgnoreCase equality comparison. SpanHelpers.IndexOf skips comparing the two characters in some cases, + // but we don't actually know that the two characters are equal, since we compared with | 0x20. So we just compare + // the full string always. + int bitPos = BitOperations.TrailingZeroCount(mask); + nint charPos = (nint)((uint)bitPos / 2); // div by 2 (shr) because we work with 2-byte chars + if (EqualsIgnoreCase(ref Unsafe.Add(ref searchSpace, offset + charPos), ref valueRef, value.Length)) + { + // Match! Return the index. + return (int)(offset + charPos); + } + + // Clear the two lowest set bits in the mask. If there are no more set bits, we're done. + // If any remain, we loop around to do the next comparison. + if (Bmi1.IsSupported) + { + mask = Bmi1.ResetLowestSetBit(Bmi1.ResetLowestSetBit(mask)); + } + else + { + mask &= ~(uint)(0b11 << bitPos); + } + } while (mask != 0); + goto LoopFooter; + + } while (true); + } + else // 128bit vector path (SSE2 or AdvSimd) + { + // Create a vector for each of the lowercase ASCII characters we're searching for. + Vector128 ch1 = Vector128.Create((ushort)valueChar); + Vector128 ch2 = Vector128.Create((ushort)valueCharU); + + nint searchSpaceMinusValueTailLengthAndVector = searchSpaceMinusValueTailLength - (nint)Vector128.Count; + do + { + // Make sure we don't go out of bounds. + Debug.Assert(offset + ch1ch2Distance + Vector128.Count <= source.Length); + + // Load a vector from the current search space offset and another from the offset plus the distance between the two characters. + // For each, | with 0x20 so that letters are lowercased, then & those together to get a mask. If the mask is all zeros, there + // was no match. If it wasn't, we have to do more work to check for a match. + Vector128 cmpCh2 = Vector128.Equals(ch2, Vector128.BitwiseOr(Vector128.LoadUnsafe(ref searchSpace, (nuint)(offset + ch1ch2Distance)), Vector128.Create((ushort)0x20))); + Vector128 cmpCh1 = Vector128.Equals(ch1, Vector128.BitwiseOr(Vector128.LoadUnsafe(ref searchSpace, (nuint)offset), Vector128.Create((ushort)0x20))); + Vector128 cmpAnd = (cmpCh1 & cmpCh2).AsByte(); + if (cmpAnd != Vector128.Zero) + { + goto CandidateFound; + } + + LoopFooter: + // No match. Advance to the next vector. + offset += Vector128.Count; + + // If we've reached the end of the search space, bail. + if (offset == searchSpaceMinusValueTailLength) + { + return -1; + } + + // If we're within a vector's length of the end of the search space, adjust the offset + // to point to the last vector so that our next iteration will process it. + if (offset > searchSpaceMinusValueTailLengthAndVector) + { + offset = searchSpaceMinusValueTailLengthAndVector; + } + + continue; + + CandidateFound: + // Possible matches at the current location. Extract the bits for each element. + // For each set bits, we'll check if it's a match at that location. + uint mask = cmpAnd.ExtractMostSignificantBits(); + do + { + // Do a full IgnoreCase equality comparison. SpanHelpers.IndexOf skips comparing the two characters in some cases, + // but we don't actually know that the two characters are equal, since we compared with | 0x20. So we just compare + // the full string always. + int bitPos = BitOperations.TrailingZeroCount(mask); + int charPos = (int)((uint)bitPos / 2); // div by 2 (shr) because we work with 2-byte chars + if (EqualsIgnoreCase(ref Unsafe.Add(ref searchSpace, offset + charPos), ref valueRef, value.Length)) + { + // Match! Return the index. + return (int)(offset + charPos); + } + + // Clear the two lowest set bits in the mask. If there are no more set bits, we're done. + // If any remain, we loop around to do the next comparison. + if (Bmi1.IsSupported) + { + mask = Bmi1.ResetLowestSetBit(Bmi1.ResetLowestSetBit(mask)); + } + else + { + mask &= ~(uint)(0b11 << bitPos); + } + } while (mask != 0); + goto LoopFooter; + + } while (true); + } } internal static int LastIndexOf(string source, string value, int startIndex, int count) diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index 12f2f11ce6f021..a42bca4c73dc07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.cs @@ -1052,6 +1052,7 @@ public int CompareTo(Guid value) public static bool operator !=(Guid a, Guid b) => !EqualsCore(a, b); + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe int HexsToChars(TChar* guidChars, int a, int b) where TChar : unmanaged, IUtfChar { guidChars[0] = TChar.CastFrom(HexConverter.ToCharLower(a >> 4)); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/File.cs b/src/libraries/System.Private.CoreLib/src/System/IO/File.cs index e512103a323762..45b2a91def3301 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/File.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/File.cs @@ -1078,12 +1078,10 @@ private static async Task InternalWriteAllLinesAsync(StreamWriter writer, IEnume { foreach (string line in contents) { - cancellationToken.ThrowIfCancellationRequested(); - await writer.WriteLineAsync(line).ConfigureAwait(false); + await writer.WriteLineAsync(line.AsMemory(), cancellationToken).ConfigureAwait(false); } - cancellationToken.ThrowIfCancellationRequested(); - await writer.FlushAsync().ConfigureAwait(false); + await writer.FlushAsync(cancellationToken).ConfigureAwait(false); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs index 5583c2c7f33961..df0c9e95cc6c05 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs @@ -888,26 +888,34 @@ public override Task WriteLineAsync(ReadOnlyMemory buffer, CancellationTok public override Task FlushAsync() { - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Flush() which a subclass might have overridden. To be safe - // we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Flush) when we are not sure. if (GetType() != typeof(StreamWriter)) { return base.FlushAsync(); } - // flushEncoder should be true at the end of the file and if - // the user explicitly calls Flush (though not if AutoFlush is true). - // This is required to flush any dangling characters from our UTF-7 - // and UTF-8 encoders. ThrowIfDisposed(); CheckAsyncTaskInProgress(); + return (_asyncWriteTask = FlushAsyncInternal(flushStream: true, flushEncoder: true, CancellationToken.None)); + } - Task task = FlushAsyncInternal(flushStream: true, flushEncoder: true); - _asyncWriteTask = task; + /// Clears all buffers for this stream asynchronously and causes any buffered data to be written to the underlying device. + /// The to monitor for cancellation requests. + /// A that represents the asynchronous flush operation. + public override Task FlushAsync(CancellationToken cancellationToken) + { + if (GetType() != typeof(StreamWriter)) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } - return task; + return FlushAsync(); + } + + ThrowIfDisposed(); + CheckAsyncTaskInProgress(); + return (_asyncWriteTask = FlushAsyncInternal(flushStream: true, flushEncoder: true, cancellationToken)); } private Task FlushAsyncInternal(bool flushStream, bool flushEncoder, CancellationToken cancellationToken = default) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs index b3d39eb292a737..e01444f8e91c77 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs @@ -652,6 +652,18 @@ public virtual Task FlushAsync() return Task.Factory.StartNew(static state => ((TextWriter)state!).Flush(), this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } + + /// + /// Asynchronously clears all buffers for the current writer and causes any buffered data to + /// be written to the underlying device. + /// + /// The to monitor for cancellation requests. + /// A that represents the asynchronous flush operation. + /// The text writer is disposed. + /// The writer is currently in use by a previous write operation. + public virtual Task FlushAsync(CancellationToken cancellationToken) => + cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : + FlushAsync(); #endregion private sealed class NullTextWriter : TextWriter @@ -665,6 +677,7 @@ internal NullTextWriter() { } public override void Flush() { } public override Task FlushAsync() => Task.CompletedTask; + public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask; public override void Write(char value) { } public override void Write(char[]? buffer) { } @@ -992,6 +1005,18 @@ public override Task FlushAsync() Flush(); return Task.CompletedTask; } + + [MethodImpl(MethodImplOptions.Synchronized)] + public override Task FlushAsync(CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + Flush(); + return Task.CompletedTask; + } } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs index d12bf4f4fae0ef..986644c4951aa0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs @@ -597,7 +597,7 @@ public static int IndexOfAnyExcept(this Span span, ReadOnlySpan values) /// If all of the values are in , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAnyExcept(this Span span, IndexOfAnyValues values) where T : IEquatable? => + public static int IndexOfAnyExcept(this Span span, SearchValues values) where T : IEquatable? => IndexOfAnyExcept((ReadOnlySpan)span, values); /// Searches for the first index of any value other than the specified . @@ -840,8 +840,8 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(values)), /// If all of the values are in , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAnyExcept(this ReadOnlySpan span, IndexOfAnyValues values) where T : IEquatable? => - IndexOfAnyValues.IndexOfAnyExcept(span, values); + public static int IndexOfAnyExcept(this ReadOnlySpan span, SearchValues values) where T : IEquatable? => + SearchValues.IndexOfAnyExcept(span, values); /// Searches for the last index of any value other than the specified . /// The type of the span and values. @@ -899,7 +899,7 @@ public static int LastIndexOfAnyExcept(this Span span, ReadOnlySpan val /// If all of the values are in , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAnyExcept(this Span span, IndexOfAnyValues values) where T : IEquatable? => + public static int LastIndexOfAnyExcept(this Span span, SearchValues values) where T : IEquatable? => LastIndexOfAnyExcept((ReadOnlySpan)span, values); /// Searches for the last index of any value other than the specified . @@ -1143,8 +1143,8 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(values)), /// If all of the values are in , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAnyExcept(this ReadOnlySpan span, IndexOfAnyValues values) where T : IEquatable? => - IndexOfAnyValues.LastIndexOfAnyExcept(span, values); + public static int LastIndexOfAnyExcept(this ReadOnlySpan span, SearchValues values) where T : IEquatable? => + SearchValues.LastIndexOfAnyExcept(span, values); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1688,7 +1688,7 @@ public static int IndexOfAny(this Span span, ReadOnlySpan values) where /// The span to search. /// The set of values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAny(this Span span, IndexOfAnyValues values) where T : IEquatable? => + public static int IndexOfAny(this Span span, SearchValues values) where T : IEquatable? => IndexOfAny((ReadOnlySpan)span, values); /// @@ -1877,8 +1877,8 @@ public static unsafe int IndexOfAny(this ReadOnlySpan span, ReadOnlySpanThe span to search. /// The set of values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAny(this ReadOnlySpan span, IndexOfAnyValues values) where T : IEquatable? => - IndexOfAnyValues.IndexOfAny(span, values); + public static int IndexOfAny(this ReadOnlySpan span, SearchValues values) where T : IEquatable? => + SearchValues.IndexOfAny(span, values); /// /// Searches for the last index of any of the specified values similar to calling LastIndexOf several times with the logical OR operator. If not found, returns -1. @@ -1962,7 +1962,7 @@ public static int LastIndexOfAny(this Span span, ReadOnlySpan values) w /// The span to search. /// The set of values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAny(this Span span, IndexOfAnyValues values) where T : IEquatable? => + public static int LastIndexOfAny(this Span span, SearchValues values) where T : IEquatable? => LastIndexOfAny((ReadOnlySpan)span, values); /// @@ -2151,8 +2151,8 @@ public static unsafe int LastIndexOfAny(this ReadOnlySpan span, ReadOnlySp /// The span to search. /// The set of values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAny(this ReadOnlySpan span, IndexOfAnyValues values) where T : IEquatable? => - IndexOfAnyValues.LastIndexOfAny(span, values); + public static int LastIndexOfAny(this ReadOnlySpan span, SearchValues values) where T : IEquatable? => + SearchValues.LastIndexOfAny(span, values); /// /// Determines whether two sequences are equal by comparing the elements using IEquatable{T}.Equals(T). diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs index 0a4d1ceaf65845..ed689b5d9ec774 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs @@ -907,7 +907,7 @@ private static bool TryCopyTo(string source, Span destination, out } } - private static char GetHexBase(char fmt) + internal static char GetHexBase(char fmt) { // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase. @@ -1675,7 +1675,7 @@ private static unsafe string NegativeInt32ToDecStr(int value, int digits, string return result; } - private static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); Debug.Assert(value < 0); @@ -1724,7 +1724,7 @@ private static unsafe string Int32ToHexStr(int value, char hexBase, int digits) return result; } - private static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); @@ -1999,7 +1999,7 @@ private static unsafe string UInt32ToDecStr(uint value, int digits) return result; } - private static unsafe bool TryUInt32ToDecStr(uint value, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryUInt32ToDecStr(uint value, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); @@ -2019,7 +2019,7 @@ private static unsafe bool TryUInt32ToDecStr(uint value, Span dest return false; } - private static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); @@ -2108,7 +2108,7 @@ private static unsafe string NegativeInt64ToDecStr(long value, int digits, strin return result; } - private static unsafe bool TryNegativeInt64ToDecStr(long value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryNegativeInt64ToDecStr(long value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); Debug.Assert(value < 0); @@ -2157,7 +2157,7 @@ private static unsafe string Int64ToHexStr(long value, char hexBase, int digits) return result; } - private static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); @@ -2427,7 +2427,7 @@ internal static unsafe string UInt64ToDecStr(ulong value, int digits) return result; } - private static unsafe bool TryUInt64ToDecStr(ulong value, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryUInt64ToDecStr(ulong value, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); @@ -2448,7 +2448,7 @@ private static unsafe bool TryUInt64ToDecStr(ulong value, Span des return false; } - private static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + internal static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar { int countedDigits = FormattingHelpers.CountDigits(value); int bufferLength = Math.Max(digits, countedDigits); diff --git a/src/libraries/System.Private.CoreLib/src/System/Random.Net5CompatImpl.cs b/src/libraries/System.Private.CoreLib/src/System/Random.Net5CompatImpl.cs index bb4cbae365b3ca..0a2dcba9c12645 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Random.Net5CompatImpl.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Random.Net5CompatImpl.cs @@ -83,7 +83,17 @@ private ulong NextUInt64() => public override double NextDouble() => _prng.Sample(); - public override float NextSingle() => (float)_prng.Sample(); + public override float NextSingle() + { + while (true) + { + float f = (float)_prng.Sample(); + if (f < 1.0f) // reject 1.0f, which is rare but possible due to rounding + { + return f; + } + } + } public override void NextBytes(byte[] buffer) => _prng.NextBytes(buffer); @@ -197,7 +207,14 @@ public override double NextDouble() public override float NextSingle() { _prng.EnsureInitialized(_seed); - return (float)_parent.Sample(); + while (true) + { + float f = (float)_parent.Sample(); + if (f < 1.0f) // reject 1.0f, which is rare but possible due to rounding + { + return f; + } + } } public override void NextBytes(byte[] buffer) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs index 9b581a305afdef..27ac00870c28a7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs @@ -25,7 +25,7 @@ public ConstructorInvoker(RuntimeConstructorInfo constructorInfo) } else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke) { - // Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing. + // Always use emit invoke (if IsDynamicCodeSupported == true); useful for testing. _invoked = true; } } @@ -53,7 +53,7 @@ public ConstructorInvoker(RuntimeConstructorInfo constructorInfo) } else { - if (RuntimeFeature.IsDynamicCodeCompiled) + if (RuntimeFeature.IsDynamicCodeSupported) { _invokeFunc = InvokerEmitUtil.CreateInvokeDelegate(_method); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs index 3abc6925b7a4af..2ce19ba7a7546b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs @@ -39,17 +39,15 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) SetCustomAttributeCore(con, binaryAttribute); } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); - [System.ObsoleteAttribute("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [RequiresAssemblyFiles(ThrowingMessageInRAF)] public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs index 3daac6f42875b0..82d95cb8c4f42c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs @@ -31,14 +31,21 @@ public ILGenerator GetILGenerator(int streamSize) protected abstract ILGenerator GetILGeneratorCore(int streamSize); public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - => SetCustomAttributeCore(con, binaryAttribute); + { + ArgumentNullException.ThrowIfNull(con); + ArgumentNullException.ThrowIfNull(binaryAttribute); + + SetCustomAttributeCore(con, binaryAttribute); + } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - => SetCustomAttributeCore(customBuilder); + { + ArgumentNullException.ThrowIfNull(customBuilder); - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); + } public void SetImplementationFlags(MethodImplAttributes attributes) => SetImplementationFlagsCore(attributes); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs index f3cdb7f848fb32..8017aabdcdb52c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs @@ -35,11 +35,9 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue) public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) => SetCustomAttributeCore(con, binaryAttribute); - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - => SetCustomAttributeCore(customBuilder); - - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); + => SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EventBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EventBuilder.cs index 4c4a8f09f6ed49..75b1a9e3606687 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EventBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EventBuilder.cs @@ -27,17 +27,15 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) SetCustomAttributeCore(con, binaryAttribute); } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); - public void SetRaiseMethod(MethodBuilder mdBuilder) => SetRaiseMethodCore(mdBuilder); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs index 26092610945625..1e879c09da292e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs @@ -22,17 +22,15 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) SetCustomAttributeCore(con, binaryAttribute); } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); - public void SetOffset(int iOffset) => SetOffsetCore(iOffset); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs index 3594991999021b..dfc38ba67ab088 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs @@ -13,17 +13,15 @@ protected GenericTypeParameterBuilder() public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) => SetCustomAttributeCore(con, binaryAttribute); - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); - public void SetBaseTypeConstraint([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? baseTypeConstraint) => SetBaseTypeConstraintCore(baseTypeConstraint); protected abstract void SetBaseTypeConstraintCore([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? baseTypeConstraint); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs index dab5cd525e029a..ef2c0cea25ab07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs @@ -56,17 +56,20 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) SetCustomAttributeCore(con, binaryAttribute); } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + internal void SetCustomAttribute(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + SetCustomAttributeCore(con, binaryAttribute); + } + + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); - public void SetImplementationFlags(MethodImplAttributes attributes) => SetImplementationFlagsCore(attributes); protected abstract void SetImplementationFlagsCore(MethodImplAttributes attributes); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs index 021ddd08ecd86e..21f68439ee3927 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs @@ -134,17 +134,15 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) SetCustomAttributeCore(con, binaryAttribute); } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); - public abstract int GetTypeMetadataToken(Type type); public abstract int GetFieldMetadataToken(FieldInfo field); public abstract int GetMethodMetadataToken(MethodInfo method); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs new file mode 100644 index 00000000000000..c7c7e81e95ff97 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.cs @@ -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. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace System.Reflection.Emit +{ + public abstract partial class ParameterBuilder + { + protected ParameterBuilder() { } + public virtual int Attributes => throw new NotImplementedException(); + public bool IsIn => ((ParameterAttributes)Attributes & ParameterAttributes.In) != 0; + public bool IsOptional => ((ParameterAttributes)Attributes & ParameterAttributes.Optional) != 0; + public bool IsOut => ((ParameterAttributes)Attributes & ParameterAttributes.Out) != 0; + public virtual string? Name => throw new NotImplementedException(); + public virtual int Position => throw new NotImplementedException(); + public virtual void SetConstant(object? defaultValue) => throw new NotImplementedException(); + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + ArgumentNullException.ThrowIfNull(con); + ArgumentNullException.ThrowIfNull(binaryAttribute); + + SetCustomAttributeCore(con, binaryAttribute); + } + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + ArgumentNullException.ThrowIfNull(customBuilder); + + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs index 924c40f948a128..43b948ac9b9449 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs @@ -27,15 +27,14 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) SetCustomAttributeCore(con, binaryAttribute); } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); - } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); + } public void SetGetMethod(MethodBuilder mdBuilder) => SetGetMethodCore(mdBuilder); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs index e715ac81fbb9d5..e3f3b9aa55b5d7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs @@ -277,17 +277,15 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) SetCustomAttributeCore(con, binaryAttribute); } - protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute); + protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute); public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { ArgumentNullException.ThrowIfNull(customBuilder); - SetCustomAttributeCore(customBuilder); + SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data); } - protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder); - public void SetParent([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent) => SetParentCore(parent); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/InvokerEmitUtil.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/InvokerEmitUtil.cs index 87bccf3173281f..c800f9e3ef02c0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/InvokerEmitUtil.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/InvokerEmitUtil.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection.Emit; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -64,15 +65,19 @@ public static unsafe InvokeFunc CreateInvokeDelegate(MethodBase method) } } - // Invoke the method. // For CallStack reasons, don't inline target method. + // Mono interpreter does not support\need this. + if (RuntimeFeature.IsDynamicCodeCompiled) + { #if MONO - il.Emit(OpCodes.Call, Methods.DisableInline()); + il.Emit(OpCodes.Call, Methods.DisableInline()); #else - il.Emit(OpCodes.Call, Methods.NextCallReturnAddress()); - il.Emit(OpCodes.Pop); + il.Emit(OpCodes.Call, Methods.NextCallReturnAddress()); + il.Emit(OpCodes.Pop); #endif + } + // Invoke the method. if (emitNew) { il.Emit(OpCodes.Newobj, (ConstructorInfo)method); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs index a33ca063fa8777..15a0c195308286 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs @@ -37,7 +37,7 @@ internal sealed partial class MethodInvoker } else { - if (RuntimeFeature.IsDynamicCodeCompiled) + if (RuntimeFeature.IsDynamicCodeSupported) { _invokeFunc = InvokerEmitUtil.CreateInvokeDelegate(_method); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs index 71138a8ebb7067..25cd61020bd910 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs @@ -141,8 +141,6 @@ internal sealed class CultureNameResourceSetPair // there yet because CultureInfo's class initializer hasn't finished. If we move SystemResMgr off of // Assembly (or at least make it an internal property) we should be able to circumvent this problem. - // This is our min required ResourceSet type. - private static readonly Type s_minResourceSet = typeof(ResourceSet); // These Strings are used to avoid using Reflection in CreateResourceSet. internal const string ResReaderTypeName = "System.Resources.ResourceReader"; internal const string ResSetTypeName = "System.Resources.RuntimeResourceSet"; @@ -212,7 +210,7 @@ public ResourceManager(string baseName, Assembly assembly, MainAssembly = assembly; BaseNameField = baseName; - if (usingResourceSet != null && (usingResourceSet != s_minResourceSet) && !usingResourceSet.IsSubclassOf(s_minResourceSet)) + if (usingResourceSet != null && (usingResourceSet != typeof(ResourceSet)) && !usingResourceSet.IsSubclassOf(typeof(ResourceSet))) throw new ArgumentException(SR.Arg_ResMgrNotResSet, nameof(usingResourceSet)); _userResourceSet = usingResourceSet; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/BypassReadyToRunAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/BypassReadyToRunAttribute.cs new file mode 100644 index 00000000000000..d4def4f9eadb8b --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/BypassReadyToRunAttribute.cs @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime +{ + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)] + internal sealed class BypassReadyToRunAttribute : Attribute + { + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CollectionsMarshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CollectionsMarshal.cs index 6a60224305a6b1..a54dc8405f1ab6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CollectionsMarshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CollectionsMarshal.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace System.Runtime.InteropServices { @@ -39,5 +40,40 @@ public static ref TValue GetValueRefOrNullRef(DictionaryItems should not be added to or removed from the while the ref is in use. public static ref TValue? GetValueRefOrAddDefault(Dictionary dictionary, TKey key, out bool exists) where TKey : notnull => ref Dictionary.CollectionsMarshalHelper.GetValueRefOrAddDefault(dictionary, key, out exists); + + /// + /// Sets the count of the to the specified value. + /// + /// The list to set the count of. + /// The value to set the list's count to. + /// + /// is . + /// + /// + /// is negative. + /// + /// + /// When increasing the count, uninitialized data is being exposed. + /// + public static void SetCount(List list, int count) + { + if (count < 0) + { + ThrowHelper.ThrowArgumentOutOfRangeException_NeedNonNegNum(nameof(count)); + } + + list._version++; + + if (count > list.Capacity) + { + list.Grow(count); + } + else if (count < list._size && RuntimeHelpers.IsReferenceOrContainsReferences()) + { + Array.Clear(list._items, count, list._size - count); + } + + list._size = count; + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs new file mode 100644 index 00000000000000..0e392d1535fd86 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs @@ -0,0 +1,199 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; + +namespace System.Runtime.InteropServices.Marshalling +{ + /// + /// A marshaller for -derived types that marshals the handle following the lifetime rules for s. + /// + /// The -derived type. + [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder), MarshalMode.ManagedToUnmanagedIn, typeof(SafeHandleMarshaller<>.ManagedToUnmanagedIn))] + [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder), MarshalMode.ManagedToUnmanagedRef, typeof(SafeHandleMarshaller<>.ManagedToUnmanagedRef))] + [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder), MarshalMode.ManagedToUnmanagedOut, typeof(SafeHandleMarshaller<>.ManagedToUnmanagedOut))] + public static class SafeHandleMarshaller<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> where T : SafeHandle + { + /// + /// Custom marshaller to marshal a as its underlying handle value. + /// + public struct ManagedToUnmanagedIn + { + private bool _addRefd; + private T? _handle; + + /// + /// Initializes the marshaller from a managed handle. + /// + /// The managed handle. + public void FromManaged(T handle) + { + _handle = handle; + handle.DangerousAddRef(ref _addRefd); + } + + /// + /// Get the unmanaged handle. + /// + /// The unmanaged handle. + public IntPtr ToUnmanaged() => _handle!.DangerousGetHandle(); + + /// + /// Release any references keeping the managed handle alive. + /// + public void Free() + { + if (_addRefd) + { + _handle!.DangerousRelease(); + } + } + } + + /// + /// Custom marshaller to marshal a as its underlying handle value. + /// + public struct ManagedToUnmanagedRef + { + private bool _addRefd; + private bool _callInvoked; + private T? _handle; + private IntPtr _originalHandleValue; + private T _newHandle; + private T? _handleToReturn; + + /// + /// Create the marshaller in a default state. + /// + public ManagedToUnmanagedRef() + { + _addRefd = false; + _callInvoked = false; + // SafeHandle ref marshalling has always required parameterless constructors, + // but it has never required them to be public. + // We construct the handle now to ensure we don't cause an exception + // before we are able to capture the unmanaged handle after the call. + _newHandle = Activator.CreateInstance()!; + } + + /// + /// Initialize the marshaller from a managed handle. + /// + /// The managed handle + public void FromManaged(T handle) + { + _handle = handle; + handle.DangerousAddRef(ref _addRefd); + _originalHandleValue = handle.DangerousGetHandle(); + } + + /// + /// Retrieve the unmanaged handle. + /// + /// The unmanaged handle + public IntPtr ToUnmanaged() => _originalHandleValue; + + /// + /// Initialize the marshaller from an unmanaged handle. + /// + /// The unmanaged handle. + public void FromUnmanaged(IntPtr value) + { + if (value == _originalHandleValue) + { + _handleToReturn = _handle; + } + else + { + Marshal.InitHandle(_newHandle, value); + _handleToReturn = _newHandle; + } + } + + /// + /// Notify the marshaller that the native call has been invoked. + /// + public void OnInvoked() + { + _callInvoked = true; + } + + /// + /// Retrieve the managed handle from the marshaller. + /// + /// The managed handle. + public T ToManagedFinally() => _handleToReturn!; + + /// + /// Free any resources and reference counts owned by the marshaller. + /// + public void Free() + { + if (_addRefd) + { + _handle!.DangerousRelease(); + } + + // If we never invoked the call, then we aren't going to use the + // new handle. Dispose it now to avoid clogging up the finalizer queue + // unnecessarily. + if (!_callInvoked) + { + _newHandle.Dispose(); + } + } + } + + /// + /// Custom marshaller to marshal a as its underlying handle value. + /// + public struct ManagedToUnmanagedOut + { + private bool _initialized; + private T _newHandle; + + /// + /// Create the marshaller in a default state. + /// + public ManagedToUnmanagedOut() + { + _initialized = false; + // SafeHandle out marshalling has always required parameterless constructors, + // but it has never required them to be public. + // We construct the handle now to ensure we don't cause an exception + // before we are able to capture the unmanaged handle after the call. + _newHandle = Activator.CreateInstance()!; + } + + /// + /// Initialize the marshaller from an unmanaged handle. + /// + /// The unmanaged handle. + public void FromUnmanaged(IntPtr value) + { + _initialized = true; + Marshal.InitHandle(_newHandle, value); + } + + /// + /// Retrieve the managed handle from the marshaller. + /// + /// The managed handle. + public T ToManaged() => _newHandle; + + /// + /// Free any resources and reference counts owned by the marshaller. + /// + public void Free() + { + // If we never captured the handle value, then we aren't going to use the + // new handle. Dispose it now to avoid clogging up the finalizer queue + // unnecessarily. + if (!_initialized) + { + _newHandle!.Dispose(); + } + } + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeHandle.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeHandle.cs index 93522077d0cdf6..ef8860aed8e79d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeHandle.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeHandle.cs @@ -256,7 +256,7 @@ private void InternalRelease(bool disposeOrFinalizeOperation) // If we get here we successfully decremented the ref count. Additionally we // may have decremented it to zero and set the handle state as closed. In - // this case (providng we own the handle) we will call the ReleaseHandle + // this case (providing we own the handle) we will call the ReleaseHandle // method on the SafeHandle subclass. if (performRelease) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs index d284f4221334d3..bd1192b7f1af50 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs @@ -123,6 +123,43 @@ public abstract class PackedSimd public static Vector128 AddPairwiseWidening(Vector128 value) { throw new PlatformNotSupportedException(); } public static Vector128 AddPairwiseWidening(Vector128 value) { throw new PlatformNotSupportedException(); } + // Saturating integer arithmetic + + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 MultiplyRoundedSaturateQ15(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + // Bit shifts public static Vector128 ShiftLeft(Vector128 value, int count) { throw new PlatformNotSupportedException(); } @@ -171,6 +208,99 @@ public abstract class PackedSimd public static Vector128 And(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } public static Vector128 And(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Or(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Not(Vector128 value) { throw new PlatformNotSupportedException(); } + + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw new PlatformNotSupportedException(); } + + public static Vector128 PopCount(Vector128 value) { throw new PlatformNotSupportedException(); } + + // Boolean horizontal reductions + + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AnyTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static bool AllTrue(Vector128 value) { throw new PlatformNotSupportedException(); } + public static int Bitmask(Vector128 value) { throw new PlatformNotSupportedException(); } public static int Bitmask(Vector128 value) { throw new PlatformNotSupportedException(); } public static int Bitmask(Vector128 value) { throw new PlatformNotSupportedException(); } @@ -182,6 +312,8 @@ public abstract class PackedSimd public static int Bitmask(Vector128 value) { throw new PlatformNotSupportedException(); } public static int Bitmask(Vector128 value) { throw new PlatformNotSupportedException(); } + // Comparisons + public static Vector128 CompareEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } public static Vector128 CompareEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } public static Vector128 CompareEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } @@ -208,6 +340,60 @@ public abstract class PackedSimd public static Vector128 CompareNotEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } public static Vector128 CompareNotEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + // Conversions + internal static Vector128 ConvertNarrowingSignedSaturate(Vector128 lower, Vector128 upper) { throw new PlatformNotSupportedException(); } internal static Vector128 ConvertNarrowingSignedSaturate(Vector128 lower, Vector128 upper) { throw new PlatformNotSupportedException(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs index d17d6164ef8598..2a9ac47545ad28 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs @@ -515,6 +515,127 @@ public abstract class PackedSimd [Intrinsic] public static Vector128 AddPairwiseWidening(Vector128 value) => AddPairwiseWidening(value); + // Saturating integer arithmetic + + /// + /// i8x16.add.sat.s + /// + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + /// + /// i8x16.add.sat.u + /// + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + /// + /// i16x8.add.sat.s + /// + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + /// + /// i16x8.add.sat.u + /// + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + + /// + /// i8x16.sub.sat.s + /// + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + /// + /// i8x16.sub.sat.u + /// + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + /// + /// i16x8.sub.sat.s + /// + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + /// + /// i16x8.sub.sat.u + /// + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + + /// + /// i16x8.q15mulr.sat.s + /// + public static Vector128 MultiplyRoundedSaturateQ15(Vector128 left, Vector128 right) => MultiplyRoundedSaturateQ15(left, right); + + /// + /// i8x16.min.s + /// + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i8x16.min.u + /// + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i16x8.min.s + /// + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i16x8.min.u + /// + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i32x4.min.s + /// + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i32x4.min.u + /// + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + + /// + /// i8x16.max.s + /// + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i8x16.max.u + /// + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i16x8.max.s + /// + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i16x8.max.u + /// + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i32x4.max.s + /// + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i32x4.max.u + /// + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + + /// + /// i8x16.avgr.u + /// + public static Vector128 AverageRounded(Vector128 left, Vector128 right) => AverageRounded(left, right); + /// + /// i16x8.avgr.u + /// + public static Vector128 AverageRounded(Vector128 left, Vector128 right) => AverageRounded(left, right); + + /// + /// i8x16.abs + /// + public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i16x8.abs + /// + public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i32x4.abs + /// + public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i64x2.abs + /// + public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i32x4.abs + /// + public static Vector128 Abs(Vector128 value) => Abs(value); + // Bit shifts /// @@ -733,6 +854,433 @@ public abstract class PackedSimd [Intrinsic] public static Vector128 And(Vector128 left, Vector128 right) => And(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + /// + /// v128.or + /// + [Intrinsic] + public static Vector128 Or(Vector128 left, Vector128 right) => Or(left, right); + + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + /// + /// v128.xor + /// + [Intrinsic] + public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + /// + /// v128.not + /// + [Intrinsic] + public static Vector128 Not(Vector128 value) => Not(value); + + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + /// + /// v128.andnot + /// + [Intrinsic] + public static Vector128 AndNot(Vector128 left, Vector128 right) => AndNot(left, right); + + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + /// + /// v128.bitselect + /// + [Intrinsic] + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) => BitwiseSelect(left, right, select); + + /// + /// i8x16.popcnt + /// + [Intrinsic] + public static Vector128 PopCount(Vector128 value) => PopCount(value); + + // Boolean horizontal reductions + + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + /// + /// v128.any_true + /// + [Intrinsic] + public static bool AnyTrue(Vector128 value) => AnyTrue(value); + + /// + /// i8x16.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i8x16.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i16x8.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i16x8.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i32x4.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i32x4.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i64x2.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i64x2.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i32x4.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + /// + /// i32x4.all_true + /// + [Intrinsic] + public static bool AllTrue(Vector128 value) => AllTrue(value); + + // Bitmask extraction + /// /// i8x16.bitmask /// @@ -784,6 +1332,8 @@ public abstract class PackedSimd [Intrinsic] public static int Bitmask(Vector128 value) => Bitmask(value); + // Comparisons + /// /// i8x16.eq /// @@ -906,6 +1456,251 @@ public abstract class PackedSimd [Intrinsic] public static Vector128 CompareNotEqual(Vector128 left, Vector128 right) => CompareNotEqual(left, right); + /// + /// i8x16.lt_s + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i8x16.lt_u + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i16x8.lt_s + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i16x8.lt_u + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i32x4.lt_s + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i32x4.lt_u + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i64x2.lt_s + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i64x2.lt_u + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// f32x4.lt + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// f64x2.lt + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i32x4.lt_s + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + /// + /// i32x4.lt_u + /// + [Intrinsic] + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) => CompareLessThan(left, right); + + /// + /// i8x16.le_s + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i8x16.le_u + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i16x8.le_s + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i16x8.le_u + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i32x4.le_s + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i32x4.le_u + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i64x2.le_s + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i64x2.le_u + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// f32x4.le + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// f64x2.le + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i32x4.le_s + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + /// + /// i32x4.le_u + /// + [Intrinsic] + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) => CompareLessThanOrEqual(left, right); + + /// + /// i8x16.gt_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i8x16.gt_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i16x8.gt_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i16x8.gt_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i32x4.gt_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i32x4.gt_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i64x2.gt_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i64x2.gt_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// f32x4.gt + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// f64x2.gt + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i32x4.gt_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + /// + /// i32x4.gt_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) => CompareGreaterThan(left, right); + + /// + /// i8x16.ge_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i8x16.ge_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i16x8.ge_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i16x8.ge_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i32x4.ge_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i32x4.ge_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i32x4.ge_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i64x2.ge_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// f32x4.ge + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// f64x2.ge + /// + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i32x4.ge_s + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + /// + /// i32x4.ge_u + /// + [Intrinsic] + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) => CompareGreaterThanOrEqual(left, right); + + // Conversions + /// /// i8x16.narrow_i16x8_s /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs index 0d93c5f5d6c4ff..4b6fcabee54e35 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs @@ -21,6 +21,143 @@ internal Avx512BW() { } internal VL() { } public static new bool IsSupported { [Intrinsic] get { return false; } } + + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtusepi16_epi8 (__m128i a) + /// VPMOVUWB xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtusepi16_epi8 (__m256i a) + /// VPMOVUWB xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtsepi16_epi8 (__m128i a) + /// VPMOVSWB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtsepi16_epi8 (__m256i a) + /// VPMOVSWB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_permutevar8x16_epi16 (__m128i a, __m128i b) + /// VPERMW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar8x16(Vector128 left, Vector128 control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_permutevar8x16_epi16 (__m128i a, __m128i b) + /// VPERMW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar8x16(Vector128 left, Vector128 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm256_permutevar16x16_epi16 (__m256i a, __m256i b) + /// VPERMW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar16x16(Vector256 left, Vector256 control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_permutevar16x16_epi16 (__m256i a, __m256i b) + /// VPERMW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar16x16(Vector256 left, Vector256 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_sllv_epi16 (__m128i a, __m128i count) + /// VPSLLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftLeftLogicalVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_sllv_epi16 (__m128i a, __m128i count) + /// VPSLLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftLeftLogicalVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_sllv_epi16 (__m256i a, __m256i count) + /// VPSLLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftLeftLogicalVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_sllv_epi16 (__m256i a, __m256i count) + /// VPSLLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftLeftLogicalVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_srav_epi16 (__m128i a, __m128i count) + /// VPSRAVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftRightArithmeticVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_srav_epi16 (__m256i a, __m256i count) + /// VPSRAVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftRightArithmeticVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_srlv_epi16 (__m128i a, __m128i count) + /// VPSRLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftRightLogicalVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_srlv_epi16 (__m128i a, __m128i count) + /// VPSRLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftRightLogicalVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_srlv_epi16 (__m256i a, __m256i count) + /// VPSRLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftRightLogicalVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_srlv_epi16 (__m256i a, __m256i count) + /// VPSRLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftRightLogicalVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } } public new abstract class X64 : Avx512F.X64 @@ -105,6 +242,59 @@ internal X64() { } /// public static Vector512 Average(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcastb_epi8 (__m128i a) + /// VPBROADCASTB zmm1 {k1}{z}, xmm2/m8 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcastb_epi8 (__m128i a) + /// VPBROADCASTB zmm1 {k1}{z}, xmm2/m8 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcastw_epi16 (__m128i a) + /// VPBROADCASTW zmm1 {k1}{z}, xmm2/m16 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcastw_epi16 (__m128i a) + /// VPBROADCASTW zmm1 {k1}{z}, xmm2/m16 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Byte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Byte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtusepi16_epi8 (__m512i a) + /// VPMOVUWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256ByteWithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256SByte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256SByte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtsepi16_epi8 (__m512i a) + /// VPMOVSWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256SByteWithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_cvtepi8_epi16 (__m128i a) /// VPMOVSXBW zmm1 {k1}{z}, ymm2/m256 @@ -250,6 +440,17 @@ internal X64() { } /// public static Vector512 PackUnsignedSaturate(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_permutevar32x16_epi16 (__m512i a, __m512i b) + /// VPERMW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar32x16(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_permutevar32x16_epi16 (__m512i a, __m512i b) + /// VPERMW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar32x16(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_sll_epi16 (__m512i a, __m128i count) /// VPSLLW zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -283,6 +484,17 @@ internal X64() { } /// public static Vector512 ShiftLeftLogical128BitLane(Vector512 value, [ConstantExpected] byte numBytes) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_sllv_epi16 (__m512i a, __m512i count) + /// VPSLLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_sllv_epi16 (__m512i a, __m512i count) + /// VPSLLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// /// _mm512_sra_epi16 (__m512i a, __m128i count) /// VPSRAW zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -295,6 +507,12 @@ internal X64() { } /// public static Vector512 ShiftRightArithmetic(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srav_epi16 (__m512i a, __m512i count) + /// VPSRAVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftRightArithmeticVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_srl_epi16 (__m512i a, __m128i count) /// VPSRLW zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -328,6 +546,17 @@ internal X64() { } /// public static Vector512 ShiftRightLogical128BitLane(Vector512 value, [ConstantExpected] byte numBytes) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srlv_epi16 (__m512i a, __m512i count) + /// VPSRLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srlv_epi16 (__m512i a, __m512i count) + /// VPSRLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_shuffle_epi8 (__m512i a, __m512i b) /// VPSHUFB zmm1 {k1}{z}, zmm2, zmm3/m512 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs index 01811c5a108dbf..79a3219fe4c4ad 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs @@ -21,6 +21,143 @@ internal Avx512BW() { } internal VL() { } public static new bool IsSupported { get => IsSupported; } + + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm_cvtusepi16_epi8 (__m128i a) + /// VPMOVUWB xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector128 value) => ConvertToVector128ByteWithSaturation(value); + /// + /// __m128i _mm256_cvtusepi16_epi8 (__m256i a) + /// VPMOVUWB xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector256 value) => ConvertToVector128ByteWithSaturation(value); + + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm_cvtepi16_epi8 (__m128i a) + /// VPMOVWB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm256_cvtepi16_epi8 (__m256i a) + /// VPMOVWB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm_cvtsepi16_epi8 (__m128i a) + /// VPMOVSWB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector128 value) => ConvertToVector128SByteWithSaturation(value); + /// + /// __m128i _mm256_cvtsepi16_epi8 (__m256i a) + /// VPMOVSWB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector256 value) => ConvertToVector128SByteWithSaturation(value); + + /// + /// __m128i _mm_permutevar8x16_epi16 (__m128i a, __m128i b) + /// VPERMW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar8x16(Vector128 left, Vector128 control) => PermuteVar8x16(left, control); + /// + /// __m128i _mm_permutevar8x16_epi16 (__m128i a, __m128i b) + /// VPERMW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar8x16(Vector128 left, Vector128 control) => PermuteVar8x16(left, control); + + /// + /// __m256i _mm256_permutevar16x16_epi16 (__m256i a, __m256i b) + /// VPERMW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar16x16(Vector256 left, Vector256 control) => PermuteVar16x16(left, control); + /// + /// __m256i _mm256_permutevar16x16_epi16 (__m256i a, __m256i b) + /// VPERMW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar16x16(Vector256 left, Vector256 control) => PermuteVar16x16(left, control); + + /// + /// __m128i _mm_sllv_epi16 (__m128i a, __m128i count) + /// VPSLLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftLeftLogicalVariable(Vector128 value, Vector128 count) => ShiftLeftLogicalVariable(value, count); + /// + /// __m128i _mm_sllv_epi16 (__m128i a, __m128i count) + /// VPSLLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftLeftLogicalVariable(Vector128 value, Vector128 count) => ShiftLeftLogicalVariable(value, count); + /// + /// __m256i _mm256_sllv_epi16 (__m256i a, __m256i count) + /// VPSLLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftLeftLogicalVariable(Vector256 value, Vector256 count) => ShiftLeftLogicalVariable(value, count); + /// + /// __m256i _mm256_sllv_epi16 (__m256i a, __m256i count) + /// VPSLLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftLeftLogicalVariable(Vector256 value, Vector256 count) => ShiftLeftLogicalVariable(value, count); + + /// + /// __m128i _mm_srav_epi16 (__m128i a, __m128i count) + /// VPSRAVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftRightArithmeticVariable(Vector128 value, Vector128 count) => ShiftRightArithmeticVariable(value, count); + /// + /// __m256i _mm256_srav_epi16 (__m256i a, __m256i count) + /// VPSRAVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftRightArithmeticVariable(Vector256 value, Vector256 count) => ShiftRightArithmeticVariable(value, count); + + /// + /// __m128i _mm_srlv_epi16 (__m128i a, __m128i count) + /// VPSRLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftRightLogicalVariable(Vector128 value, Vector128 count) => ShiftRightLogicalVariable(value, count); + /// + /// __m128i _mm_srlv_epi16 (__m128i a, __m128i count) + /// VPSRLVW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 ShiftRightLogicalVariable(Vector128 value, Vector128 count) => ShiftRightLogicalVariable(value, count); + /// + /// __m256i _mm256_srlv_epi16 (__m256i a, __m256i count) + /// VPSRLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftRightLogicalVariable(Vector256 value, Vector256 count) => ShiftRightLogicalVariable(value, count); + /// + /// __m256i _mm256_srlv_epi16 (__m256i a, __m256i count) + /// VPSRLVW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 ShiftRightLogicalVariable(Vector256 value, Vector256 count) => ShiftRightLogicalVariable(value, count); } [Intrinsic] @@ -106,6 +243,59 @@ internal X64() { } /// public static Vector512 Average(Vector512 left, Vector512 right) => Average(left, right); + /// + /// __m512i _mm512_broadcastb_epi8 (__m128i a) + /// VPBROADCASTB zmm1 {k1}{z}, xmm2/m8 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512i _mm512_broadcastb_epi8 (__m128i a) + /// VPBROADCASTB zmm1 {k1}{z}, xmm2/m8 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512i _mm512_broadcastw_epi16 (__m128i a) + /// VPBROADCASTW zmm1 {k1}{z}, xmm2/m16 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512i _mm512_broadcastw_epi16 (__m128i a) + /// VPBROADCASTW zmm1 {k1}{z}, xmm2/m16 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Byte(Vector512 value) => ConvertToVector256Byte(value); + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Byte(Vector512 value) => ConvertToVector256Byte(value); + /// + /// __m256i _mm512_cvtusepi16_epi8 (__m512i a) + /// VPMOVUWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256ByteWithSaturation(Vector512 value) => ConvertToVector256ByteWithSaturation(value); + + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256SByte(Vector512 value) => ConvertToVector256SByte(value); + /// + /// __m256i _mm512_cvtepi16_epi8 (__m512i a) + /// VPMOVWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256SByte(Vector512 value) => ConvertToVector256SByte(value); + /// + /// __m256i _mm512_cvtsepi16_epi8 (__m512i a) + /// VPMOVSWB ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256SByteWithSaturation(Vector512 value) => ConvertToVector256SByteWithSaturation(value); + /// /// __m512i _mm512_cvtepi8_epi16 (__m128i a) /// VPMOVSXBW zmm1 {k1}{z}, ymm2/m256 @@ -251,6 +441,17 @@ internal X64() { } /// public static Vector512 PackUnsignedSaturate(Vector512 left, Vector512 right) => PackUnsignedSaturate(left, right); + /// + /// __m512i _mm512_permutevar32x16_epi16 (__m512i a, __m512i b) + /// VPERMW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar32x16(Vector512 left, Vector512 control) => PermuteVar32x16(left, control); + /// + /// __m512i _mm512_permutevar32x16_epi16 (__m512i a, __m512i b) + /// VPERMW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar32x16(Vector512 left, Vector512 control) => PermuteVar32x16(left, control); + /// /// __m512i _mm512_sll_epi16 (__m512i a, __m128i count) /// VPSLLW zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -284,6 +485,17 @@ internal X64() { } /// public static Vector512 ShiftLeftLogical128BitLane(Vector512 value, [ConstantExpected] byte numBytes) => ShiftLeftLogical128BitLane(value, numBytes); + /// + /// __m512i _mm512_sllv_epi16 (__m512i a, __m512i count) + /// VPSLLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) => ShiftLeftLogicalVariable(value, count); + /// + /// __m512i _mm512_sllv_epi16 (__m512i a, __m512i count) + /// VPSLLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) => ShiftLeftLogicalVariable(value, count); + /// /// _mm512_sra_epi16 (__m512i a, __m128i count) /// VPSRAW zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -296,6 +508,12 @@ internal X64() { } /// public static Vector512 ShiftRightArithmetic(Vector512 value, [ConstantExpected] byte count) => ShiftRightArithmetic(value, count); + /// + /// __m512i _mm512_srav_epi16 (__m512i a, __m512i count) + /// VPSRAVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftRightArithmeticVariable(Vector512 value, Vector512 count) => ShiftRightArithmeticVariable(value, count); + /// /// __m512i _mm512_srl_epi16 (__m512i a, __m128i count) /// VPSRLW zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -329,6 +547,17 @@ internal X64() { } /// public static Vector512 ShiftRightLogical128BitLane(Vector512 value, [ConstantExpected] byte numBytes) => ShiftRightLogical128BitLane(value, numBytes); + /// + /// __m512i _mm512_srlv_epi16 (__m512i a, __m512i count) + /// VPSRLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) => ShiftRightLogicalVariable(value, count); + /// + /// __m512i _mm512_srlv_epi16 (__m512i a, __m512i count) + /// VPSRLVW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) => ShiftRightLogicalVariable(value, count); + /// /// __m512i _mm512_shuffle_epi8 (__m512i a, __m512i b) /// VPSHUFB zmm1 {k1}{z}, zmm2, zmm3/m512 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.PlatformNotSupported.cs index 0503b5a0db8a1d..6bac345ed9d304 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.PlatformNotSupported.cs @@ -22,6 +22,155 @@ internal VL() { } public static new bool IsSupported { [Intrinsic] get { return false; } } + /// + /// __m128i _mm_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 xmm1 {k1}{z}, xmm2/m64 + /// + public static Vector128 BroadcastPairScalarToVector128(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 xmm1 {k1}{z}, xmm2/m64 + /// + public static Vector128 BroadcastPairScalarToVector128(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm256_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 ymm1 {k1}{z}, xmm2/m64 + /// + public static Vector256 BroadcastPairScalarToVector256(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 ymm1 {k1}{z}, xmm2/m64 + /// + public static Vector256 BroadcastPairScalarToVector256(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_broadcast_f32x2 (__m128 a) + /// VBROADCASTF32x2 ymm1 {k1}{z}, xmm2/m64 + /// + public static Vector256 BroadcastPairScalarToVector256(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128d _mm_cvtepi64_pd (__m128i a) + /// VCVTQQ2PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Double(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_cvtepu64_pd (__m128i a) + /// VCVTUQQ2PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Double(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtps_epi64 (__m128 a) + /// VCVTPS2QQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtpd_epi64 (__m128d a) + /// VCVTPD2QQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvttps_epi64 (__m128 a) + /// VCVTTPS2QQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128Int64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvttpd_epi64 (__m128d a) + /// VCVTTPD2QQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Int64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm_cvtepi64_ps (__m128i a) + /// VCVTQQ2PS xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm256_cvtepi64_ps (__m256i a) + /// VCVTQQ2PS xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm_cvtepu64_ps (__m128i a) + /// VCVTUQQ2PS xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm256_cvtepu64_ps (__m256i a) + /// VCVTUQQ2PS xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtps_epu64 (__m128 a) + /// VCVTPS2UQQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtpd_epu64 (__m128d a) + /// VCVTPD2UQQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvttps_epu64 (__m128 a) + /// VCVTTPS2UQQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128UInt64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvttpd_epu64 (__m128d a) + /// VCVTTPD2UQQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256d _mm256_cvtepi64_pd (__m256i a) + /// VCVTQQ2PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Double(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_cvtepu64_pd (__m256i a) + /// VCVTUQQ2PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Double(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvtps_epi64 (__m128 a) + /// VCVTPS2QQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvtpd_epi64 (__m256d a) + /// VCVTPD2QQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Int64(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvttps_epi64 (__m128 a) + /// VCVTTPS2QQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256Int64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvttpd_epi64 (__m256d a) + /// VCVTTPD2QQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Int64WithTruncation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvtps_epu64 (__m128 a) + /// VCVTPS2UQQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvtpd_epu64 (__m256d a) + /// VCVTPD2UQQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256UInt64(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvttps_epu64 (__m128 a) + /// VCVTTPS2UQQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256UInt64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvttpd_epu64 (__m256d a) + /// VCVTTPD2UQQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256UInt64WithTruncation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// /// __m128i _mm_mullo_epi64 (__m128i a, __m128i b) /// VPMULLQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst @@ -42,6 +191,48 @@ internal VL() { } /// VPMULLQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst /// public static Vector256 MultiplyLow(Vector256 left, Vector256 right) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_range_ps(__m128 a, __m128 b, int imm); + /// VRANGEPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 Range(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_range_pd(__m128d a, __m128d b, int imm); + /// VRANGEPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 Range(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_range_ps(__m256 a, __m256 b, int imm); + /// VRANGEPS ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 Range(Vector256 left, Vector256 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_range_pd(__m256d a, __m256d b, int imm); + /// VRANGEPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 Range(Vector256 left, Vector256 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_reduce_ps(__m128 a, int imm); + /// VREDUCEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 Reduce(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_reduce_pd(__m128d a, int imm); + /// VREDUCEPD xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 Reduce(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_reduce_ps(__m256 a, int imm); + /// VREDUCEPS ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 Reduce(Vector256 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_reduce_pd(__m256d a, int imm); + /// VREDUCEPD ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 Reduce(Vector256 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } } public new abstract class X64 : Avx512F.X64 @@ -73,6 +264,180 @@ internal X64() { } /// public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastPairScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastPairScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_broadcast_f32x2 (__m128 a) + /// VBROADCASTF32x2 zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastPairScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_broadcast_i64x2 (__m128i const * mem_addr) + /// VBROADCASTI64x2 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(long* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcast_i64x2 (__m128i const * mem_addr) + /// VBROADCASTI64x2 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(ulong* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_broadcast_f64x2 (__m128d const * mem_addr) + /// VBROADCASTF64x2 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(double* address) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_broadcast_i32x8 (__m256i const * mem_addr) + /// VBROADCASTI32x8 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(int* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcast_i32x8 (__m256i const * mem_addr) + /// VBROADCASTI32x8 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(uint* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_broadcast_f32x8 (__m256 const * mem_addr) + /// VBROADCASTF32x8 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(float* address) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_cvtepi64_ps (__m512i a) + /// VCVTQQ2PS ymm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector256 ConvertToVector256Single(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_cvtepu64_ps (__m512i a) + /// VCVTUQQ2PS ymm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector256 ConvertToVector256Single(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512d _mm512_cvtepi64_pd (__m512i a) + /// VCVTQQ2PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 ConvertToVector512Double(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_cvtepu64_pd (__m512i a) + /// VCVTUQQ2PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 ConvertToVector512Double(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtps_epi64 (__m512 a) + /// VCVTPS2QQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512Int64(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtpd_epi64 (__m512d a) + /// VCVTPD2QQ zmm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector512 ConvertToVector512Int64(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvttps_epi64 (__m512 a) + /// VCVTTPS2QQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512Int64WithTruncation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvttpd_epi64 (__m512 a) + /// VCVTTPD2QQ zmm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// + public static Vector512 ConvertToVector512Int64WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtps_epu64 (__m512 a) + /// VCVTPS2UQQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt64(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtpd_epu64 (__m512d a) + /// VCVTPD2UQQ zmm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector512 ConvertToVector512UInt64(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvttps_epu64 (__m512 a) + /// VCVTTPS2UQQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt64WithTruncation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvttpd_epu64 (__m512d a) + /// VCVTTPD2UQQ zmm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector512 ConvertToVector512UInt64WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm512_extracti64x2_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x2 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static new Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti64x2_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x2 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static new Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm512_extractf64x2_pd (__m512d a, const int imm8) + /// VEXTRACTF64x2 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static new Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_extracti32x8_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x8 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static new Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti32x8_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x8 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static new Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm512_extractf32x8_ps (__m512 a, const int imm8) + /// VEXTRACTF32x8 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static new Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_inserti64x2_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI64x2 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 + /// + public static new Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_inserti64x2_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI64x2 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 + /// + public static new Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_insertf64x2_pd (__m512d a, __m128d b, int imm8) + /// VINSERTF64x2 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 + /// + public static new Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_inserti32x8_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI32x8 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 + /// + public static new Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_inserti32x8_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI32x8 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 + /// + public static new Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_insertf32x8_ps (__m512 a, __m256 b, int imm8) + /// VINSERTF32x8 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 + /// + public static new Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_mullo_epi64 (__m512i a, __m512i b) /// VPMULLQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst @@ -95,6 +460,62 @@ internal X64() { } /// public static Vector512 Or(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_range_ps(__m512 a, __m512 b, int imm); + /// VRANGEPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{sae}, imm8 + /// + public static Vector512 Range(Vector512 left, Vector512 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_range_pd(__m512d a, __m512d b, int imm); + /// VRANGEPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{sae}, imm8 + /// + public static Vector512 Range(Vector512 left, Vector512 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_range_ss(__m128 a, __m128 b, int imm); + /// VRANGESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 RangeScalar(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_range_sd(__m128d a, __m128d b, int imm); + /// VRANGESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// + public static Vector128 RangeScalar(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_reduce_ps(__m512 a, int imm); + /// VREDUCEPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae}, imm8 + /// + public static Vector512 Reduce(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_reduce_pd(__m512d a, int imm); + /// VREDUCEPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae}, imm8 + /// + public static Vector512 Reduce(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_reduce_ss(__m128 a, int imm); + /// VREDUCESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 ReduceScalar(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_reduce_sd(__m128d a, int imm); + /// VREDUCESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// + public static Vector128 ReduceScalar(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm_reduce_ss(__m128 a, __m128 b, int imm); + /// VREDUCESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReduceScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_reduce_sd(__m128d a, __m128d b, int imm); + /// VREDUCESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReduceScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// /// __m512 _mm512_xor_ps (__m512 a, __m512 b) /// VXORPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.cs index 436595edfc9bdb..97898da3ff6edf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512DQ.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace System.Runtime.Intrinsics.X86 @@ -21,6 +22,155 @@ internal VL() { } public static new bool IsSupported { get => IsSupported; } + /// + /// __m128i _mm_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 xmm1 {k1}{z}, xmm2/m64 + /// + public static Vector128 BroadcastPairScalarToVector128(Vector128 value) => BroadcastPairScalarToVector128(value); + /// + /// __m128i _mm_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 xmm1 {k1}{z}, xmm2/m64 + /// + public static Vector128 BroadcastPairScalarToVector128(Vector128 value) => BroadcastPairScalarToVector128(value); + + /// + /// __m256i _mm256_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 ymm1 {k1}{z}, xmm2/m64 + /// + public static Vector256 BroadcastPairScalarToVector256(Vector128 value) => BroadcastPairScalarToVector256(value); + /// + /// __m256i _mm256_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 ymm1 {k1}{z}, xmm2/m64 + /// + public static Vector256 BroadcastPairScalarToVector256(Vector128 value) => BroadcastPairScalarToVector256(value); + /// + /// __m256 _mm256_broadcast_f32x2 (__m128 a) + /// VBROADCASTF32x2 ymm1 {k1}{z}, xmm2/m64 + /// + public static Vector256 BroadcastPairScalarToVector256(Vector128 value) => BroadcastPairScalarToVector256(value); + + /// + /// __m128d _mm_cvtepi64_pd (__m128i a) + /// VCVTQQ2PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Double(Vector128 value) => ConvertToVector128Double(value); + /// + /// __m128d _mm_cvtepu64_pd (__m128i a) + /// VCVTUQQ2PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Double(Vector128 value) => ConvertToVector128Double(value); + /// + /// __m128i _mm_cvtps_epi64 (__m128 a) + /// VCVTPS2QQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128Int64(Vector128 value) => ConvertToVector128Int64(value); + /// + /// __m128i _mm_cvtpd_epi64 (__m128d a) + /// VCVTPD2QQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Int64(Vector128 value) => ConvertToVector128Int64(value); + /// + /// __m128i _mm_cvttps_epi64 (__m128 a) + /// VCVTTPS2QQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128Int64WithTruncation(Vector128 value) => ConvertToVector128Int64WithTruncation(value); + /// + /// __m128i _mm_cvttpd_epi64 (__m128d a) + /// VCVTTPD2QQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Int64WithTruncation(Vector128 value) => ConvertToVector128Int64WithTruncation(value); + /// + /// __m128 _mm_cvtepi64_ps (__m128i a) + /// VCVTQQ2PS xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector128 value) => ConvertToVector128Single(value); + /// + /// __m128 _mm256_cvtepi64_ps (__m256i a) + /// VCVTQQ2PS xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector256 value) => ConvertToVector128Single(value); + /// + /// __m128 _mm_cvtepu64_ps (__m128i a) + /// VCVTUQQ2PS xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector128 value) => ConvertToVector128Single(value); + /// + /// __m128 _mm256_cvtepu64_ps (__m256i a) + /// VCVTUQQ2PS xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128Single(Vector256 value) => ConvertToVector128Single(value); + /// + /// __m128i _mm_cvtps_epu64 (__m128 a) + /// VCVTPS2UQQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128UInt64(Vector128 value) => ConvertToVector128UInt64(value); + /// + /// __m128i _mm_cvtpd_epu64 (__m128d a) + /// VCVTPD2UQQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt64(Vector128 value) => ConvertToVector128UInt64(value); + /// + /// __m128i _mm_cvttps_epu64 (__m128 a) + /// VCVTTPS2UQQ xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128UInt64WithTruncation(Vector128 value) => ConvertToVector128UInt64WithTruncation(value); + /// + /// __m128i _mm_cvttpd_epu64 (__m128d a) + /// VCVTTPD2UQQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt64WithTruncation(Vector128 value) => ConvertToVector128UInt64WithTruncation(value); + + /// + /// __m256d _mm256_cvtepi64_pd (__m256i a) + /// VCVTQQ2PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Double(Vector256 value) => ConvertToVector256Double(value); + /// + /// __m256d _mm256_cvtepu64_pd (__m256i a) + /// VCVTUQQ2PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Double(Vector256 value) => ConvertToVector256Double(value); + /// + /// __m256i _mm256_cvtps_epi64 (__m128 a) + /// VCVTPS2QQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256Int64(Vector128 value) => ConvertToVector256Int64(value); + /// + /// __m256i _mm256_cvtpd_epi64 (__m256d a) + /// VCVTPD2QQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Int64(Vector256 value) => ConvertToVector256Int64(value); + /// + /// __m256i _mm256_cvttps_epi64 (__m128 a) + /// VCVTTPS2QQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256Int64WithTruncation(Vector128 value) => ConvertToVector256Int64WithTruncation(value); + /// + /// __m256i _mm256_cvttpd_epi64 (__m256d a) + /// VCVTTPD2QQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256Int64WithTruncation(Vector256 value) => ConvertToVector256Int64WithTruncation(value); + /// + /// __m256i _mm256_cvtps_epu64 (__m128 a) + /// VCVTPS2UQQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256UInt64(Vector128 value) => ConvertToVector256UInt64(value); + /// + /// __m256i _mm256_cvtpd_epu64 (__m256d a) + /// VCVTPD2UQQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256UInt64(Vector256 value) => ConvertToVector256UInt64(value); + /// + /// __m256i _mm256_cvttps_epu64 (__m128 a) + /// VCVTTPS2UQQ ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256UInt64WithTruncation(Vector128 value) => ConvertToVector256UInt64WithTruncation(value); + /// + /// __m256i _mm256_cvttpd_epu64 (__m256d a) + /// VCVTTPD2UQQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ConvertToVector256UInt64WithTruncation(Vector256 value) => ConvertToVector256UInt64WithTruncation(value); + /// /// __m128i _mm_mullo_epi64 (__m128i a, __m128i b) /// VPMULLQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst @@ -41,6 +191,48 @@ internal VL() { } /// VPMULLQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst /// public static Vector256 MultiplyLow(Vector256 left, Vector256 right) => MultiplyLow(left, right); + + /// + /// __m128 _mm_range_ps(__m128 a, __m128 b, int imm); + /// VRANGEPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 Range(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => Range(left, right, control); + /// + /// __m128d _mm_range_pd(__m128d a, __m128d b, int imm); + /// VRANGEPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 Range(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => Range(left, right, control); + /// + /// __m256 _mm256_range_ps(__m256 a, __m256 b, int imm); + /// VRANGEPS ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 Range(Vector256 left, Vector256 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => Range(left, right, control); + /// + /// __m256d _mm256_range_pd(__m256d a, __m256d b, int imm); + /// VRANGEPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 Range(Vector256 left, Vector256 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => Range(left, right, control); + + /// + /// __m128 _mm_reduce_ps(__m128 a, int imm); + /// VREDUCEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 Reduce(Vector128 value, [ConstantExpected] byte control) => Reduce(value, control); + /// + /// __m128d _mm_reduce_pd(__m128d a, int imm); + /// VREDUCEPD xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 Reduce(Vector128 value, [ConstantExpected] byte control) => Reduce(value, control); + /// + /// __m256 _mm256_reduce_ps(__m256 a, int imm); + /// VREDUCEPS ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 Reduce(Vector256 value, [ConstantExpected] byte control) => Reduce(value, control); + /// + /// __m256d _mm256_reduce_pd(__m256d a, int imm); + /// VREDUCEPD ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 Reduce(Vector256 value, [ConstantExpected] byte control) => Reduce(value, control); } [Intrinsic] @@ -73,6 +265,180 @@ internal X64() { } /// public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastPairScalarToVector512(Vector128 value) => BroadcastPairScalarToVector512(value); + /// + /// __m512i _mm512_broadcast_i32x2 (__m128i a) + /// VBROADCASTI32x2 zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastPairScalarToVector512(Vector128 value) => BroadcastPairScalarToVector512(value); + /// + /// __m512 _mm512_broadcast_f32x2 (__m128 a) + /// VBROADCASTF32x2 zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastPairScalarToVector512(Vector128 value) => BroadcastPairScalarToVector512(value); + + /// + /// __m512i _mm512_broadcast_i64x2 (__m128i const * mem_addr) + /// VBROADCASTI64x2 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(long* address) => BroadcastVector128ToVector512(address); + /// + /// __m512i _mm512_broadcast_i64x2 (__m128i const * mem_addr) + /// VBROADCASTI64x2 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(ulong* address) => BroadcastVector128ToVector512(address); + /// + /// __m512d _mm512_broadcast_f64x2 (__m128d const * mem_addr) + /// VBROADCASTF64x2 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(double* address) => BroadcastVector128ToVector512(address); + + /// + /// __m512i _mm512_broadcast_i32x8 (__m256i const * mem_addr) + /// VBROADCASTI32x8 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(int* address) => BroadcastVector256ToVector512(address); + /// + /// __m512i _mm512_broadcast_i32x8 (__m256i const * mem_addr) + /// VBROADCASTI32x8 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(uint* address) => BroadcastVector256ToVector512(address); + /// + /// __m512 _mm512_broadcast_f32x8 (__m256 const * mem_addr) + /// VBROADCASTF32x8 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(float* address) => BroadcastVector256ToVector512(address); + + /// + /// __m512 _mm512_cvtepi64_ps (__m512i a) + /// VCVTQQ2PS ymm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector256 ConvertToVector256Single(Vector512 value) => ConvertToVector256Single(value); + /// + /// __m512 _mm512_cvtepu64_ps (__m512i a) + /// VCVTUQQ2PS ymm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector256 ConvertToVector256Single(Vector512 value) => ConvertToVector256Single(value); + + /// + /// __m512d _mm512_cvtepi64_pd (__m512i a) + /// VCVTQQ2PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 ConvertToVector512Double(Vector512 value) => ConvertToVector512Double(value); + /// + /// __m512d _mm512_cvtepu64_pd (__m512i a) + /// VCVTUQQ2PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 ConvertToVector512Double(Vector512 value) => ConvertToVector512Double(value); + /// + /// __m512i _mm512_cvtps_epi64 (__m512 a) + /// VCVTPS2QQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512Int64(Vector256 value) => ConvertToVector512Int64(value); + /// + /// __m512i _mm512_cvtpd_epi64 (__m512d a) + /// VCVTPD2QQ zmm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector512 ConvertToVector512Int64(Vector512 value) => ConvertToVector512Int64(value); + /// + /// __m512i _mm512_cvttps_epi64 (__m512 a) + /// VCVTTPS2QQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512Int64WithTruncation(Vector256 value) => ConvertToVector512Int64WithTruncation(value); + /// + /// __m512i _mm512_cvttpd_epi64 (__m512 a) + /// VCVTTPD2QQ zmm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// + public static Vector512 ConvertToVector512Int64WithTruncation(Vector512 value) => ConvertToVector512Int64WithTruncation(value); + /// + /// __m512i _mm512_cvtps_epu64 (__m512 a) + /// VCVTPS2UQQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt64(Vector256 value) => ConvertToVector512UInt64(value); + /// + /// __m512i _mm512_cvtpd_epu64 (__m512d a) + /// VCVTPD2UQQ zmm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector512 ConvertToVector512UInt64(Vector512 value) => ConvertToVector512UInt64(value); + /// + /// __m512i _mm512_cvttps_epu64 (__m512 a) + /// VCVTTPS2UQQ zmm1 {k1}{z}, ymm2/m256/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt64WithTruncation(Vector256 value) => ConvertToVector512UInt64WithTruncation(value); + /// + /// __m512i _mm512_cvttpd_epu64 (__m512d a) + /// VCVTTPD2UQQ zmm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector512 ConvertToVector512UInt64WithTruncation(Vector512 value) => ConvertToVector512UInt64WithTruncation(value); + + /// + /// __m128i _mm512_extracti64x2_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x2 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static new Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti64x2_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x2 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static new Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128d _mm512_extractf64x2_pd (__m512d a, const int imm8) + /// VEXTRACTF64x2 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static new Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + + /// + /// __m256i _mm512_extracti32x8_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x8 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static new Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti32x8_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x8 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static new Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256 _mm512_extractf32x8_ps (__m512 a, const int imm8) + /// VEXTRACTF32x8 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static new Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + + /// + /// __m512i _mm512_inserti64x2_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI64x2 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 + /// + public static new Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); + /// + /// __m512i _mm512_inserti64x2_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI64x2 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 + /// + public static new Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); + /// + /// __m512d _mm512_insertf64x2_pd (__m512d a, __m128d b, int imm8) + /// VINSERTF64x2 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 + /// + public static new Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); + + /// + /// __m512i _mm512_inserti32x8_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI32x8 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 + /// + public static new Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); + /// + /// __m512i _mm512_inserti32x8_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI32x8 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 + /// + public static new Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); + /// + /// __m512 _mm512_insertf32x8_ps (__m512 a, __m256 b, int imm8) + /// VINSERTF32x8 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 + /// + public static new Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); + /// /// __m512i _mm512_mullo_epi64 (__m512i a, __m512i b) /// VPMULLQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst @@ -95,6 +461,62 @@ internal X64() { } /// public static Vector512 Or(Vector512 left, Vector512 right) => Or(left, right); + /// + /// __m512 _mm512_range_ps(__m512 a, __m512 b, int imm); + /// VRANGEPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{sae}, imm8 + /// + public static Vector512 Range(Vector512 left, Vector512 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => Range(left, right, control); + /// + /// __m512d _mm512_range_pd(__m512d a, __m512d b, int imm); + /// VRANGEPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{sae}, imm8 + /// + public static Vector512 Range(Vector512 left, Vector512 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => Range(left, right, control); + + /// + /// __m128 _mm_range_ss(__m128 a, __m128 b, int imm); + /// VRANGESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 RangeScalar(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => RangeScalar(left, right, control); + /// + /// __m128d _mm_range_sd(__m128d a, __m128d b, int imm); + /// VRANGESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// + public static Vector128 RangeScalar(Vector128 left, Vector128 right, [ConstantExpected(Max = (byte)(0x0F))] byte control) => RangeScalar(left, right, control); + + /// + /// __m512 _mm512_reduce_ps(__m512 a, int imm); + /// VREDUCEPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae}, imm8 + /// + public static Vector512 Reduce(Vector512 value, [ConstantExpected] byte control) => Reduce(value, control); + /// + /// __m512d _mm512_reduce_pd(__m512d a, int imm); + /// VREDUCEPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae}, imm8 + /// + public static Vector512 Reduce(Vector512 value, [ConstantExpected] byte control) => Reduce(value, control); + + /// + /// __m128 _mm_reduce_ss(__m128 a, int imm); + /// VREDUCESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 ReduceScalar(Vector128 value, [ConstantExpected] byte control) => ReduceScalar(value, control); + /// + /// __m128d _mm_reduce_sd(__m128d a, int imm); + /// VREDUCESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// + public static Vector128 ReduceScalar(Vector128 value, [ConstantExpected] byte control) => ReduceScalar(value, control); + /// + /// __m128 _mm_reduce_ss(__m128 a, __m128 b, int imm); + /// VREDUCESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReduceScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) => ReduceScalar(upper, value, control); + /// + /// __m128d _mm_reduce_sd(__m128d a, __m128d b, int imm); + /// VREDUCESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReduceScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) => ReduceScalar(upper, value, control); + /// /// __m512 _mm512_xor_ps (__m512 a, __m512 b) /// VXORPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs index 96b70d19e58c17..331e93cbca5552 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs @@ -33,6 +33,438 @@ internal VL() { } /// public static Vector256 Abs(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtusepi32_epi8 (__m128i a) + /// VPMOVUSDB xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtusepi64_epi8 (__m128i a) + /// VPMOVUSQB xmm1/m16 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtusepi32_epi8 (__m256i a) + /// VPMOVUSDB xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtusepi64_epi8 (__m256i a) + /// VPMOVUSQB xmm1/m32 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128d _mm_cvtepu32_pd (__m128i a) + /// VCVTUDQ2PD xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128Double(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtsepi32_epi16 (__m128i a) + /// VPMOVSDW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtsepi64_epi16 (__m128i a) + /// VPMOVSQW xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtsepi32_epi16 (__m256i a) + /// VPMOVSDW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtsepi64_epi16 (__m256i a) + /// VPMOVSQW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Int32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Int32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Int32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Int32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm128_cvtsepi64_epi32 (__m128i a) + /// VPMOVSQD xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Int32WithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtsepi64_epi32 (__m256i a) + /// VPMOVSQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Int32WithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtsepi32_epi8 (__m128i a) + /// VPMOVSDB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtsepi64_epi8 (__m128i a) + /// VPMOVSQB xmm1/m16 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtsepi32_epi8 (__m256i a) + /// VPMOVSDB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtsepi64_epi8 (__m256i a) + /// VPMOVSQB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_cvtepu32_ps (__m128i a) + /// VCVTUDQ2PS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToVector128Single(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtusepi32_epi16 (__m128i a) + /// VPMOVUSDW xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtusepi64_epi16 (__m128i a) + /// VPMOVUSQW xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtusepi32_epi16 (__m256i a) + /// VPMOVUSDW xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtusepi64_epi16 (__m256i a) + /// VPMOVUSQW xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm128_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m128 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm128_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m128 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtps_epu32 (__m128 a) + /// VCVTPS2UDQ xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvtpd_epu32 (__m128d a) + /// VCVTPD2UDQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtpd_epu32 (__m256d a) + /// VCVTPD2UDQ xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm128_cvtusepi64_epi32 (__m128i a) + /// VPMOVUSQD xmm1/m128 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt32WithSaturation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvtusepi64_epi32 (__m256i a) + /// VPMOVUSQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt32WithSaturation(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvttps_epu32 (__m128 a) + /// VCVTTPS2UDQ xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToVector128UInt32WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_cvttpd_epu32 (__m128d a) + /// VCVTTPD2UDQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt32WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm256_cvttpd_epu32 (__m256d a) + /// VCVTTPD2UDQ xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128UInt32WithTruncation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256d _mm512_cvtepu32_pd (__m128i a) + /// VCVTUDQ2PD ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256Double(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_cvtepu32_ps (__m256i a) + /// VCVTUDQ2PS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ConvertToVector256Single(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvtps_epu32 (__m256 a) + /// VCVTPS2UDQ ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ConvertToVector256UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_cvttps_epu32 (__m256 a) + /// VCVTTPS2UDQ ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ConvertToVector256UInt32WithTruncation(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_fixupimm_ps(__m128 a, __m128 b, __m128i tbl, int imm); + /// VFIXUPIMMPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 Fixup(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_fixupimm_pd(__m128d a, __m128d b, __m128i tbl, int imm); + /// VFIXUPIMMPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 Fixup(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_fixupimm_ps(__m256 a, __m256 b, __m256i tbl, int imm); + /// VFIXUPIMMPS ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 Fixup(Vector256 left, Vector256 right, Vector256 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_fixupimm_pd(__m256d a, __m256d b, __m256i tbl, int imm); + /// VFIXUPIMMPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 Fixup(Vector256 left, Vector256 right, Vector256 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_getexp_ps (__m128 a) + /// VGETEXPPS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 GetExponent(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_getexp_pd (__m128d a) + /// VGETEXPPD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 GetExponent(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_getexp_ps (__m256 a) + /// VGETEXPPS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 GetExponent(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_getexp_pd (__m256d a) + /// VGETEXPPD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 GetExponent(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_getmant_ps (__m128 a) + /// VGETMANTPS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 GetMantissa(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_getmant_pd (__m128d a) + /// VGETMANTPD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 GetMantissa(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_getmant_ps (__m256 a) + /// VGETMANTPS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 GetMantissa(Vector256 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_getmant_pd (__m256d a) + /// VGETMANTPD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 GetMantissa(Vector256 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// /// __m128i _mm_max_epi64 (__m128i a, __m128i b) /// VPMAXSQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst @@ -75,6 +507,106 @@ internal VL() { } /// public static Vector256 Min(Vector256 left, Vector256 right) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_permute4x64_epi64 (__m256i a, __m256i b) + /// VPERMQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 PermuteVar4x64(Vector256 value, Vector256 control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_permute4x64_pd (__m256d a, __m256i b) + /// VPERMQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 PermuteVar4x64(Vector256 value, Vector256 control) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_permute4x64_pd (__m256d a, __m256i b) + /// VPERMPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 PermuteVar4x64(Vector256 value, Vector256 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_rcp14_ps (__m128 a, __m128 b) + /// VRCP14PS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 Reciprocal14(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_rcp14_pd (__m128d a, __m128d b) + /// VRCP14PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 Reciprocal14(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_rcp14_ps (__m256 a, __m256 b) + /// VRCP14PS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 Reciprocal14(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_rcp14_pd (__m256d a, __m256d b) + /// VRCP14PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 Reciprocal14(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_rsqrt14_ps (__m128 a, __m128 b) + /// VRSQRT14PS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ReciprocalSqrt14(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_rsqrt14_pd (__m128d a, __m128d b) + /// VRSQRT14PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ReciprocalSqrt14(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_rsqrt14_ps (__m256 a, __m256 b) + /// VRSQRT14PS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ReciprocalSqrt14(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_rsqrt14_pd (__m256d a, __m256d b) + /// VRSQRT14PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ReciprocalSqrt14(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_roundscale_ps (__m128 a, int imm) + /// VRNDSCALEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RoundScale(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_roundscale_pd (__m128d a, int imm) + /// VRNDSCALEPD xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RoundScale(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_roundscale_ps (__m256 a, int imm) + /// VRNDSCALEPS ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RoundScale(Vector256 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_roundscale_pd (__m256d a, int imm) + /// VRNDSCALEPD ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RoundScale(Vector256 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_scalef_ps (__m128 a, int imm) + /// VSCALEFPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 Scale(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_scalef_pd (__m128d a, int imm) + /// VSCALEFPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 Scale(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_scalef_ps (__m256 a, int imm) + /// VSCALEFPS ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 Scale(Vector256 left, Vector256 right) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_scalef_pd (__m256d a, int imm) + /// VSCALEFPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 Scale(Vector256 left, Vector256 right) { throw new PlatformNotSupportedException(); } + /// /// __m128i _mm_sra_epi64 (__m128i a, __m128i count) /// VPSRAQ xmm1 {k1}{z}, xmm2, xmm3/m128 @@ -96,6 +628,17 @@ internal VL() { } /// VPSRAQ ymm1 {k1}{z}, ymm2, imm8 /// public static Vector256 ShiftRightArithmetic(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_srav_epi64 (__m128i a, __m128i count) + /// VPSRAVQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 ShiftRightArithmeticVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_srav_epi64 (__m256i a, __m256i count) + /// VPSRAVQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 ShiftRightArithmeticVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } } public new abstract class X64 : Avx2.X64 @@ -103,6 +646,45 @@ internal VL() { } internal X64() { } public static new bool IsSupported { [Intrinsic] get { return false; } } + + /// + /// __m128 _mm_cvtsi64_ss (__m128 a, __int64 b) + /// VCVTUSI2SS xmm1, xmm2, r/m64 + /// This intrinsic is only available on 64-bit processes + /// + public static Vector128 ConvertScalarToVector128Single(Vector128 upper, ulong value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_cvtsi64_sd (__m128d a, __int64 b) + /// VCVTUSI2SD xmm1, xmm2, r/m64 + /// This intrinsic is only available on 64-bit processes + /// + public static Vector128 ConvertScalarToVector128Double(Vector128 upper, ulong value) { throw new PlatformNotSupportedException(); } + + /// + /// unsigned __int64 _mm_cvtss_u64 (__m128 a) + /// VCVTSS2USI r64, xmm1/m32{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// unsigned __int64 _mm_cvtsd_u64 (__m128d a) + /// VCVTSD2USI r64, xmm1/m64{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// unsigned __int64 _mm_cvttss_u64 (__m128 a) + /// VCVTTSS2USI r64, xmm1/m32{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// unsigned __int64 _mm_cvttsd_u64 (__m128d a) + /// VCVTTSD2USI r64, xmm1/m64{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } } /// @@ -171,235 +753,876 @@ internal X64() { } /// __m512i _mm512_and_epi32 (__m512i a, __m512i b) /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_and_epi32 (__m512i a, __m512i b) + /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) + /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) + /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) + /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) + /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_broadcastd_epi32 (__m128i a) + /// VPBROADCASTD zmm1 {k1}{z}, xmm2/m32 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcastd_epi32 (__m128i a) + /// VPBROADCASTD zmm1 {k1}{z}, xmm2/m32 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcastq_epi64 (__m128i a) + /// VPBROADCASTQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcastq_epi64 (__m128i a) + /// VPBROADCASTQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_broadcastss_ps (__m128 a) + /// VBROADCASTSS zmm1 {k1}{z}, xmm2/m32 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_broadcastsd_pd (__m128d a) + /// VBROADCASTSD zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_broadcast_i32x4 (__m128i const * mem_addr) + /// VBROADCASTI32x4 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(int* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcast_i32x4 (__m128i const * mem_addr) + /// VBROADCASTI32x4 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(uint* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_broadcast_f32x4 (__m128 const * mem_addr) + /// VBROADCASTF32x4 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(float* address) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_broadcast_i64x4 (__m256i const * mem_addr) + /// VBROADCASTI64x4 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(long* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_broadcast_i64x4 (__m256i const * mem_addr) + /// VBROADCASTI64x4 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(ulong* address) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_broadcast_f64x4 (__m256d const * mem_addr) + /// VBROADCASTF64x4 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(double* address) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_cvtsi32_ss (__m128 a, int b) + /// VCVTUSI2SS xmm1, xmm2, r/m32 + /// + public static Vector128 ConvertScalarToVector128Single(Vector128 upper, uint value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_cvtsi32_sd (__m128d a, int b) + /// VCVTUSI2SD xmm1, xmm2, r/m32 + /// + public static Vector128 ConvertScalarToVector128Double(Vector128 upper, uint value) { throw new PlatformNotSupportedException(); } + + /// + /// unsigned int _mm_cvtss_u32 (__m128 a) + /// VCVTSS2USI r32, xmm1/m32{er} + /// + public static uint ConvertToUInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// unsigned int _mm_cvtsd_u32 (__m128d a) + /// VCVTSD2USI r32, xmm1/m64{er} + /// + public static uint ConvertToUInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// unsigned int _mm_cvttss_u32 (__m128 a) + /// VCVTTSS2USI r32, xmm1/m32{er} + /// + public static uint ConvertToUInt32WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// unsigned int _mm_cvttsd_u32 (__m128d a) + /// VCVTTSD2USI r32, xmm1/m64{er} + /// + public static uint ConvertToUInt32WithTruncation(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtusepi32_epi8 (__m512i a) + /// VPMOVUSDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtusepi64_epi8 (__m512i a) + /// VPMOVUSQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtsepi64_epi16 (__m512i a) + /// VPMOVSQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtsepi32_epi8 (__m512i a) + /// VPMOVSDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtsepi64_epi8 (__m512i a) + /// VPMOVSQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_cvtusepi64_epi16 (__m512i a) + /// VPMOVUSQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtsepi32_epi16 (__m512i a) + /// VPMOVSDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int16WithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_cvtpd_epi32 (__m512d a) + /// VCVTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256Int32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtsepi64_epi32 (__m512i a) + /// VPMOVSQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int32WithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvttpd_epi32 (__m512d a) + /// VCVTTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// + public static Vector256 ConvertToVector256Int32WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256 _mm512_cvtpd_ps (__m512d a) + /// VCVTPD2PS ymm1, zmm2/m512 + /// VCVTPD2PS ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256Single(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt16(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtusepi32_epi16 (__m512i a) + /// VPMOVUSDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt16WithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_cvtpd_epu32 (__m512d a) + /// VCVTPD2UDQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256UInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvtusepi64_epi32 (__m512i a) + /// VPMOVUSQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt32WithSaturation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_cvttpd_epu32 (__m512d a) + /// VCVTTPD2UDQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256UInt32WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512d _mm512_cvtepi32_pd (__m256i a) + /// VCVTDQ2PD zmm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector512 ConvertToVector512Double(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_cvtps_pd (__m256 a) + /// VCVTPS2PD zmm1 {k1}{z}, ymm2/m256/m32bcst{sae} + /// + public static Vector512 ConvertToVector512Double(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_cvtepu32_pd (__m256i a) + /// VCVTUDQ2PD zmm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector512 ConvertToVector512Double(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi8_epi32 (__m128i a) + /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu8_epi32 (__m128i a) + /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi16_epi32 (__m128i a) + /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu16_epi32 (__m128i a) + /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtps_epi32 (__m512 a) + /// VCVTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512Int32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvttps_epi32 (__m512 a) + /// VCVTTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} + /// + public static Vector512 ConvertToVector512Int32WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi8_epi64 (__m128i a) + /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu8_epi64 (__m128i a) + /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi16_epi64 (__m128i a) + /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu16_epi64 (__m128i a) + /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi32_epi64 (__m128i a) + /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int64(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu32_epi64 (__m128i a) + /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int64(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_cvtepi32_ps (__m512i a) + /// VCVTDQ2PS zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512Single(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_cvtepu32_ps (__m512i a) + /// VCVTUDQ2PS zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512Single(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi8_epi32 (__m128i a) + /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu8_epi32 (__m128i a) + /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi16_epi32 (__m128i a) + /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu16_epi32 (__m128i a) + /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtps_epu32 (__m512 a) + /// VCVTPS2UDQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvttps_epu32 (__m512 a) + /// VCVTTPS2UDQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt32WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi8_epi64 (__m128i a) + /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu8_epi64 (__m128i a) + /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi16_epi64 (__m128i a) + /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu16_epi64 (__m128i a) + /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepi32_epi64 (__m128i a) + /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt64(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_cvtepu32_epi64 (__m128i a) + /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt64(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_div_ps (__m512 a, __m512 b) + /// VDIVPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er} + /// + public static Vector512 Divide(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_div_pd (__m512d a, __m512d b) + /// VDIVPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{er} + /// + public static Vector512 Divide(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_moveldup_ps (__m512 a) + /// VMOVSLDUP zmm1 {k1}{z}, zmm2/m512 + /// + public static Vector512 DuplicateEvenIndexed(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_movedup_pd (__m512d a) + /// VMOVDDUP zmm1 {k1}{z}, zmm2/m512 + /// + public static Vector512 DuplicateEvenIndexed(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_movehdup_ps (__m512 a) + /// VMOVSHDUP zmm1 {k1}{z}, zmm2/m512 + /// + public static Vector512 DuplicateOddIndexed(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti32x4_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti32x4_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm512_extractf32x4_ps (__m512 a, const int imm8) + /// VEXTRACTF32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm512_extractf128_pd (__m512d a, const int imm8) + /// VEXTRACTF32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti64x4_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm512_extracti64x4_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm512_extractf256_ps (__m512 a, const int imm8) + /// VEXTRACTF64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm512_extractf64x4_pd (__m512d a, const int imm8) + /// VEXTRACTF64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_fixupimm_ps(__m512 a, __m512 b, __m512i tbl, int imm); + /// VFIXUPIMMPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{sae}, imm8 + /// + public static Vector512 Fixup(Vector512 left, Vector512 right, Vector512 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_fixupimm_pd(__m512d a, __m512d b, __m512i tbl, int imm); + /// VFIXUPIMMPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{sae}, imm8 + /// + public static Vector512 Fixup(Vector512 left, Vector512 right, Vector512 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_fixupimm_ss(__m128 a, __m128 b, __m128i tbl, int imm); + /// VFIXUPIMMSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 FixupScalar(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_and_epi32 (__m512i a, __m512i b) - /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m128d _mm_fixupimm_sd(__m128d a, __m128d b, __m128i tbl, int imm); + /// VFIXUPIMMSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 /// - public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector128 FixupScalar(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) - /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512 _mm512_fmadd_ps (__m512 a, __m512 b, __m512 c) + /// VFMADDPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplyAdd(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) - /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512d _mm512_fmadd_pd (__m512d a, __m512d b, __m512d c) + /// VFMADDPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 And(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplyAdd(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512 _mm512_fmaddsub_ps (__m512 a, __m512 b, __m512 c) + /// VFMADDSUBPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplyAddSubtract(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512d _mm512_fmaddsub_pd (__m512d a, __m512d b, __m512d c) + /// VFMADDSUBPD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplyAddSubtract(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512 _mm512_fmsub_ps (__m512 a, __m512 b, __m512 c) + /// VFMSUBPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplySubtract(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512d _mm512_fmsub_pd (__m512d a, __m512d b, __m512d c) + /// VFMSUBPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplySubtract(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512 _mm512_fmsubadd_ps (__m512 a, __m512 b, __m512 c) + /// VFMSUBADDPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplySubtractAdd(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512d _mm512_fmsubadd_pd (__m512d a, __m512d b, __m512d c) + /// VFMSUBADDPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplySubtractAdd(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) - /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512 _mm512_fnmadd_ps (__m512 a, __m512 b, __m512 c) + /// VFNMADDPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplyAddNegated(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) - /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512d _mm512_fnmadd_pd (__m512d a, __m512d b, __m512d c) + /// VFNMADDPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplyAddNegated(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m256i _mm512_cvtpd_epi32 (__m512d a) - /// VCVTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// __m512 _mm512_fnmsub_ps (__m512 a, __m512 b, __m512 c) + /// VFNMSUBPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector256 ConvertToVector256Int32(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplySubtractNegated(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m256 _mm512_cvtpd_ps (__m512d a) - /// VCVTPD2PS ymm1, zmm2/m512 - /// VCVTPD2PS ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// __m512d _mm512_fnmsub_pd (__m512d a, __m512d b, __m512d c) + /// VFNMSUBPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector256 ConvertToVector256Single(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector512 FusedMultiplySubtractNegated(Vector512 a, Vector512 b, Vector512 c) { throw new PlatformNotSupportedException(); } /// - /// __m256i _mm512_cvttpd_epi32 (__m512d a) - /// VCVTTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// __m512 _mm512_getexp_ps (__m512 a) + /// VGETEXPPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} /// - public static Vector256 ConvertToVector256Int32WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector512 GetExponent(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_getexp_pd (__m512d a) + /// VGETEXPPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// + public static Vector512 GetExponent(Vector512 value) { throw new PlatformNotSupportedException(); } /// - /// __m512d _mm512_cvtepi32_pd (__m256i a) - /// VCVTDQ2PD zmm1 {k1}{z}, ymm2/m256/m32bcst + /// __m128 _mm_getexp_ss (__m128 a) + /// VGETEXPSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} /// - public static Vector512 ConvertToVector512Double(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetExponentScalar(Vector128 value) { throw new PlatformNotSupportedException(); } /// - /// __m512d _mm512_cvtps_pd (__m256 a) - /// VCVTPS2PD zmm1 {k1}{z}, ymm2/m256/m32bcst{sae} + /// __m128d _mm_getexp_sd (__m128d a) + /// VGETEXPSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} /// - public static Vector512 ConvertToVector512Double(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetExponentScalar(Vector128 value) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi8_epi32 (__m128i a) - /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// __m128 _mm_getexp_ss (__m128 a, __m128 b) + /// VGETEXPSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int32(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetExponentScalar(Vector128 upper, Vector128 value) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu8_epi32 (__m128i a) - /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// __m128d _mm_getexp_sd (__m128d a, __m128d b) + /// VGETEXPSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int32(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetExponentScalar(Vector128 upper, Vector128 value) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_cvtepi16_epi32 (__m128i a) - /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512 _mm512_getmant_ps (__m512 a) + /// VGETMANTPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} /// - public static Vector512 ConvertToVector512Int32(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector512 GetMantissa(Vector512 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu16_epi32 (__m128i a) - /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512d _mm512_getmant_pd (__m512d a) + /// VGETMANTPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae} /// - public static Vector512 ConvertToVector512Int32(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector512 GetMantissa(Vector512 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_cvtps_epi32 (__m512 a) - /// VCVTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// __m128 _mm_getmant_ss (__m128 a) + /// VGETMANTSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} /// - public static Vector512 ConvertToVector512Int32(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetMantissaScalar(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi8_epi64 (__m128i a) - /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m128d _mm_getmant_sd (__m128d a) + /// VGETMANTSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} /// - public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetMantissaScalar(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu8_epi64 (__m128i a) - /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m128 _mm_getmant_ss (__m128 a, __m128 b) + /// VGETMANTSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetMantissaScalar(Vector128 upper, Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi16_epi64 (__m128i a) - /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m128d _mm_getmant_sd (__m128d a, __m128d b) + /// VGETMANTSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 GetMantissaScalar(Vector128 upper, Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_cvtepu16_epi64 (__m128i a) - /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Int64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi32_epi64 (__m128i a) - /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Int64(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu32_epi64 (__m128i a) - /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Int64(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512 _mm512_cvtepi32_ps (__m512i a) - /// VCVTDQ2PS zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Single(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi8_epi32 (__m128i a) - /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti32x4_epi32 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu8_epi32 (__m128i a) - /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti32x4_epi32 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi16_epi32 (__m128i a) - /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu16_epi32 (__m128i a) - /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi8_epi64 (__m128i a) - /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m512 _mm512_insertf32x4_ps (__m512 a, __m128 b, int imm8) + /// VINSERTF32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu8_epi64 (__m128i a) - /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m512d _mm512_insertf128_pd (__m512d a, __m128d b, int imm8) + /// VINSERTF32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } + /// - /// __m512i _mm512_cvtepi16_epi64 (__m128i a) - /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu16_epi64 (__m128i a) - /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepi32_epi64 (__m128i a) - /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector256 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvtepu32_epi64 (__m128i a) - /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector256 value) { throw new PlatformNotSupportedException(); } - + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512i _mm512_cvttps_epi32 (__m512 a) - /// VCVTTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512Int32WithTruncation(Vector512 value) { throw new PlatformNotSupportedException(); } - + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512 _mm512_div_ps (__m512 a, __m512 b) - /// VDIVPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er} + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 Divide(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512d _mm512_div_pd (__m512d a, __m512d b) - /// VDIVPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{er} + /// __m512i _mm512_inserti64x4_epi64 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 Divide(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } - + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512 _mm512_moveldup_ps (__m512 a) - /// VMOVSLDUP zmm1 {k1}{z}, zmm2/m512 + /// __m512i _mm512_inserti64x4_epi64 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 DuplicateEvenIndexed(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512d _mm512_movedup_pd (__m512d a) - /// VMOVDDUP zmm1 {k1}{z}, zmm2/m512 + /// __m512 _mm512_insertf256_ps (__m512 a, __m256 b, int imm8) + /// VINSERTF64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 DuplicateEvenIndexed(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// - /// __m512 _mm512_movehdup_ps (__m512 a) - /// VMOVSHDUP zmm1 {k1}{z}, zmm2/m512 + /// __m512d _mm512_insertf64x4_pd (__m512d a, __m256d b, int imm8) + /// VINSERTF64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 DuplicateOddIndexed(Vector512 value) { throw new PlatformNotSupportedException(); } + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) { throw new PlatformNotSupportedException(); } /// /// __m512i _mm512_load_si512 (__m512i const * mem_addr) @@ -679,6 +1902,202 @@ internal X64() { } /// public static Vector512 Or(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_permute_pd (__m512d a, int imm8) + /// VPERMILPD zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute2x64(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_permute_ps (__m512 a, int imm8) + /// VPERMILPS zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 Permute4x32(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_permute4x64_epi64 (__m512i a, const int imm8) + /// VPERMQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute4x64(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_permute4x64_epi64 (__m512i a, const int imm8) + /// VPERMQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute4x64(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_permute4x64_pd (__m512d a, const int imm8) + /// VPERMPD zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute4x64(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512d _mm512_permutevar_pd (__m512d a, __m512i b) + /// VPERMILPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar2x64(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_permutevar_ps (__m512 a, __m512i b) + /// VPERMILPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar4x32(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_permutevar8x64_epi64 (__m512i a, __m512i b) + /// VPERMQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar8x64(Vector512 value, Vector512 control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_permutevar8x64_epi64 (__m512i a, __m512i b) + /// VPERMQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar8x64(Vector512 value, Vector512 control) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_permutevar8x64_pd (__m512d a, __m512i b) + /// VPERMPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar8x64(Vector512 value, Vector512 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_permutevar16x32_epi32 (__m512i a, __m512i b) + /// VPERMD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar16x32(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_permutevar16x32_epi32 (__m512i a, __m512i b) + /// VPERMD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar16x32(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_permutevar16x32_ps (__m512 a, __m512i b) + /// VPERMPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar16x32(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_rcp14_ps (__m512 a, __m512 b) + /// VRCP14PS zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 Reciprocal14(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_rcp14_pd (__m512d a, __m512d b) + /// VRCP14PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 Reciprocal14(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_rcp14_ss (__m128 a) + /// VRCP14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// + public static Vector128 Reciprocal14Scalar(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_rcp14_sd (__m128d a) + /// VRCP14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// + public static Vector128 Reciprocal14Scalar(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm_rcp14_ss (__m128 a, __m128 b) + /// VRCP14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 Reciprocal14Scalar(Vector128 upper, Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_rcp14_sd (__m128d a, __m128d b) + /// VRCP14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 Reciprocal14Scalar(Vector128 upper, Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_rsqrt14_ps (__m512 a, __m512 b) + /// VRSQRT14PS zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 ReciprocalSqrt14(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_rsqrt14_pd (__m512d a, __m512d b) + /// VRSQRT14PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 ReciprocalSqrt14(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_rsqrt14_ss (__m128 a) + /// VRSQRT14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_rsqrt14_sd (__m128d a) + /// VRSQRT14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm_rsqrt14_ss (__m128 a, __m128 b) + /// VRSQRT14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 upper, Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_rsqrt14_sd (__m128d a, __m128d b) + /// VRSQRT14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 upper, Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_roundscale_ps (__m512 a, int imm) + /// VRNDSCALEPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae}, imm8 + /// + public static Vector512 RoundScale(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_roundscale_pd (__m512d a, int imm) + /// VRNDSCALEPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae}, imm8 + /// + public static Vector512 RoundScale(Vector512 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_roundscale_ss (__m128 a, int imm) + /// VRNDSCALESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 RoundScaleScalar(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_roundscale_sd (__m128d a, int imm) + /// VRNDSCALESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// + public static Vector128 RoundScaleScalar(Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm_roundscale_ss (__m128 a, __m128 b, int imm) + /// VRNDSCALESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 RoundScaleScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_roundscale_sd (__m128d a, __m128d b, int imm) + /// VRNDSCALESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 RoundScaleScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// __m512 _mm512_scalef_ps (__m512 a, __m512 b) + /// VSCALEFPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er} + /// + public static Vector512 Scale(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_scalef_pd (__m512d a, __m512d b) + /// VSCALEFPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{er} + /// + public static Vector512 Scale(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + + /// + /// __m128 _mm_scalef_ss (__m128 a, __m128 b) + /// VSCALEFSS xmm1 {k1}{z}, xmm2, xmm3/m32{er} + /// + public static Vector128 ScaleScalar(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_scalef_sd (__m128d a, __m128d b) + /// VSCALEFSD xmm1 {k1}{z}, xmm2, xmm3/m64{er} + /// + public static Vector128 ScaleScalar(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_sll_epi32 (__m512i a, __m128i count) /// VPSLLD zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -722,6 +2141,27 @@ internal X64() { } /// public static Vector512 ShiftLeftLogical(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_sllv_epi32 (__m512i a, __m512i count) + /// VPSLLVD ymm1 {k1}{z}, ymm2, ymm3/m512/m32bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_sllv_epi32 (__m512i a, __m512i count) + /// VPSLLVD ymm1 {k1}{z}, ymm2, ymm3/m512/m32bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_sllv_epi64 (__m512i a, __m512i count) + /// VPSLLVQ ymm1 {k1}{z}, ymm2, ymm3/m512/m64bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_sllv_epi64 (__m512i a, __m512i count) + /// VPSLLVQ ymm1 {k1}{z}, ymm2, ymm3/m512/m64bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// /// _mm512_sra_epi32 (__m512i a, __m128i count) /// VPSRAD zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -744,6 +2184,17 @@ internal X64() { } /// public static Vector512 ShiftRightArithmetic(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srav_epi32 (__m512i a, __m512i count) + /// VPSRAVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftRightArithmeticVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srav_epi64 (__m512i a, __m512i count) + /// VPSRAVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftRightArithmeticVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_srl_epi32 (__m512i a, __m128i count) /// VPSRLD zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -786,6 +2237,27 @@ internal X64() { } /// public static Vector512 ShiftRightLogical(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srlv_epi32 (__m512i a, __m512i count) + /// VPSRLVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srlv_epi32 (__m512i a, __m512i count) + /// VPSRLVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srlv_epi64 (__m512i a, __m512i count) + /// VPSRLVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_srlv_epi64 (__m512i a, __m512i count) + /// VPSRLVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_shuffle_epi32 (__m512i a, const int imm8) /// VPSHUFD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs index 3b787d30a8ea11..b687677a844ddf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs @@ -33,6 +33,438 @@ internal VL() { } /// public static Vector256 Abs(Vector256 value) => Abs(value); + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector128 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Byte(Vector256 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm_cvtusepi32_epi8 (__m128i a) + /// VPMOVUSDB xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector128 value) => ConvertToVector128ByteWithSaturation(value); + /// + /// __m128i _mm_cvtusepi64_epi8 (__m128i a) + /// VPMOVUSQB xmm1/m16 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector128 value) => ConvertToVector128ByteWithSaturation(value); + /// + /// __m128i _mm256_cvtusepi32_epi8 (__m256i a) + /// VPMOVUSDB xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector256 value) => ConvertToVector128ByteWithSaturation(value); + /// + /// __m128i _mm256_cvtusepi64_epi8 (__m256i a) + /// VPMOVUSQB xmm1/m32 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector256 value) => ConvertToVector128ByteWithSaturation(value); + + /// + /// __m128d _mm_cvtepu32_pd (__m128i a) + /// VCVTUDQ2PD xmm1 {k1}{z}, xmm2/m64/m32bcst + /// + public static Vector128 ConvertToVector128Double(Vector128 value) => ConvertToVector128Double(value); + + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector128 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector256 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm_cvtsepi32_epi16 (__m128i a) + /// VPMOVSDW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector128 value) => ConvertToVector128Int16WithSaturation(value); + /// + /// __m128i _mm_cvtsepi64_epi16 (__m128i a) + /// VPMOVSQW xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector128 value) => ConvertToVector128Int16WithSaturation(value); + /// + /// __m128i _mm256_cvtsepi32_epi16 (__m256i a) + /// VPMOVSDW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector256 value) => ConvertToVector128Int16WithSaturation(value); + /// + /// __m128i _mm256_cvtsepi64_epi16 (__m256i a) + /// VPMOVSQW xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector256 value) => ConvertToVector128Int16WithSaturation(value); + + /// + /// __m128i _mm_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Int32(Vector128 value) => ConvertToVector128Int32(value); + /// + /// __m128i _mm_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Int32(Vector128 value) => ConvertToVector128Int32(value); + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Int32(Vector256 value) => ConvertToVector128Int32(value); + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Int32(Vector256 value) => ConvertToVector128Int32(value); + /// + /// __m128i _mm128_cvtsepi64_epi32 (__m128i a) + /// VPMOVSQD xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128Int32WithSaturation(Vector128 value) => ConvertToVector128Int32WithSaturation(value); + /// + /// __m128i _mm256_cvtsepi64_epi32 (__m256i a) + /// VPMOVSQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128Int32WithSaturation(Vector256 value) => ConvertToVector128Int32WithSaturation(value); + + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm_cvtepi32_epi8 (__m128i a) + /// VPMOVDB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm_cvtepi64_epi8 (__m128i a) + /// VPMOVQB xmm1/m16 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector128 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm256_cvtepi32_epi8 (__m256i a) + /// VPMOVDB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm256_cvtepi64_epi8 (__m256i a) + /// VPMOVQB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector256 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm_cvtsepi32_epi8 (__m128i a) + /// VPMOVSDB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector128 value) => ConvertToVector128SByteWithSaturation(value); + /// + /// __m128i _mm_cvtsepi64_epi8 (__m128i a) + /// VPMOVSQB xmm1/m16 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector128 value) => ConvertToVector128SByteWithSaturation(value); + /// + /// __m128i _mm256_cvtsepi32_epi8 (__m256i a) + /// VPMOVSDB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector256 value) => ConvertToVector128SByteWithSaturation(value); + /// + /// __m128i _mm256_cvtsepi64_epi8 (__m256i a) + /// VPMOVSQB xmm1/m32 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector256 value) => ConvertToVector128SByteWithSaturation(value); + + /// + /// __m128 _mm_cvtepu32_ps (__m128i a) + /// VCVTUDQ2PS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToVector128Single(Vector128 value) => ConvertToVector128Single(value); + + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm_cvtepi32_epi16 (__m128i a) + /// VPMOVDW xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm_cvtepi64_epi16 (__m128i a) + /// VPMOVQW xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm256_cvtepi32_epi16 (__m256i a) + /// VPMOVDW xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm256_cvtepi64_epi16 (__m256i a) + /// VPMOVQW xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector256 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm_cvtusepi32_epi16 (__m128i a) + /// VPMOVUSDW xmm1/m64 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector128 value) => ConvertToVector128UInt16WithSaturation(value); + /// + /// __m128i _mm_cvtusepi64_epi16 (__m128i a) + /// VPMOVUSQW xmm1/m32 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector128 value) => ConvertToVector128UInt16WithSaturation(value); + /// + /// __m128i _mm256_cvtusepi32_epi16 (__m256i a) + /// VPMOVUSDW xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector256 value) => ConvertToVector128UInt16WithSaturation(value); + /// + /// __m128i _mm256_cvtusepi64_epi16 (__m256i a) + /// VPMOVUSQW xmm1/m64 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector256 value) => ConvertToVector128UInt16WithSaturation(value); + + /// + /// __m128i _mm128_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m128 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) => ConvertToVector128UInt32(value); + /// + /// __m128i _mm128_cvtepi64_epi32 (__m128i a) + /// VPMOVQD xmm1/m128 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) => ConvertToVector128UInt32(value); + /// + /// __m128i _mm_cvtps_epu32 (__m128 a) + /// VCVTPS2UDQ xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) => ConvertToVector128UInt32(value); + /// + /// __m128i _mm_cvtpd_epu32 (__m128d a) + /// VCVTPD2UDQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) => ConvertToVector128UInt32(value); + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value) => ConvertToVector128UInt32(value); + /// + /// __m128i _mm256_cvtepi64_epi32 (__m256i a) + /// VPMOVQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value) => ConvertToVector128UInt32(value); + /// + /// __m128i _mm256_cvtpd_epu32 (__m256d a) + /// VCVTPD2UDQ xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value) => ConvertToVector128UInt32(value); + /// + /// __m128i _mm128_cvtusepi64_epi32 (__m128i a) + /// VPMOVUSQD xmm1/m128 {k1}{z}, xmm2 + /// + public static Vector128 ConvertToVector128UInt32WithSaturation(Vector128 value) => ConvertToVector128UInt32WithSaturation(value); + /// + /// __m128i _mm256_cvtusepi64_epi32 (__m256i a) + /// VPMOVUSQD xmm1/m128 {k1}{z}, ymm2 + /// + public static Vector128 ConvertToVector128UInt32WithSaturation(Vector256 value) => ConvertToVector128UInt32WithSaturation(value); + /// + /// __m128i _mm_cvttps_epu32 (__m128 a) + /// VCVTTPS2UDQ xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToVector128UInt32WithTruncation(Vector128 value) => ConvertToVector128UInt32WithTruncation(value); + /// + /// __m128i _mm_cvttpd_epu32 (__m128d a) + /// VCVTTPD2UDQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ConvertToVector128UInt32WithTruncation(Vector128 value) => ConvertToVector128UInt32WithTruncation(value); + /// + /// __m128i _mm256_cvttpd_epu32 (__m256d a) + /// VCVTTPD2UDQ xmm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector128 ConvertToVector128UInt32WithTruncation(Vector256 value) => ConvertToVector128UInt32WithTruncation(value); + + /// + /// __m256d _mm512_cvtepu32_pd (__m128i a) + /// VCVTUDQ2PD ymm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector256 ConvertToVector256Double(Vector128 value) => ConvertToVector256Double(value); + /// + /// __m256 _mm256_cvtepu32_ps (__m256i a) + /// VCVTUDQ2PS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ConvertToVector256Single(Vector256 value) => ConvertToVector256Single(value); + /// + /// __m256i _mm256_cvtps_epu32 (__m256 a) + /// VCVTPS2UDQ ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ConvertToVector256UInt32(Vector256 value) => ConvertToVector256UInt32(value); + /// + /// __m256i _mm256_cvttps_epu32 (__m256 a) + /// VCVTTPS2UDQ ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ConvertToVector256UInt32WithTruncation(Vector256 value) => ConvertToVector256UInt32WithTruncation(value); + + /// + /// __m128 _mm_fixupimm_ps(__m128 a, __m128 b, __m128i tbl, int imm); + /// VFIXUPIMMPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 Fixup(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) => Fixup(left, right, table, control); + /// + /// __m128d _mm_fixupimm_pd(__m128d a, __m128d b, __m128i tbl, int imm); + /// VFIXUPIMMPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 Fixup(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) => Fixup(left, right, table, control); + /// + /// __m256 _mm256_fixupimm_ps(__m256 a, __m256 b, __m256i tbl, int imm); + /// VFIXUPIMMPS ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 Fixup(Vector256 left, Vector256 right, Vector256 table, [ConstantExpected] byte control) => Fixup(left, right, table, control); + /// + /// __m256d _mm256_fixupimm_pd(__m256d a, __m256d b, __m256i tbl, int imm); + /// VFIXUPIMMPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 Fixup(Vector256 left, Vector256 right, Vector256 table, [ConstantExpected] byte control) => Fixup(left, right, table, control); + + /// + /// __m128 _mm_getexp_ps (__m128 a) + /// VGETEXPPS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 GetExponent(Vector128 value) => GetExponent(value); + /// + /// __m128d _mm_getexp_pd (__m128d a) + /// VGETEXPPD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 GetExponent(Vector128 value) => GetExponent(value); + /// + /// __m256 _mm256_getexp_ps (__m256 a) + /// VGETEXPPS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 GetExponent(Vector256 value) => GetExponent(value); + /// + /// __m256d _mm256_getexp_pd (__m256d a) + /// VGETEXPPD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 GetExponent(Vector256 value) => GetExponent(value); + + /// + /// __m128 _mm_getmant_ps (__m128 a) + /// VGETMANTPS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 GetMantissa(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissa(value, control); + /// + /// __m128d _mm_getmant_pd (__m128d a) + /// VGETMANTPD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 GetMantissa(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissa(value, control); + /// + /// __m256 _mm256_getmant_ps (__m256 a) + /// VGETMANTPS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 GetMantissa(Vector256 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissa(value, control); + /// + /// __m256d _mm256_getmant_pd (__m256d a) + /// VGETMANTPD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 GetMantissa(Vector256 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissa(value, control); + /// /// __m128i _mm_max_epi64 (__m128i a, __m128i b) /// VPMAXSQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst @@ -75,6 +507,106 @@ internal VL() { } /// public static Vector256 Min(Vector256 left, Vector256 right) => Min(left, right); + /// + /// __m256i _mm256_permute4x64_epi64 (__m256i a, __m256i b) + /// VPERMQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 PermuteVar4x64(Vector256 value, Vector256 control) => PermuteVar4x64(value, control); + /// + /// __m256i _mm256_permute4x64_pd (__m256d a, __m256i b) + /// VPERMQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 PermuteVar4x64(Vector256 value, Vector256 control) => PermuteVar4x64(value, control); + /// + /// __m256d _mm256_permute4x64_pd (__m256d a, __m256i b) + /// VPERMPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 PermuteVar4x64(Vector256 value, Vector256 control) => PermuteVar4x64(value, control); + + /// + /// __m128 _mm_rcp14_ps (__m128 a, __m128 b) + /// VRCP14PS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 Reciprocal14(Vector128 value) => Reciprocal14(value); + /// + /// __m128d _mm_rcp14_pd (__m128d a, __m128d b) + /// VRCP14PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 Reciprocal14(Vector128 value) => Reciprocal14(value); + /// + /// __m256 _mm256_rcp14_ps (__m256 a, __m256 b) + /// VRCP14PS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 Reciprocal14(Vector256 value) => Reciprocal14(value); + /// + /// __m256d _mm256_rcp14_pd (__m256d a, __m256d b) + /// VRCP14PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 Reciprocal14(Vector256 value) => Reciprocal14(value); + + /// + /// __m128 _mm_rsqrt14_ps (__m128 a, __m128 b) + /// VRSQRT14PS xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ReciprocalSqrt14(Vector128 value) => ReciprocalSqrt14(value); + /// + /// __m128d _mm_rsqrt14_pd (__m128d a, __m128d b) + /// VRSQRT14PD xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 ReciprocalSqrt14(Vector128 value) => ReciprocalSqrt14(value); + /// + /// __m256 _mm256_rsqrt14_ps (__m256 a, __m256 b) + /// VRSQRT14PS ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 ReciprocalSqrt14(Vector256 value) => ReciprocalSqrt14(value); + /// + /// __m256d _mm256_rsqrt14_pd (__m256d a, __m256d b) + /// VRSQRT14PD ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 ReciprocalSqrt14(Vector256 value) => ReciprocalSqrt14(value); + + /// + /// __m128 _mm_roundscale_ps (__m128 a, int imm) + /// VRNDSCALEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RoundScale(Vector128 value, [ConstantExpected] byte control) => RoundScale(value, control); + /// + /// __m128d _mm_roundscale_pd (__m128d a, int imm) + /// VRNDSCALEPD xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RoundScale(Vector128 value, [ConstantExpected] byte control) => RoundScale(value, control); + /// + /// __m256 _mm256_roundscale_ps (__m256 a, int imm) + /// VRNDSCALEPS ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RoundScale(Vector256 value, [ConstantExpected] byte control) => RoundScale(value, control); + /// + /// __m256d _mm256_roundscale_pd (__m256d a, int imm) + /// VRNDSCALEPD ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RoundScale(Vector256 value, [ConstantExpected] byte control) => RoundScale(value, control); + + /// + /// __m128 _mm_scalef_ps (__m128 a, int imm) + /// VSCALEFPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 Scale(Vector128 left, Vector128 right) => Scale(left, right); + /// + /// __m128d _mm_scalef_pd (__m128d a, int imm) + /// VSCALEFPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 Scale(Vector128 left, Vector128 right) => Scale(left, right); + /// + /// __m256 _mm256_scalef_ps (__m256 a, int imm) + /// VSCALEFPS ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 Scale(Vector256 left, Vector256 right) => Scale(left, right); + /// + /// __m256d _mm256_scalef_pd (__m256d a, int imm) + /// VSCALEFPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 Scale(Vector256 left, Vector256 right) => Scale(left, right); + /// /// __m128i _mm_sra_epi64 (__m128i a, __m128i count) /// VPSRAQ xmm1 {k1}{z}, xmm2, xmm3/m128 @@ -96,6 +628,17 @@ internal VL() { } /// VPSRAQ ymm1 {k1}{z}, ymm2, imm8 /// public static Vector256 ShiftRightArithmetic(Vector256 value, [ConstantExpected] byte count) => ShiftRightArithmetic(value, count); + + /// + /// __m128i _mm_srav_epi64 (__m128i a, __m128i count) + /// VPSRAVQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 ShiftRightArithmeticVariable(Vector128 value, Vector128 count) => ShiftRightArithmeticVariable(value, count); + /// + /// __m256i _mm256_srav_epi64 (__m256i a, __m256i count) + /// VPSRAVQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 ShiftRightArithmeticVariable(Vector256 value, Vector256 count) => ShiftRightArithmeticVariable(value, count); } [Intrinsic] @@ -104,6 +647,45 @@ internal VL() { } internal X64() { } public static new bool IsSupported { get => IsSupported; } + + /// + /// __m128 _mm_cvtsi64_ss (__m128 a, __int64 b) + /// VCVTUSI2SS xmm1, xmm2, r/m64 + /// This intrinsic is only available on 64-bit processes + /// + public static Vector128 ConvertScalarToVector128Single(Vector128 upper, ulong value) => ConvertScalarToVector128Single(upper, value); + /// + /// __m128d _mm_cvtsi64_sd (__m128d a, __int64 b) + /// VCVTUSI2SD xmm1, xmm2, r/m64 + /// This intrinsic is only available on 64-bit processes + /// + public static Vector128 ConvertScalarToVector128Double(Vector128 upper, ulong value) => ConvertScalarToVector128Double(upper, value); + + /// + /// unsigned __int64 _mm_cvtss_u64 (__m128 a) + /// VCVTSS2USI r64, xmm1/m32{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64(Vector128 value) => ConvertToUInt64(value); + /// + /// unsigned __int64 _mm_cvtsd_u64 (__m128d a) + /// VCVTSD2USI r64, xmm1/m64{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64(Vector128 value) => ConvertToUInt64(value); + + /// + /// unsigned __int64 _mm_cvttss_u64 (__m128 a) + /// VCVTTSS2USI r64, xmm1/m32{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64WithTruncation(Vector128 value) => ConvertToUInt64WithTruncation(value); + /// + /// unsigned __int64 _mm_cvttsd_u64 (__m128d a) + /// VCVTTSD2USI r64, xmm1/m64{er} + /// This intrinsic is only available on 64-bit processes + /// + public static ulong ConvertToUInt64WithTruncation(Vector128 value) => ConvertToUInt64WithTruncation(value); } /// @@ -172,235 +754,876 @@ internal X64() { } /// __m512i _mm512_and_epi32 (__m512i a, __m512i b) /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + /// + /// __m512i _mm512_and_epi32 (__m512i a, __m512i b) + /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + /// + /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) + /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + /// + /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) + /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) + /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) + /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + /// + /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) + /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + + /// + /// __m512i _mm512_broadcastd_epi32 (__m128i a) + /// VPBROADCASTD zmm1 {k1}{z}, xmm2/m32 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512i _mm512_broadcastd_epi32 (__m128i a) + /// VPBROADCASTD zmm1 {k1}{z}, xmm2/m32 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512i _mm512_broadcastq_epi64 (__m128i a) + /// VPBROADCASTQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512i _mm512_broadcastq_epi64 (__m128i a) + /// VPBROADCASTQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512 _mm512_broadcastss_ps (__m128 a) + /// VBROADCASTSS zmm1 {k1}{z}, xmm2/m32 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + /// + /// __m512d _mm512_broadcastsd_pd (__m128d a) + /// VBROADCASTSD zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 BroadcastScalarToVector512(Vector128 value) => BroadcastScalarToVector512(value); + + /// + /// __m512i _mm512_broadcast_i32x4 (__m128i const * mem_addr) + /// VBROADCASTI32x4 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(int* address) => BroadcastVector128ToVector512(address); + /// + /// __m512i _mm512_broadcast_i32x4 (__m128i const * mem_addr) + /// VBROADCASTI32x4 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(uint* address) => BroadcastVector128ToVector512(address); + /// + /// __m512 _mm512_broadcast_f32x4 (__m128 const * mem_addr) + /// VBROADCASTF32x4 zmm1 {k1}{z}, m128 + /// + public static unsafe Vector512 BroadcastVector128ToVector512(float* address) => BroadcastVector128ToVector512(address); + + /// + /// __m512i _mm512_broadcast_i64x4 (__m256i const * mem_addr) + /// VBROADCASTI64x4 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(long* address) => BroadcastVector256ToVector512(address); + /// + /// __m512i _mm512_broadcast_i64x4 (__m256i const * mem_addr) + /// VBROADCASTI64x4 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(ulong* address) => BroadcastVector256ToVector512(address); + /// + /// __m512d _mm512_broadcast_f64x4 (__m256d const * mem_addr) + /// VBROADCASTF64x4 zmm1 {k1}{z}, m256 + /// + public static unsafe Vector512 BroadcastVector256ToVector512(double* address) => BroadcastVector256ToVector512(address); + + /// + /// __m128 _mm_cvtsi32_ss (__m128 a, int b) + /// VCVTUSI2SS xmm1, xmm2, r/m32 + /// + public static Vector128 ConvertScalarToVector128Single(Vector128 upper, uint value) => ConvertScalarToVector128Single(upper, value); + /// + /// __m128d _mm_cvtsi32_sd (__m128d a, int b) + /// VCVTUSI2SD xmm1, xmm2, r/m32 + /// + public static Vector128 ConvertScalarToVector128Double(Vector128 upper, uint value) => ConvertScalarToVector128Double(upper, value); + + /// + /// unsigned int _mm_cvtss_u32 (__m128 a) + /// VCVTSS2USI r32, xmm1/m32{er} + /// + public static uint ConvertToUInt32(Vector128 value) => ConvertToUInt32(value); + /// + /// unsigned int _mm_cvtsd_u32 (__m128d a) + /// VCVTSD2USI r32, xmm1/m64{er} + /// + public static uint ConvertToUInt32(Vector128 value) => ConvertToUInt32(value); + /// + /// unsigned int _mm_cvttss_u32 (__m128 a) + /// VCVTTSS2USI r32, xmm1/m32{er} + /// + public static uint ConvertToUInt32WithTruncation(Vector128 value) => ConvertToUInt32WithTruncation(value); + /// + /// unsigned int _mm_cvttsd_u32 (__m128d a) + /// VCVTTSD2USI r32, xmm1/m64{er} + /// + public static uint ConvertToUInt32WithTruncation(Vector128 value) => ConvertToUInt32WithTruncation(value); + + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Byte(Vector512 value) => ConvertToVector128Byte(value); + /// + /// __m128i _mm512_cvtusepi32_epi8 (__m512i a) + /// VPMOVUSDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector512 value) => ConvertToVector128ByteWithSaturation(value); + /// + /// __m128i _mm512_cvtusepi64_epi8 (__m512i a) + /// VPMOVUSQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128ByteWithSaturation(Vector512 value) => ConvertToVector128ByteWithSaturation(value); + + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector512 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16(Vector512 value) => ConvertToVector128Int16(value); + /// + /// __m128i _mm512_cvtsepi64_epi16 (__m512i a) + /// VPMOVSQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128Int16WithSaturation(Vector512 value) => ConvertToVector128Int16WithSaturation(value); + + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm512_cvtepi32_epi8 (__m512i a) + /// VPMOVDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm512_cvtepi64_epi8 (__m512i a) + /// VPMOVQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByte(Vector512 value) => ConvertToVector128SByte(value); + /// + /// __m128i _mm512_cvtsepi32_epi8 (__m512i a) + /// VPMOVSDB xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector512 value) => ConvertToVector128SByteWithSaturation(value); + /// + /// __m128i _mm512_cvtsepi64_epi8 (__m512i a) + /// VPMOVSQB xmm1/m64 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128SByteWithSaturation(Vector512 value) => ConvertToVector128SByteWithSaturation(value); + + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector512 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm512_cvtepi64_epi16 (__m512i a) + /// VPMOVQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128UInt16(Vector512 value) => ConvertToVector128UInt16(value); + /// + /// __m128i _mm512_cvtusepi64_epi16 (__m512i a) + /// VPMOVUSQW xmm1/m128 {k1}{z}, zmm2 + /// + public static Vector128 ConvertToVector128UInt16WithSaturation(Vector512 value) => ConvertToVector128UInt16WithSaturation(value); + + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int16(Vector512 value) => ConvertToVector256Int16(value); + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int16(Vector512 value) => ConvertToVector256Int16(value); + /// + /// __m256i _mm512_cvtsepi32_epi16 (__m512i a) + /// VPMOVSDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int16WithSaturation(Vector512 value) => ConvertToVector256Int16WithSaturation(value); + + /// + /// __m256i _mm512_cvtpd_epi32 (__m512d a) + /// VCVTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256Int32(Vector512 value) => ConvertToVector256Int32(value); + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int32(Vector512 value) => ConvertToVector256Int32(value); + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int32(Vector512 value) => ConvertToVector256Int32(value); + /// + /// __m256i _mm512_cvtsepi64_epi32 (__m512i a) + /// VPMOVSQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256Int32WithSaturation(Vector512 value) => ConvertToVector256Int32WithSaturation(value); + /// + /// __m256i _mm512_cvttpd_epi32 (__m512d a) + /// VCVTTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// + public static Vector256 ConvertToVector256Int32WithTruncation(Vector512 value) => ConvertToVector256Int32WithTruncation(value); + + /// + /// __m256 _mm512_cvtpd_ps (__m512d a) + /// VCVTPD2PS ymm1, zmm2/m512 + /// VCVTPD2PS ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256Single(Vector512 value) => ConvertToVector256Single(value); + + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt16(Vector512 value) => ConvertToVector256UInt16(value); + /// + /// __m256i _mm512_cvtepi32_epi16 (__m512i a) + /// VPMOVDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt16(Vector512 value) => ConvertToVector256UInt16(value); + /// + /// __m256i _mm512_cvtusepi32_epi16 (__m512i a) + /// VPMOVUSDW ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt16WithSaturation(Vector512 value) => ConvertToVector256UInt16WithSaturation(value); + + /// + /// __m256i _mm512_cvtpd_epu32 (__m512d a) + /// VCVTPD2UDQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256UInt32(Vector512 value) => ConvertToVector256UInt32(value); + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt32(Vector512 value) => ConvertToVector256UInt32(value); + /// + /// __m256i _mm512_cvtepi64_epi32 (__m512i a) + /// VPMOVQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt32(Vector512 value) => ConvertToVector256UInt32(value); + /// + /// __m256i _mm512_cvtusepi64_epi32 (__m512i a) + /// VPMOVUSQD ymm1/m256 {k1}{z}, zmm2 + /// + public static Vector256 ConvertToVector256UInt32WithSaturation(Vector512 value) => ConvertToVector256UInt32WithSaturation(value); + /// + /// __m256i _mm512_cvttpd_epu32 (__m512d a) + /// VCVTTPD2UDQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// + public static Vector256 ConvertToVector256UInt32WithTruncation(Vector512 value) => ConvertToVector256UInt32WithTruncation(value); + + /// + /// __m512d _mm512_cvtepi32_pd (__m256i a) + /// VCVTDQ2PD zmm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector512 ConvertToVector512Double(Vector256 value) => ConvertToVector512Double(value); + /// + /// __m512d _mm512_cvtps_pd (__m256 a) + /// VCVTPS2PD zmm1 {k1}{z}, ymm2/m256/m32bcst{sae} + /// + public static Vector512 ConvertToVector512Double(Vector256 value) => ConvertToVector512Double(value); + /// + /// __m512d _mm512_cvtepu32_pd (__m256i a) + /// VCVTUDQ2PD zmm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector512 ConvertToVector512Double(Vector256 value) => ConvertToVector512Double(value); + /// + /// __m512i _mm512_cvtepi8_epi32 (__m128i a) + /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int32(Vector128 value) => ConvertToVector512Int32(value); + /// + /// __m512i _mm512_cvtepu8_epi32 (__m128i a) + /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int32(Vector128 value) => ConvertToVector512Int32(value); + /// + /// __m512i _mm512_cvtepi16_epi32 (__m128i a) + /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int32(Vector256 value) => ConvertToVector512Int32(value); + /// + /// __m512i _mm512_cvtepu16_epi32 (__m128i a) + /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int32(Vector256 value) => ConvertToVector512Int32(value); + /// + /// __m512i _mm512_cvtps_epi32 (__m512 a) + /// VCVTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512Int32(Vector512 value) => ConvertToVector512Int32(value); + /// + /// __m512i _mm512_cvttps_epi32 (__m512 a) + /// VCVTTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} + /// + public static Vector512 ConvertToVector512Int32WithTruncation(Vector512 value) => ConvertToVector512Int32WithTruncation(value); + /// + /// __m512i _mm512_cvtepi8_epi64 (__m128i a) + /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + /// + /// __m512i _mm512_cvtepu8_epi64 (__m128i a) + /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + /// + /// __m512i _mm512_cvtepi16_epi64 (__m128i a) + /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + /// + /// __m512i _mm512_cvtepu16_epi64 (__m128i a) + /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + /// + /// __m512i _mm512_cvtepi32_epi64 (__m128i a) + /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int64(Vector256 value) => ConvertToVector512Int64(value); + /// + /// __m512i _mm512_cvtepu32_epi64 (__m128i a) + /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512Int64(Vector256 value) => ConvertToVector512Int64(value); + /// + /// __m512 _mm512_cvtepi32_ps (__m512i a) + /// VCVTDQ2PS zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512Single(Vector512 value) => ConvertToVector512Single(value); + /// + /// __m512 _mm512_cvtepu32_ps (__m512i a) + /// VCVTUDQ2PS zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512Single(Vector512 value) => ConvertToVector512Single(value); + /// + /// __m512i _mm512_cvtepi8_epi32 (__m128i a) + /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt32(Vector128 value) => ConvertToVector512UInt32(value); + /// + /// __m512i _mm512_cvtepu8_epi32 (__m128i a) + /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt32(Vector128 value) => ConvertToVector512UInt32(value); + /// + /// __m512i _mm512_cvtepi16_epi32 (__m128i a) + /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt32(Vector256 value) => ConvertToVector512UInt32(value); + /// + /// __m512i _mm512_cvtepu16_epi32 (__m128i a) + /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt32(Vector256 value) => ConvertToVector512UInt32(value); + /// + /// __m512i _mm512_cvtps_epu32 (__m512 a) + /// VCVTPS2UDQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt32(Vector512 value) => ConvertToVector512UInt32(value); + /// + /// __m512i _mm512_cvttps_epu32 (__m512 a) + /// VCVTTPS2UDQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// + public static Vector512 ConvertToVector512UInt32WithTruncation(Vector512 value) => ConvertToVector512UInt32WithTruncation(value); + /// + /// __m512i _mm512_cvtepi8_epi64 (__m128i a) + /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + /// + /// __m512i _mm512_cvtepu8_epi64 (__m128i a) + /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + /// + /// __m512i _mm512_cvtepi16_epi64 (__m128i a) + /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + /// + /// __m512i _mm512_cvtepu16_epi64 (__m128i a) + /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// + public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + /// + /// __m512i _mm512_cvtepi32_epi64 (__m128i a) + /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt64(Vector256 value) => ConvertToVector512UInt64(value); + /// + /// __m512i _mm512_cvtepu32_epi64 (__m128i a) + /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// + public static Vector512 ConvertToVector512UInt64(Vector256 value) => ConvertToVector512UInt64(value); + + /// + /// __m512 _mm512_div_ps (__m512 a, __m512 b) + /// VDIVPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er} + /// + public static Vector512 Divide(Vector512 left, Vector512 right) => Divide(left, right); + /// + /// __m512d _mm512_div_pd (__m512d a, __m512d b) + /// VDIVPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{er} + /// + public static Vector512 Divide(Vector512 left, Vector512 right) => Divide(left, right); + + /// + /// __m512 _mm512_moveldup_ps (__m512 a) + /// VMOVSLDUP zmm1 {k1}{z}, zmm2/m512 + /// + public static Vector512 DuplicateEvenIndexed(Vector512 value) => DuplicateEvenIndexed(value); + /// + /// __m512d _mm512_movedup_pd (__m512d a) + /// VMOVDDUP zmm1 {k1}{z}, zmm2/m512 + /// + public static Vector512 DuplicateEvenIndexed(Vector512 value) => DuplicateEvenIndexed(value); + /// + /// __m512 _mm512_movehdup_ps (__m512 a) + /// VMOVSHDUP zmm1 {k1}{z}, zmm2/m512 + /// + public static Vector512 DuplicateOddIndexed(Vector512 value) => DuplicateOddIndexed(value); + + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti32x4_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti32x4_epi32 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128i _mm512_extracti128_si512 (__m512i a, const int imm8) + /// VEXTRACTI32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128 _mm512_extractf32x4_ps (__m512 a, const int imm8) + /// VEXTRACTF32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + /// + /// __m128d _mm512_extractf128_pd (__m512d a, const int imm8) + /// VEXTRACTF32x4 xmm1/m128 {k1}{z}, zmm2, imm8 + /// + public static Vector128 ExtractVector128(Vector512 value, [ConstantExpected] byte index) => ExtractVector128(value, index); + + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti256_si512 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti64x4_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256i _mm512_extracti64x4_epi64 (__m512i a, const int imm8) + /// VEXTRACTI64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256 _mm512_extractf256_ps (__m512 a, const int imm8) + /// VEXTRACTF64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + /// + /// __m256d _mm512_extractf64x4_pd (__m512d a, const int imm8) + /// VEXTRACTF64x4 ymm1/m256 {k1}{z}, zmm2, imm8 + /// + public static Vector256 ExtractVector256(Vector512 value, [ConstantExpected] byte index) => ExtractVector256(value, index); + + /// + /// __m512 _mm512_fixupimm_ps(__m512 a, __m512 b, __m512i tbl, int imm); + /// VFIXUPIMMPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{sae}, imm8 + /// + public static Vector512 Fixup(Vector512 left, Vector512 right, Vector512 table, [ConstantExpected] byte control) => Fixup(left, right, table, control); + /// + /// __m512d _mm512_fixupimm_pd(__m512d a, __m512d b, __m512i tbl, int imm); + /// VFIXUPIMMPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{sae}, imm8 + /// + public static Vector512 Fixup(Vector512 left, Vector512 right, Vector512 table, [ConstantExpected] byte control) => Fixup(left, right, table, control); + + /// + /// __m128 _mm_fixupimm_ss(__m128 a, __m128 b, __m128i tbl, int imm); + /// VFIXUPIMMSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 FixupScalar(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) => FixupScalar(left, right, table, control); /// - /// __m512i _mm512_and_epi32 (__m512i a, __m512i b) - /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m128d _mm_fixupimm_sd(__m128d a, __m128d b, __m128i tbl, int imm); + /// VFIXUPIMMSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 /// - public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + public static Vector128 FixupScalar(Vector128 left, Vector128 right, Vector128 table, [ConstantExpected] byte control) => FixupScalar(left, right, table, control); + /// - /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) - /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512 _mm512_fmadd_ps (__m512 a, __m512 b, __m512 c) + /// VFMADDPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + public static Vector512 FusedMultiplyAdd(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplyAdd(a, b, c); /// - /// __m512i _mm512_and_epi64 (__m512i a, __m512i b) - /// VPANDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512d _mm512_fmadd_pd (__m512d a, __m512d b, __m512d c) + /// VFMADDPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 And(Vector512 left, Vector512 right) => And(left, right); + public static Vector512 FusedMultiplyAdd(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplyAdd(a, b, c); /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512 _mm512_fmaddsub_ps (__m512 a, __m512 b, __m512 c) + /// VFMADDSUBPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplyAddSubtract(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplyAddSubtract(a, b, c); /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512d _mm512_fmaddsub_pd (__m512d a, __m512d b, __m512d c) + /// VFMADDSUBPD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplyAddSubtract(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplyAddSubtract(a, b, c); + /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512 _mm512_fmsub_ps (__m512 a, __m512 b, __m512 c) + /// VFMSUBPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplySubtract(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplySubtract(a, b, c); /// - /// __m512i _mm512_andnot_si512 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512d _mm512_fmsub_pd (__m512d a, __m512d b, __m512d c) + /// VFMSUBPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplySubtract(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplySubtract(a, b, c); + /// - /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512 _mm512_fmsubadd_ps (__m512 a, __m512 b, __m512 c) + /// VFMSUBADDPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplySubtractAdd(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplySubtractAdd(a, b, c); /// - /// __m512i _mm512_andnot_epi32 (__m512i a, __m512i b) - /// VPANDND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// __m512d _mm512_fmsubadd_pd (__m512d a, __m512d b, __m512d c) + /// VFMSUBADDPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplySubtractAdd(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplySubtractAdd(a, b, c); + /// - /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) - /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512 _mm512_fnmadd_ps (__m512 a, __m512 b, __m512 c) + /// VFNMADDPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplyAddNegated(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplyAddNegated(a, b, c); /// - /// __m512i _mm512_andnot_epi64 (__m512i a, __m512i b) - /// VPANDNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// __m512d _mm512_fnmadd_pd (__m512d a, __m512d b, __m512d c) + /// VFNMADDPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector512 AndNot(Vector512 left, Vector512 right) => AndNot(left, right); + public static Vector512 FusedMultiplyAddNegated(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplyAddNegated(a, b, c); /// - /// __m256i _mm512_cvtpd_epi32 (__m512d a) - /// VCVTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// __m512 _mm512_fnmsub_ps (__m512 a, __m512 b, __m512 c) + /// VFNMSUBPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst /// - public static Vector256 ConvertToVector256Int32(Vector512 value) => ConvertToVector256Int32(value); + public static Vector512 FusedMultiplySubtractNegated(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplySubtractNegated(a, b, c); /// - /// __m256 _mm512_cvtpd_ps (__m512d a) - /// VCVTPD2PS ymm1, zmm2/m512 - /// VCVTPD2PS ymm1 {k1}{z}, zmm2/m512/m64bcst{er} + /// __m512d _mm512_fnmsub_pd (__m512d a, __m512d b, __m512d c) + /// VFNMSUBPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst /// - public static Vector256 ConvertToVector256Single(Vector512 value) => ConvertToVector256Single(value); + public static Vector512 FusedMultiplySubtractNegated(Vector512 a, Vector512 b, Vector512 c) => FusedMultiplySubtractNegated(a, b, c); /// - /// __m256i _mm512_cvttpd_epi32 (__m512d a) - /// VCVTTPD2DQ ymm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// __m512 _mm512_getexp_ps (__m512 a) + /// VGETEXPPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} /// - public static Vector256 ConvertToVector256Int32WithTruncation(Vector512 value) => ConvertToVector256Int32WithTruncation(value); + public static Vector512 GetExponent(Vector512 value) => GetExponent(value); + /// + /// __m512d _mm512_getexp_pd (__m512d a) + /// VGETEXPPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae} + /// + public static Vector512 GetExponent(Vector512 value) => GetExponent(value); /// - /// __m512d _mm512_cvtepi32_pd (__m256i a) - /// VCVTDQ2PD zmm1 {k1}{z}, ymm2/m256/m32bcst + /// __m128 _mm_getexp_ss (__m128 a) + /// VGETEXPSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} /// - public static Vector512 ConvertToVector512Double(Vector256 value) => ConvertToVector512Double(value); + public static Vector128 GetExponentScalar(Vector128 value) => GetExponentScalar(value); /// - /// __m512d _mm512_cvtps_pd (__m256 a) - /// VCVTPS2PD zmm1 {k1}{z}, ymm2/m256/m32bcst{sae} + /// __m128d _mm_getexp_sd (__m128d a) + /// VGETEXPSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} /// - public static Vector512 ConvertToVector512Double(Vector256 value) => ConvertToVector512Double(value); + public static Vector128 GetExponentScalar(Vector128 value) => GetExponentScalar(value); /// - /// __m512i _mm512_cvtepi8_epi32 (__m128i a) - /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// __m128 _mm_getexp_ss (__m128 a, __m128 b) + /// VGETEXPSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int32(Vector128 value) => ConvertToVector512Int32(value); + public static Vector128 GetExponentScalar(Vector128 upper, Vector128 value) => GetExponentScalar(upper, value); /// - /// __m512i _mm512_cvtepu8_epi32 (__m128i a) - /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// __m128d _mm_getexp_sd (__m128d a, __m128d b) + /// VGETEXPSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int32(Vector128 value) => ConvertToVector512Int32(value); + public static Vector128 GetExponentScalar(Vector128 upper, Vector128 value) => GetExponentScalar(upper, value); + /// - /// __m512i _mm512_cvtepi16_epi32 (__m128i a) - /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512 _mm512_getmant_ps (__m512 a) + /// VGETMANTPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} /// - public static Vector512 ConvertToVector512Int32(Vector256 value) => ConvertToVector512Int32(value); + public static Vector512 GetMantissa(Vector512 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissa(value, control); /// - /// __m512i _mm512_cvtepu16_epi32 (__m128i a) - /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512d _mm512_getmant_pd (__m512d a) + /// VGETMANTPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae} /// - public static Vector512 ConvertToVector512Int32(Vector256 value) => ConvertToVector512Int32(value); + public static Vector512 GetMantissa(Vector512 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissa(value, control); + /// - /// __m512i _mm512_cvtps_epi32 (__m512 a) - /// VCVTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// __m128 _mm_getmant_ss (__m128 a) + /// VGETMANTSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} /// - public static Vector512 ConvertToVector512Int32(Vector512 value) => ConvertToVector512Int32(value); + public static Vector128 GetMantissaScalar(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissaScalar(value, control); /// - /// __m512i _mm512_cvtepi8_epi64 (__m128i a) - /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m128d _mm_getmant_sd (__m128d a) + /// VGETMANTSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} /// - public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + public static Vector128 GetMantissaScalar(Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissaScalar(value, control); /// - /// __m512i _mm512_cvtepu8_epi64 (__m128i a) - /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m128 _mm_getmant_ss (__m128 a, __m128 b) + /// VGETMANTSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + public static Vector128 GetMantissaScalar(Vector128 upper, Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissaScalar(upper, value, control); /// - /// __m512i _mm512_cvtepi16_epi64 (__m128i a) - /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m128d _mm_getmant_sd (__m128d a, __m128d b) + /// VGETMANTSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae} + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. /// - public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + public static Vector128 GetMantissaScalar(Vector128 upper, Vector128 value, [ConstantExpected(Max = (byte)(0x0F))] byte control) => GetMantissaScalar(upper, value, control); + /// - /// __m512i _mm512_cvtepu16_epi64 (__m128i a) - /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Int64(Vector128 value) => ConvertToVector512Int64(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepi32_epi64 (__m128i a) - /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Int64(Vector256 value) => ConvertToVector512Int64(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepu32_epi64 (__m128i a) - /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Int64(Vector256 value) => ConvertToVector512Int64(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512 _mm512_cvtepi32_ps (__m512i a) - /// VCVTDQ2PS zmm1 {k1}{z}, zmm2/m512/m32bcst{er} + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512Single(Vector512 value) => ConvertToVector512Single(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepi8_epi32 (__m128i a) - /// VPMOVSXBD zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti32x4_epi32 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector128 value) => ConvertToVector512UInt32(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepu8_epi32 (__m128i a) - /// VPMOVZXBD zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti32x4_epi32 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector128 value) => ConvertToVector512UInt32(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepi16_epi32 (__m128i a) - /// VPMOVSXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector256 value) => ConvertToVector512UInt32(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepu16_epi32 (__m128i a) - /// VPMOVZXWD zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti128_si512 (__m512i a, __m128i b, const int imm8) + /// VINSERTI32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt32(Vector256 value) => ConvertToVector512UInt32(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepi8_epi64 (__m128i a) - /// VPMOVSXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m512 _mm512_insertf32x4_ps (__m512 a, __m128 b, int imm8) + /// VINSERTF32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); /// - /// __m512i _mm512_cvtepu8_epi64 (__m128i a) - /// VPMOVZXBQ zmm1 {k1}{z}, xmm2/m64 + /// __m512d _mm512_insertf128_pd (__m512d a, __m128d b, int imm8) + /// VINSERTF32x4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + public static Vector512 InsertVector128(Vector512 value, Vector128 data, [ConstantExpected] byte index) => InsertVector128(value, data, index); + /// - /// __m512i _mm512_cvtepi16_epi64 (__m128i a) - /// VPMOVSXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512i _mm512_cvtepu16_epi64 (__m128i a) - /// VPMOVZXWQ zmm1 {k1}{z}, xmm2/m128 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector128 value) => ConvertToVector512UInt64(value); + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512i _mm512_cvtepi32_epi64 (__m128i a) - /// VPMOVSXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector256 value) => ConvertToVector512UInt64(value); + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512i _mm512_cvtepu32_epi64 (__m128i a) - /// VPMOVZXDQ zmm1 {k1}{z}, ymm2/m256 + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512UInt64(Vector256 value) => ConvertToVector512UInt64(value); - + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512i _mm512_cvttps_epi32 (__m512 a) - /// VCVTTPS2DQ zmm1 {k1}{z}, zmm2/m512/m32bcst{sae} + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 ConvertToVector512Int32WithTruncation(Vector512 value) => ConvertToVector512Int32WithTruncation(value); - + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512 _mm512_div_ps (__m512 a, __m512 b) - /// VDIVPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er} + /// __m512i _mm512_inserti256_si512 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 Divide(Vector512 left, Vector512 right) => Divide(left, right); + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512d _mm512_div_pd (__m512d a, __m512d b) - /// VDIVPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{er} + /// __m512i _mm512_inserti64x4_epi64 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 Divide(Vector512 left, Vector512 right) => Divide(left, right); - + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512 _mm512_moveldup_ps (__m512 a) - /// VMOVSLDUP zmm1 {k1}{z}, zmm2/m512 + /// __m512i _mm512_inserti64x4_epi64 (__m512i a, __m256i b, const int imm8) + /// VINSERTI64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 DuplicateEvenIndexed(Vector512 value) => DuplicateEvenIndexed(value); + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512d _mm512_movedup_pd (__m512d a) - /// VMOVDDUP zmm1 {k1}{z}, zmm2/m512 + /// __m512 _mm512_insertf256_ps (__m512 a, __m256 b, int imm8) + /// VINSERTF64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 DuplicateEvenIndexed(Vector512 value) => DuplicateEvenIndexed(value); + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// - /// __m512 _mm512_movehdup_ps (__m512 a) - /// VMOVSHDUP zmm1 {k1}{z}, zmm2/m512 + /// __m512d _mm512_insertf64x4_pd (__m512d a, __m256d b, int imm8) + /// VINSERTF64x4 zmm1 {k1}{z}, zmm2, xmm3/m256, imm8 /// - public static Vector512 DuplicateOddIndexed(Vector512 value) => DuplicateOddIndexed(value); + public static Vector512 InsertVector256(Vector512 value, Vector256 data, [ConstantExpected] byte index) => InsertVector256(value, data, index); /// /// __m512i _mm512_load_si512 (__m512i const * mem_addr) @@ -680,6 +1903,202 @@ internal X64() { } /// public static Vector512 Or(Vector512 left, Vector512 right) => Or(left, right); + /// + /// __m512d _mm512_permute_pd (__m512d a, int imm8) + /// VPERMILPD zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute2x64(Vector512 value, [ConstantExpected] byte control) => Permute2x64(value, control); + + /// + /// __m512 _mm512_permute_ps (__m512 a, int imm8) + /// VPERMILPS zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 Permute4x32(Vector512 value, [ConstantExpected] byte control) => Permute4x32(value, control); + + /// + /// __m512i _mm512_permute4x64_epi64 (__m512i a, const int imm8) + /// VPERMQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute4x64(Vector512 value, [ConstantExpected] byte control) => Permute4x64(value, control); + /// + /// __m512i _mm512_permute4x64_epi64 (__m512i a, const int imm8) + /// VPERMQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute4x64(Vector512 value, [ConstantExpected] byte control) => Permute4x64(value, control); + /// + /// __m512d _mm512_permute4x64_pd (__m512d a, const int imm8) + /// VPERMPD zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 Permute4x64(Vector512 value, [ConstantExpected] byte control) => Permute4x64(value, control); + + /// + /// __m512d _mm512_permutevar_pd (__m512d a, __m512i b) + /// VPERMILPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar2x64(Vector512 left, Vector512 control) => PermuteVar2x64(left, control); + + /// + /// __m512 _mm512_permutevar_ps (__m512 a, __m512i b) + /// VPERMILPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar4x32(Vector512 left, Vector512 control) => PermuteVar4x32(left, control); + + /// + /// __m512i _mm512_permutevar8x64_epi64 (__m512i a, __m512i b) + /// VPERMQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar8x64(Vector512 value, Vector512 control) => PermuteVar8x64(value, control); + /// + /// __m512i _mm512_permutevar8x64_epi64 (__m512i a, __m512i b) + /// VPERMQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar8x64(Vector512 value, Vector512 control) => PermuteVar8x64(value, control); + /// + /// __m512d _mm512_permutevar8x64_pd (__m512d a, __m512i b) + /// VPERMPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 PermuteVar8x64(Vector512 value, Vector512 control) => PermuteVar8x64(value, control); + + /// + /// __m512i _mm512_permutevar16x32_epi32 (__m512i a, __m512i b) + /// VPERMD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar16x32(Vector512 left, Vector512 control) => PermuteVar16x32(left, control); + /// + /// __m512i _mm512_permutevar16x32_epi32 (__m512i a, __m512i b) + /// VPERMD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar16x32(Vector512 left, Vector512 control) => PermuteVar16x32(left, control); + /// + /// __m512 _mm512_permutevar16x32_ps (__m512 a, __m512i b) + /// VPERMPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 PermuteVar16x32(Vector512 left, Vector512 control) => PermuteVar16x32(left, control); + + /// + /// __m512 _mm512_rcp14_ps (__m512 a, __m512 b) + /// VRCP14PS zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 Reciprocal14(Vector512 value) => Reciprocal14(value); + /// + /// __m512d _mm512_rcp14_pd (__m512d a, __m512d b) + /// VRCP14PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 Reciprocal14(Vector512 value) => Reciprocal14(value); + + /// + /// __m128 _mm_rcp14_ss (__m128 a) + /// VRCP14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// + public static Vector128 Reciprocal14Scalar(Vector128 value) => Reciprocal14Scalar(value); + /// + /// __m128d _mm_rcp14_sd (__m128d a) + /// VRCP14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// + public static Vector128 Reciprocal14Scalar(Vector128 value) => Reciprocal14Scalar(value); + /// + /// __m128 _mm_rcp14_ss (__m128 a, __m128 b) + /// VRCP14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 Reciprocal14Scalar(Vector128 upper, Vector128 value) => Reciprocal14Scalar(upper, value); + /// + /// __m128d _mm_rcp14_sd (__m128d a, __m128d b) + /// VRCP14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 Reciprocal14Scalar(Vector128 upper, Vector128 value) => Reciprocal14Scalar(upper, value); + + /// + /// __m512 _mm512_rsqrt14_ps (__m512 a, __m512 b) + /// VRSQRT14PS zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 ReciprocalSqrt14(Vector512 value) => ReciprocalSqrt14(value); + /// + /// __m512d _mm512_rsqrt14_pd (__m512d a, __m512d b) + /// VRSQRT14PD zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 ReciprocalSqrt14(Vector512 value) => ReciprocalSqrt14(value); + + /// + /// __m128 _mm_rsqrt14_ss (__m128 a) + /// VRSQRT14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 value) => ReciprocalSqrt14Scalar(value); + /// + /// __m128d _mm_rsqrt14_sd (__m128d a) + /// VRSQRT14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 value) => ReciprocalSqrt14Scalar(value); + /// + /// __m128 _mm_rsqrt14_ss (__m128 a, __m128 b) + /// VRSQRT14SS xmm1 {k1}{z}, xmm2, xmm3/m32 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 upper, Vector128 value) => ReciprocalSqrt14Scalar(upper, value); + /// + /// __m128d _mm_rsqrt14_sd (__m128d a, __m128d b) + /// VRSQRT14SD xmm1 {k1}{z}, xmm2, xmm3/m64 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 ReciprocalSqrt14Scalar(Vector128 upper, Vector128 value) => ReciprocalSqrt14Scalar(upper, value); + + /// + /// __m512 _mm512_roundscale_ps (__m512 a, int imm) + /// VRNDSCALEPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae}, imm8 + /// + public static Vector512 RoundScale(Vector512 value, [ConstantExpected] byte control) => RoundScale(value, control); + /// + /// __m512d _mm512_roundscale_pd (__m512d a, int imm) + /// VRNDSCALEPD zmm1 {k1}{z}, zmm2/m512/m64bcst{sae}, imm8 + /// + public static Vector512 RoundScale(Vector512 value, [ConstantExpected] byte control) => RoundScale(value, control); + + /// + /// __m128 _mm_roundscale_ss (__m128 a, int imm) + /// VRNDSCALESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// + public static Vector128 RoundScaleScalar(Vector128 value, [ConstantExpected] byte control) => RoundScaleScalar(value, control); + /// + /// __m128d _mm_roundscale_sd (__m128d a, int imm) + /// VRNDSCALESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// + public static Vector128 RoundScaleScalar(Vector128 value, [ConstantExpected] byte control) => RoundScaleScalar(value, control); + /// + /// __m128 _mm_roundscale_ss (__m128 a, __m128 b, int imm) + /// VRNDSCALESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 RoundScaleScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) => RoundScaleScalar(upper, value, control); + /// + /// __m128d _mm_roundscale_sd (__m128d a, __m128d b, int imm) + /// VRNDSCALESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector128 RoundScaleScalar(Vector128 upper, Vector128 value, [ConstantExpected] byte control) => RoundScaleScalar(upper, value, control); + + /// + /// __m512 _mm512_scalef_ps (__m512 a, __m512 b) + /// VSCALEFPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er} + /// + public static Vector512 Scale(Vector512 left, Vector512 right) => Scale(left, right); + /// + /// __m512d _mm512_scalef_pd (__m512d a, __m512d b) + /// VSCALEFPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{er} + /// + public static Vector512 Scale(Vector512 left, Vector512 right) => Scale(left, right); + + /// + /// __m128 _mm_scalef_ss (__m128 a, __m128 b) + /// VSCALEFSS xmm1 {k1}{z}, xmm2, xmm3/m32{er} + /// + public static Vector128 ScaleScalar(Vector128 left, Vector128 right) => ScaleScalar(left, right); + /// + /// __m128d _mm_scalef_sd (__m128d a, __m128d b) + /// VSCALEFSD xmm1 {k1}{z}, xmm2, xmm3/m64{er} + /// + public static Vector128 ScaleScalar(Vector128 left, Vector128 right) => ScaleScalar(left, right); + /// /// __m512i _mm512_sll_epi32 (__m512i a, __m128i count) /// VPSLLD zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -722,6 +2141,27 @@ internal X64() { } /// public static Vector512 ShiftLeftLogical(Vector512 value, [ConstantExpected] byte count) => ShiftLeftLogical(value, count); + /// + /// __m512i _mm512_sllv_epi32 (__m512i a, __m512i count) + /// VPSLLVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) => ShiftLeftLogicalVariable(value, count); + /// + /// __m512i _mm512_sllv_epi32 (__m512i a, __m512i count) + /// VPSLLVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) => ShiftLeftLogicalVariable(value, count); + /// + /// __m512i _mm512_sllv_epi64 (__m512i a, __m512i count) + /// VPSLLVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) => ShiftLeftLogicalVariable(value, count); + /// + /// __m512i _mm512_sllv_epi64 (__m512i a, __m512i count) + /// VPSLLVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftLeftLogicalVariable(Vector512 value, Vector512 count) => ShiftLeftLogicalVariable(value, count); + /// /// _mm512_sra_epi32 (__m512i a, __m128i count) /// VPSRAD zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -744,6 +2184,17 @@ internal X64() { } /// public static Vector512 ShiftRightArithmetic(Vector512 value, [ConstantExpected] byte count) => ShiftRightArithmetic(value, count); + /// + /// __m512i _mm512_srav_epi32 (__m512i a, __m512i count) + /// VPSRAVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftRightArithmeticVariable(Vector512 value, Vector512 count) => ShiftRightArithmeticVariable(value, count); + /// + /// __m512i _mm512_srav_epi64 (__m512i a, __m512i count) + /// VPSRAVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftRightArithmeticVariable(Vector512 value, Vector512 count) => ShiftRightArithmeticVariable(value, count); + /// /// __m512i _mm512_srl_epi32 (__m512i a, __m128i count) /// VPSRLD zmm1 {k1}{z}, zmm2, xmm3/m128 @@ -786,6 +2237,27 @@ internal X64() { } /// public static Vector512 ShiftRightLogical(Vector512 value, [ConstantExpected] byte count) => ShiftRightLogical(value, count); + /// + /// __m512i _mm512_srlv_epi32 (__m512i a, __m512i count) + /// VPSRLVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) => ShiftRightLogicalVariable(value, count); + /// + /// __m512i _mm512_srlv_epi32 (__m512i a, __m512i count) + /// VPSRLVD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) => ShiftRightLogicalVariable(value, count); + /// + /// __m512i _mm512_srlv_epi64 (__m512i a, __m512i count) + /// VPSRLVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) => ShiftRightLogicalVariable(value, count); + /// + /// __m512i _mm512_srlv_epi64 (__m512i a, __m512i count) + /// VPSRLVQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 ShiftRightLogicalVariable(Vector512 value, Vector512 count) => ShiftRightLogicalVariable(value, count); + /// /// __m512i _mm512_shuffle_epi32 (__m512i a, const int imm8) /// VPSHUFD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.PlatformNotSupported.cs new file mode 100644 index 00000000000000..61371ff29f98f2 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.PlatformNotSupported.cs @@ -0,0 +1,66 @@ +// 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.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; + +namespace System.Runtime.Intrinsics.X86 +{ + /// This class provides access to X86 AVX512VBMI hardware instructions via intrinsics + [CLSCompliant(false)] + public abstract class Avx512Vbmi : Avx512BW + { + internal Avx512Vbmi() { } + + public static new bool IsSupported { [Intrinsic] get { return false; } } + + public new abstract class VL : Avx512BW.VL + { + internal VL() { } + + public static new bool IsSupported { [Intrinsic] get { return false; } } + + /// + /// __m128i _mm_permutevar64x8_epi8 (__m128i a, __m128i b) + /// VPERMB xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar16x8(Vector128 left, Vector128 control) => PermuteVar16x8(left, control); + /// + /// __m128i _mm_permutevar64x8_epi8 (__m128i a, __m128i b) + /// VPERMB xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar16x8(Vector128 left, Vector128 control) => PermuteVar16x8(left, control); + + /// + /// __m256i _mm256_permutevar64x8_epi8 (__m256i a, __m256i b) + /// VPERMB ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar32x8(Vector256 left, Vector256 control) => PermuteVar32x8(left, control); + /// + /// __m256i _mm256_permutevar64x8_epi8 (__m256i a, __m256i b) + /// VPERMB ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar32x8(Vector256 left, Vector256 control) => PermuteVar32x8(left, control); + } + + public new abstract class X64 : Avx512BW.X64 + { + internal X64() { } + + public static new bool IsSupported { [Intrinsic] get { return false; } } + } + + /// + /// __m512i _mm512_permutevar64x8_epi8 (__m512i a, __m512i b) + /// VPERMB zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar64x8(Vector512 left, Vector512 control) => PermuteVar64x8(left, control); + /// + /// __m512i _mm512_permutevar64x8_epi8 (__m512i a, __m512i b) + /// VPERMB zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar64x8(Vector512 left, Vector512 control) => PermuteVar64x8(left, control); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.cs new file mode 100644 index 00000000000000..0dbed508665603 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512Vbmi.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace System.Runtime.Intrinsics.X86 +{ + /// This class provides access to X86 AVX512VBMI hardware instructions via intrinsics + [Intrinsic] + [CLSCompliant(false)] + public abstract class Avx512Vbmi : Avx512BW + { + internal Avx512Vbmi() { } + + public static new bool IsSupported { get => IsSupported; } + + [Intrinsic] + public new abstract class VL : Avx512BW.VL + { + internal VL() { } + + public static new bool IsSupported { get => IsSupported; } + + /// + /// __m128i _mm_permutevar64x8_epi8 (__m128i a, __m128i b) + /// VPERMB xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar16x8(Vector128 left, Vector128 control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_permutevar64x8_epi8 (__m128i a, __m128i b) + /// VPERMB xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 PermuteVar16x8(Vector128 left, Vector128 control) { throw new PlatformNotSupportedException(); } + + /// + /// __m256i _mm256_permutevar64x8_epi8 (__m256i a, __m256i b) + /// VPERMB ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar32x8(Vector256 left, Vector256 control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_permutevar64x8_epi8 (__m256i a, __m256i b) + /// VPERMB ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 PermuteVar32x8(Vector256 left, Vector256 control) { throw new PlatformNotSupportedException(); } + } + + [Intrinsic] + public new abstract class X64 : Avx512BW.X64 + { + internal X64() { } + + public static new bool IsSupported { get => IsSupported; } + } + + /// + /// __m512i _mm512_permutevar64x8_epi8 (__m512i a, __m512i b) + /// VPERMB zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar64x8(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_permutevar64x8_epi8 (__m512i a, __m512i b) + /// VPERMB zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 PermuteVar64x8(Vector512 left, Vector512 control) { throw new PlatformNotSupportedException(); } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index 53de721a0c4585..2e8fcb7d4a0df4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -722,6 +722,11 @@ private static void OnAssemblyLoad(RuntimeAssembly assembly) return InvokeResolveEvent(AssemblyResolve, assembly, assemblyFullName); } + internal static void InvokeAssemblyLoadEvent(Assembly assembly) + { + AssemblyLoad?.Invoke(AppDomain.CurrentDomain, new AssemblyLoadEventArgs(assembly)); + } + [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "The code handles the Assembly.Location equals null")] private static RuntimeAssembly? InvokeResolveEvent(ResolveEventHandler? eventHandler, RuntimeAssembly? assembly, string name) diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2ByteValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any2ByteSearchValues.cs similarity index 90% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2ByteValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/Any2ByteSearchValues.cs index 76f8db819156f6..42f4acbfebf8b0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2ByteValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any2ByteSearchValues.cs @@ -6,11 +6,11 @@ namespace System.Buffers { - internal sealed class IndexOfAny2ByteValues : IndexOfAnyValues + internal sealed class Any2ByteSearchValues : SearchValues { private readonly byte _e0, _e1; - public IndexOfAny2ByteValues(ReadOnlySpan values) + public Any2ByteSearchValues(ReadOnlySpan values) { Debug.Assert(values.Length == 2); (_e0, _e1) = (values[0], values[1]); diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any2CharSearchValues.cs similarity index 90% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/Any2CharSearchValues.cs index 8f5c0c26456230..a2bfde7f6fab94 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any2CharSearchValues.cs @@ -6,12 +6,12 @@ namespace System.Buffers { - internal sealed class IndexOfAny2CharValue : IndexOfAnyValues - where TShouldUsePacked : struct, IndexOfAnyValues.IRuntimeConst + internal sealed class Any2CharSearchValues : SearchValues + where TShouldUsePacked : struct, SearchValues.IRuntimeConst { private char _e0, _e1; - public IndexOfAny2CharValue(char value0, char value1) => + public Any2CharSearchValues(char value0, char value1) => (_e0, _e1) = (value0, value1); internal override char[] GetValues() => new[] { _e0, _e1 }; diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3ByteValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any3ByteSearchValues.cs similarity index 91% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3ByteValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/Any3ByteSearchValues.cs index ad569e18589ac3..d7208dea435067 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3ByteValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any3ByteSearchValues.cs @@ -6,11 +6,11 @@ namespace System.Buffers { - internal sealed class IndexOfAny3ByteValues : IndexOfAnyValues + internal sealed class Any3ByteSearchValues : SearchValues { private readonly byte _e0, _e1, _e2; - public IndexOfAny3ByteValues(ReadOnlySpan values) + public Any3ByteSearchValues(ReadOnlySpan values) { Debug.Assert(values.Length == 3); (_e0, _e1, _e2) = (values[0], values[1], values[2]); diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any3CharSearchValues.cs similarity index 91% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/Any3CharSearchValues.cs index b1f6cb048eda42..c69dbff8d0a4c7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any3CharSearchValues.cs @@ -6,12 +6,12 @@ namespace System.Buffers { - internal sealed class IndexOfAny3CharValue : IndexOfAnyValues - where TShouldUsePacked : struct, IndexOfAnyValues.IRuntimeConst + internal sealed class Any3CharSearchValues : SearchValues + where TShouldUsePacked : struct, SearchValues.IRuntimeConst { private char _e0, _e1, _e2; - public IndexOfAny3CharValue(char value0, char value1, char value2) => + public Any3CharSearchValues(char value0, char value1, char value2) => (_e0, _e1, _e2) = (value0, value1, value2); internal override char[] GetValues() => new[] { _e0, _e1, _e2 }; diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny4Values.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any4SearchValues.cs similarity index 94% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny4Values.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/Any4SearchValues.cs index c23839310933cf..8f87afe2e23a73 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny4Values.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any4SearchValues.cs @@ -10,13 +10,13 @@ namespace System.Buffers { - internal sealed class IndexOfAny4Values : IndexOfAnyValues + internal sealed class Any4SearchValues : SearchValues where T : struct, IEquatable where TImpl : struct, INumber { private readonly TImpl _e0, _e1, _e2, _e3; - public IndexOfAny4Values(ReadOnlySpan values) + public Any4SearchValues(ReadOnlySpan values) { Debug.Assert(Unsafe.SizeOf() == Unsafe.SizeOf()); Debug.Assert(values.Length == 4); diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny5Values.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any5SearchValues.cs similarity index 94% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny5Values.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/Any5SearchValues.cs index 55660a22b99f12..0cdfc16d04ca10 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny5Values.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Any5SearchValues.cs @@ -10,13 +10,13 @@ namespace System.Buffers { - internal sealed class IndexOfAny5Values : IndexOfAnyValues + internal sealed class Any5SearchValues : SearchValues where T : struct, IEquatable where TImpl : struct, INumber { private readonly TImpl _e0, _e1, _e2, _e3, _e4; - public IndexOfAny5Values(ReadOnlySpan values) + public Any5SearchValues(ReadOnlySpan values) { Debug.Assert(Unsafe.SizeOf() == Unsafe.SizeOf()); Debug.Assert(values.Length == 5); diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyByteValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AnyByteSearchValues.cs similarity index 96% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyByteValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/AnyByteSearchValues.cs index 492e29d5c9b2b9..ce99ac0f348c4f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyByteValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AnyByteSearchValues.cs @@ -7,13 +7,13 @@ namespace System.Buffers { - internal sealed class IndexOfAnyByteValues : IndexOfAnyValues + internal sealed class AnyByteSearchValues : SearchValues { private readonly Vector128 _bitmap0; private readonly Vector128 _bitmap1; private readonly BitVector256 _lookup; - public IndexOfAnyByteValues(ReadOnlySpan values) => + public AnyByteSearchValues(ReadOnlySpan values) => IndexOfAnyAsciiSearcher.ComputeBitmap256(values, out _bitmap0, out _bitmap1, out _lookup); internal override byte[] GetValues() => _lookup.GetByteValues(); diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiByteValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiByteSearchValues.cs similarity index 96% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiByteValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiByteSearchValues.cs index 7a502d283920d9..b71ebbda7748fe 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiByteValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiByteSearchValues.cs @@ -7,12 +7,12 @@ namespace System.Buffers { - internal sealed class IndexOfAnyAsciiByteValues : IndexOfAnyValues + internal sealed class AsciiByteSearchValues : SearchValues { private readonly Vector128 _bitmap; private readonly BitVector256 _lookup; - public IndexOfAnyAsciiByteValues(ReadOnlySpan values) => + public AsciiByteSearchValues(ReadOnlySpan values) => IndexOfAnyAsciiSearcher.ComputeBitmap(values, out _bitmap, out _lookup); internal override byte[] GetValues() => _lookup.GetByteValues(); diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiCharValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiCharSearchValues.cs similarity index 95% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiCharValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiCharSearchValues.cs index 72e2f4042ccb3a..f56541bc20a7cc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiCharValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiCharSearchValues.cs @@ -7,13 +7,13 @@ namespace System.Buffers { - internal sealed class IndexOfAnyAsciiCharValues : IndexOfAnyValues + internal sealed class AsciiCharSearchValues : SearchValues where TOptimizations : struct, IndexOfAnyAsciiSearcher.IOptimizations { private readonly Vector128 _bitmap; private readonly BitVector256 _lookup; - public IndexOfAnyAsciiCharValues(Vector128 bitmap, BitVector256 lookup) + public AsciiCharSearchValues(Vector128 bitmap, BitVector256 lookup) { _bitmap = bitmap; _lookup = lookup; diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/BitVector256.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/BitVector256.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/BitVector256.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/BitVector256.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfEmptyValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/EmptySearchValues.cs similarity index 91% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfEmptyValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/EmptySearchValues.cs index d00069c6ef61d4..c5f95097c011e2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfEmptyValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/EmptySearchValues.cs @@ -3,7 +3,7 @@ namespace System.Buffers { - internal sealed class IndexOfEmptyValues : IndexOfAnyValues + internal sealed class EmptySearchValues : SearchValues where T : IEquatable? { internal override T[] GetValues() => diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiSearcher.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs similarity index 99% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiSearcher.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs index c39639d24f8264..56e7bd741c0b25 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiSearcher.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs @@ -1,8 +1,9 @@ -// 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.Diagnostics; using System.Numerics; +using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; @@ -66,7 +67,7 @@ internal static unsafe void ComputeBitmap(ReadOnlySpan values, out Vector1 if (value > 127) { - // The values were modified concurrent with the call to IndexOfAnyValues.Create + // The values were modified concurrent with the call to SearchValues.Create ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } @@ -869,6 +870,7 @@ private static Vector128 IndexOfAnyLookupCore(Vector128 source, Vect return result; } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 IndexOfAnyLookup(Vector256 source0, Vector256 source1, Vector256 bitmapLookup) where TNegator : struct, INegator @@ -889,6 +891,7 @@ private static Vector256 IndexOfAnyLookup(Vector return TNegator.NegateIfNeeded(result); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 IndexOfAnyLookupCore(Vector256 source, Vector256 bitmapLookup) { @@ -922,6 +925,7 @@ private static Vector128 IndexOfAnyLookup(Vector128 source return TNegator.NegateIfNeeded(result); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 IndexOfAnyLookup(Vector256 source, Vector256 bitmapLookup0, Vector256 bitmapLookup1) where TNegator : struct, INegator @@ -992,6 +996,7 @@ private static unsafe int ComputeLastIndexOverlapped(ref T searchSp return offsetInVector - Vector128.Count + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref secondVector) / (nuint)sizeof(T)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe int ComputeFirstIndex(ref T searchSpace, ref T current, Vector256 result) where TNegator : struct, INegator @@ -1007,6 +1012,7 @@ private static unsafe int ComputeFirstIndex(ref T searchSpace, ref return offsetInVector + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref current) / (nuint)sizeof(T)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe int ComputeFirstIndexOverlapped(ref T searchSpace, ref T current0, ref T current1, Vector256 result) where TNegator : struct, INegator @@ -1028,6 +1034,7 @@ private static unsafe int ComputeFirstIndexOverlapped(ref T searchS return offsetInVector + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref current0) / (nuint)sizeof(T)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe int ComputeLastIndex(ref T searchSpace, ref T current, Vector256 result) where TNegator : struct, INegator @@ -1043,6 +1050,7 @@ private static unsafe int ComputeLastIndex(ref T searchSpace, ref T return offsetInVector + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref current) / (nuint)sizeof(T)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe int ComputeLastIndexOverlapped(ref T searchSpace, ref T secondVector, Vector256 result) where TNegator : struct, INegator @@ -1064,6 +1072,7 @@ private static unsafe int ComputeLastIndexOverlapped(ref T searchSp return offsetInVector - Vector256.Count + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref secondVector) / (nuint)sizeof(T)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 FixUpPackedVector256Result(Vector256 result) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyLatin1CharValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Latin1CharSearchValues.cs similarity index 94% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyLatin1CharValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/Latin1CharSearchValues.cs index a491a0bf8c9f63..3968825ccd4c72 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyLatin1CharValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Latin1CharSearchValues.cs @@ -6,17 +6,17 @@ namespace System.Buffers { - internal sealed class IndexOfAnyLatin1CharValues : IndexOfAnyValues + internal sealed class Latin1CharSearchValues : SearchValues { private readonly BitVector256 _lookup; - public IndexOfAnyLatin1CharValues(ReadOnlySpan values) + public Latin1CharSearchValues(ReadOnlySpan values) { foreach (char c in values) { if (c > 255) { - // The values were modified concurrent with the call to IndexOfAnyValues.Create + // The values were modified concurrent with the call to SearchValues.Create ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesProbabilistic.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticCharSearchValues.cs similarity index 78% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesProbabilistic.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticCharSearchValues.cs index 0838d480dbeb13..a61f9b7bd210c3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesProbabilistic.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticCharSearchValues.cs @@ -3,16 +3,27 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; namespace System.Buffers { - internal sealed class IndexOfAnyCharValuesProbabilistic : IndexOfAnyValues + internal sealed class ProbabilisticCharSearchValues : SearchValues { private ProbabilisticMap _map; private readonly string _values; - public unsafe IndexOfAnyCharValuesProbabilistic(ReadOnlySpan values) + public ProbabilisticCharSearchValues(scoped ReadOnlySpan values) { + if (Vector128.IsHardwareAccelerated && values.Length < 8) + { + // ProbabilisticMap does a Span.Contains check to confirm potential matches. + // If we have fewer than 8 values, pad them with existing ones to make the verification faster. + Span newValues = stackalloc char[8]; + newValues.Fill(values[0]); + values.CopyTo(newValues); + values = newValues; + } + _values = new string(values); _map = new ProbabilisticMap(_values); } diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/ProbabilisticMap.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs similarity index 96% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/ProbabilisticMap.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs index 493398929f1695..efd348aa99ae11 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/ProbabilisticMap.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Numerics; +using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -104,6 +105,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(values)), (short)ch, values.Length); + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 ContainsMask32CharsAvx2(Vector256 charMapLower, Vector256 charMapUpper, ref char searchSpace) { @@ -124,6 +126,7 @@ private static Vector256 ContainsMask32CharsAvx2(Vector256 charMapLo return resultLower & resultUpper; } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 IsCharBitSetAvx2(Vector256 charMapLower, Vector256 charMapUpper, Vector256 values) { @@ -172,10 +175,19 @@ private static Vector128 IsCharBitSet(Vector128 charMapLower, Vector Vector128 bitPositions = Vector128.ShuffleUnsafe(Vector128.Create(0x8040201008040201).AsByte(), highNibble); Vector128 index = values & Vector128.Create((byte)VectorizedIndexMask); - Vector128 bitMaskLower = Vector128.ShuffleUnsafe(charMapLower, index); - Vector128 bitMaskUpper = Vector128.ShuffleUnsafe(charMapUpper, index - Vector128.Create((byte)16)); - Vector128 mask = Vector128.GreaterThan(index, Vector128.Create((byte)15)); - Vector128 bitMask = Vector128.ConditionalSelect(mask, bitMaskUpper, bitMaskLower); + Vector128 bitMask; + + if (AdvSimd.Arm64.IsSupported) + { + bitMask = AdvSimd.Arm64.VectorTableLookup((charMapLower, charMapUpper), index); + } + else + { + Vector128 bitMaskLower = Vector128.ShuffleUnsafe(charMapLower, index); + Vector128 bitMaskUpper = Vector128.ShuffleUnsafe(charMapUpper, index - Vector128.Create((byte)16)); + Vector128 mask = Vector128.GreaterThan(index, Vector128.Create((byte)15)); + bitMask = Vector128.ConditionalSelect(mask, bitMaskUpper, bitMaskLower); + } return ~Vector128.Equals(bitMask & bitPositions, Vector128.Zero); } diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyByteValuesInRange.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/RangeByteSearchValues.cs similarity index 91% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyByteValuesInRange.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/RangeByteSearchValues.cs index 4561a2170ec785..a19072c4e59666 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyByteValuesInRange.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/RangeByteSearchValues.cs @@ -5,12 +5,12 @@ namespace System.Buffers { - internal sealed class IndexOfAnyByteValuesInRange : IndexOfAnyValues + internal sealed class RangeByteSearchValues : SearchValues { private readonly byte _lowInclusive, _highInclusive; private readonly uint _lowUint, _highMinusLow; - public IndexOfAnyByteValuesInRange(byte lowInclusive, byte highInclusive) + public RangeByteSearchValues(byte lowInclusive, byte highInclusive) { (_lowInclusive, _highInclusive) = (lowInclusive, highInclusive); _lowUint = lowInclusive; diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/RangeCharSearchValues.cs similarity index 92% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/RangeCharSearchValues.cs index 2aac5052745e3b..3a85f950ef4adb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/RangeCharSearchValues.cs @@ -6,14 +6,14 @@ namespace System.Buffers { - internal sealed class IndexOfAnyCharValuesInRange : IndexOfAnyValues - where TShouldUsePacked : struct, IndexOfAnyValues.IRuntimeConst + internal sealed class RangeCharSearchValues : SearchValues + where TShouldUsePacked : struct, SearchValues.IRuntimeConst { private readonly char _rangeInclusive; private char _lowInclusive, _highInclusive; private readonly uint _lowUint, _highMinusLow; - public IndexOfAnyCharValuesInRange(char lowInclusive, char highInclusive) + public RangeCharSearchValues(char lowInclusive, char highInclusive) { (_lowInclusive, _rangeInclusive, _highInclusive) = (lowInclusive, (char)(highInclusive - lowInclusive), highInclusive); _lowUint = lowInclusive; diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.T.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValues.T.cs similarity index 78% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.T.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValues.T.cs index 1873ac4eb107a3..071d4c51495faa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.T.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValues.T.cs @@ -8,19 +8,19 @@ namespace System.Buffers { /// /// Provides an immutable, read-only set of values optimized for efficient searching. - /// Instances are created by or . + /// Instances are created by or . /// /// The type of the values to search for. /// - /// are optimized for situations where the same set of values is frequently used for searching at runtime. + /// are optimized for situations where the same set of values is frequently used for searching at runtime. /// - [DebuggerTypeProxy(typeof(IndexOfAnyValuesDebugView<>))] - public class IndexOfAnyValues where T : IEquatable? + [DebuggerTypeProxy(typeof(SearchValuesDebugView<>))] + public class SearchValues where T : IEquatable? { // Only CoreLib can create derived types - private protected IndexOfAnyValues() { } + private protected SearchValues() { } - /// Used by . + /// Used by . internal virtual T[] GetValues() => throw new UnreachableException(); /// @@ -38,7 +38,7 @@ private protected IndexOfAnyValues() { } internal virtual int LastIndexOfAnyExcept(ReadOnlySpan span) => throw new UnreachableException(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int IndexOfAny(ReadOnlySpan span, IndexOfAnyValues values) + internal static int IndexOfAny(ReadOnlySpan span, SearchValues values) { if (values is null) { @@ -49,7 +49,7 @@ internal static int IndexOfAny(ReadOnlySpan span, IndexOfAnyValues values) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int IndexOfAnyExcept(ReadOnlySpan span, IndexOfAnyValues values) + internal static int IndexOfAnyExcept(ReadOnlySpan span, SearchValues values) { if (values is null) { @@ -60,7 +60,7 @@ internal static int IndexOfAnyExcept(ReadOnlySpan span, IndexOfAnyValues v } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int LastIndexOfAny(ReadOnlySpan span, IndexOfAnyValues values) + internal static int LastIndexOfAny(ReadOnlySpan span, SearchValues values) { if (values is null) { @@ -71,7 +71,7 @@ internal static int LastIndexOfAny(ReadOnlySpan span, IndexOfAnyValues val } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int LastIndexOfAnyExcept(ReadOnlySpan span, IndexOfAnyValues values) + internal static int LastIndexOfAnyExcept(ReadOnlySpan span, SearchValues values) { if (values is null) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValues.cs similarity index 69% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValues.cs index 2ff012bfa03229..c53ff57447dab6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValues.cs @@ -14,33 +14,33 @@ namespace System.Buffers { /// - /// Provides a set of initialization methods for instances of the class. + /// Provides a set of initialization methods for instances of the class. /// /// - /// IndexOfAnyValues are optimized for situations where the same set of values is frequently used for searching at runtime. + /// SearchValues are optimized for situations where the same set of values is frequently used for searching at runtime. /// - public static class IndexOfAnyValues + public static class SearchValues { /// /// Creates an optimized representation of used for efficient searching. /// /// The set of values. - public static IndexOfAnyValues Create(ReadOnlySpan values) + public static SearchValues Create(ReadOnlySpan values) { if (values.IsEmpty) { - return new IndexOfEmptyValues(); + return new EmptySearchValues(); } if (values.Length == 1) { - return new IndexOfAny1ByteValue(values); + return new SingleByteSearchValues(values); } - // IndexOfAnyValuesInRange is slower than IndexOfAny1Value, but faster than IndexOfAny2Values + // RangeByteSearchValues is slower than SingleByteSearchValues, but faster than Any2ByteSearchValues if (TryGetSingleRange(values, out byte minInclusive, out byte maxInclusive)) { - return new IndexOfAnyByteValuesInRange(minInclusive, maxInclusive); + return new RangeByteSearchValues(minInclusive, maxInclusive); } if (values.Length <= 5) @@ -48,46 +48,46 @@ public static IndexOfAnyValues Create(ReadOnlySpan values) Debug.Assert(values.Length is 2 or 3 or 4 or 5); return values.Length switch { - 2 => new IndexOfAny2ByteValues(values), - 3 => new IndexOfAny3ByteValues(values), - 4 => new IndexOfAny4Values(values), - _ => new IndexOfAny5Values(values), + 2 => new Any2ByteSearchValues(values), + 3 => new Any3ByteSearchValues(values), + 4 => new Any4SearchValues(values), + _ => new Any5SearchValues(values), }; } if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && maxInclusive < 128) { - return new IndexOfAnyAsciiByteValues(values); + return new AsciiByteSearchValues(values); } - return new IndexOfAnyByteValues(values); + return new AnyByteSearchValues(values); } /// /// Creates an optimized representation of used for efficient searching. /// /// The set of values. - public static IndexOfAnyValues Create(ReadOnlySpan values) + public static SearchValues Create(ReadOnlySpan values) { if (values.IsEmpty) { - return new IndexOfEmptyValues(); + return new EmptySearchValues(); } if (values.Length == 1) { char value = values[0]; return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value) - ? new IndexOfAny1CharValue(value) - : new IndexOfAny1CharValue(value); + ? new SingleCharSearchValues(value) + : new SingleCharSearchValues(value); } - // IndexOfAnyValuesInRange is slower than IndexOfAny1Value, but faster than IndexOfAny2Values + // RangeCharSearchValues is slower than SingleCharSearchValues, but faster than Any2CharSearchValues if (TryGetSingleRange(values, out char minInclusive, out char maxInclusive)) { return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(minInclusive) && PackedSpanHelpers.CanUsePackedIndexOf(maxInclusive) - ? new IndexOfAnyCharValuesInRange(minInclusive, maxInclusive) - : new IndexOfAnyCharValuesInRange(minInclusive, maxInclusive); + ? new RangeCharSearchValues(minInclusive, maxInclusive) + : new RangeCharSearchValues(minInclusive, maxInclusive); } if (values.Length == 2) @@ -95,8 +95,8 @@ public static IndexOfAnyValues Create(ReadOnlySpan values) char value0 = values[0]; char value1 = values[1]; return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) - ? new IndexOfAny2CharValue(value0, value1) - : new IndexOfAny2CharValue(value0, value1); + ? new Any2CharSearchValues(value0, value1) + : new Any2CharSearchValues(value0, value1); } if (values.Length == 3) @@ -105,18 +105,18 @@ public static IndexOfAnyValues Create(ReadOnlySpan values) char value1 = values[1]; char value2 = values[2]; return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) && PackedSpanHelpers.CanUsePackedIndexOf(value2) - ? new IndexOfAny3CharValue(value0, value1, value2) - : new IndexOfAny3CharValue(value0, value1, value2); + ? new Any3CharSearchValues(value0, value1, value2) + : new Any3CharSearchValues(value0, value1, value2); } - // IndexOfAnyAsciiSearcher for chars is slower than IndexOfAny3Values, but faster than IndexOfAny4Values + // IndexOfAnyAsciiSearcher for chars is slower than Any3CharSearchValues, but faster than Any4SearchValues if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && maxInclusive < 128) { IndexOfAnyAsciiSearcher.ComputeBitmap(values, out Vector128 bitmap, out BitVector256 lookup); return (Ssse3.IsSupported || PackedSimd.IsSupported) && lookup.Contains(0) - ? new IndexOfAnyAsciiCharValues(bitmap, lookup) - : new IndexOfAnyAsciiCharValues(bitmap, lookup); + ? new AsciiCharSearchValues(bitmap, lookup) + : new AsciiCharSearchValues(bitmap, lookup); } // Vector128 isn't valid. Treat the values as shorts instead. @@ -126,21 +126,21 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(values)), if (values.Length == 4) { - return new IndexOfAny4Values(shortValues); + return new Any4SearchValues(shortValues); } if (values.Length == 5) { - return new IndexOfAny5Values(shortValues); + return new Any5SearchValues(shortValues); } if (maxInclusive < 256) { // This will also match ASCII values when IndexOfAnyAsciiSearcher is not supported - return new IndexOfAnyLatin1CharValues(values); + return new Latin1CharSearchValues(values); } - return new IndexOfAnyCharValuesProbabilistic(values); + return new ProbabilisticCharSearchValues(values); } private static bool TryGetSingleRange(ReadOnlySpan values, out T minInclusive, out T maxInclusive) diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValuesDebugView.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValuesDebugView.cs similarity index 62% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValuesDebugView.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValuesDebugView.cs index 986ac148001ee2..adfad1b278468a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValuesDebugView.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SearchValuesDebugView.cs @@ -3,11 +3,11 @@ namespace System.Buffers { - internal sealed class IndexOfAnyValuesDebugView where T : IEquatable? + internal sealed class SearchValuesDebugView where T : IEquatable? { - private readonly IndexOfAnyValues _values; + private readonly SearchValues _values; - public IndexOfAnyValuesDebugView(IndexOfAnyValues values) + public SearchValuesDebugView(SearchValues values) { ArgumentNullException.ThrowIfNull(values); _values = values; diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1ByteValue.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SingleByteSearchValues.cs similarity index 90% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1ByteValue.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/SingleByteSearchValues.cs index 3dd3a6aa4fcafe..b768c2541562f7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1ByteValue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SingleByteSearchValues.cs @@ -6,11 +6,11 @@ namespace System.Buffers { - internal sealed class IndexOfAny1ByteValue : IndexOfAnyValues + internal sealed class SingleByteSearchValues : SearchValues { private readonly byte _e0; - public IndexOfAny1ByteValue(ReadOnlySpan values) + public SingleByteSearchValues(ReadOnlySpan values) { Debug.Assert(values.Length == 1); _e0 = values[0]; diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SingleCharSearchValues.cs similarity index 90% rename from src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs rename to src/libraries/System.Private.CoreLib/src/System/SearchValues/SingleCharSearchValues.cs index de7a8968b2d269..b1348e3859b073 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/SingleCharSearchValues.cs @@ -6,12 +6,12 @@ namespace System.Buffers { - internal sealed class IndexOfAny1CharValue : IndexOfAnyValues - where TShouldUsePacked : struct, IndexOfAnyValues.IRuntimeConst + internal sealed class SingleCharSearchValues : SearchValues + where TShouldUsePacked : struct, SearchValues.IRuntimeConst { private char _e0; - public IndexOfAny1CharValue(char value) => + public SingleCharSearchValues(char value) => _e0 = value; internal override char[] GetValues() => new[] { _e0 }; diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs index 6da69bb7ebe630..c48622ca293550 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs @@ -4,6 +4,7 @@ using System.Buffers.Binary; using System.Diagnostics; using System.Numerics; +using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -784,6 +785,7 @@ private static int IndexOfAnyInRange(ref short searchSpace, short lowI return -1; } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 PackSources(Vector256 source0, Vector256 source1) { @@ -824,6 +826,7 @@ private static int ComputeFirstIndex(ref short searchSpace, ref short current, V return index + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref current) / sizeof(short)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int ComputeFirstIndex(ref short searchSpace, ref short current, Vector256 equals) { @@ -846,6 +849,7 @@ private static int ComputeFirstIndexOverlapped(ref short searchSpace, ref short return offsetInVector + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref current0) / sizeof(short)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int ComputeFirstIndexOverlapped(ref short searchSpace, ref short current0, ref short current1, Vector256 equals) { @@ -860,6 +864,7 @@ private static int ComputeFirstIndexOverlapped(ref short searchSpace, ref short return offsetInVector + (int)((nuint)Unsafe.ByteOffset(ref searchSpace, ref current0) / sizeof(short)); } + [BypassReadyToRun] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 FixUpPackedVector256Result(Vector256 result) { diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs index 2aa86a75d80420..7a8dac5644f83d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs @@ -10,19 +10,18 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; using System.Text; namespace System { public partial class String { - // Avoid paying the init cost of all the IndexOfAnyValues unless they are actually used. - internal static class IndexOfAnyValuesStorage + // Avoid paying the init cost of all the SearchValues unless they are actually used. + internal static class SearchValuesStorage { /// - /// IndexOfAnyValues would use SpanHelpers.IndexOfAnyValueType for 5 values in this case. - /// No need to allocate the IndexOfAnyValues as a regular Span.IndexOfAny will use the same implementation. + /// SearchValues would use SpanHelpers.IndexOfAnyValueType for 5 values in this case. + /// No need to allocate the SearchValues as a regular Span.IndexOfAny will use the same implementation. /// public const string NewLineCharsExceptLineFeed = "\r\f\u0085\u2028\u2029"; @@ -32,8 +31,8 @@ internal static class IndexOfAnyValuesStorage /// also specifically excludes VT from the list of newline functions, so we do not include /// it in the needle list. /// - public static readonly IndexOfAnyValues NewLineChars = - IndexOfAnyValues.Create(NewLineCharsExceptLineFeed + "\n"); + public static readonly SearchValues NewLineChars = + SearchValues.Create(NewLineCharsExceptLineFeed + "\n"); } internal const int StackallocIntBufferSizeLimit = 128; @@ -1442,7 +1441,7 @@ private static int IndexOfNewlineChar(ReadOnlySpan text, string replacemen while (true) { - int idx = text.IndexOfAny(IndexOfAnyValuesStorage.NewLineChars); + int idx = text.IndexOfAny(SearchValuesStorage.NewLineChars); if ((uint)idx >= (uint)text.Length) { @@ -1486,7 +1485,7 @@ private string ReplaceLineEndingsWithLineFeed() { // If we are going to replace the new line with a line feed ('\n'), // we can skip looking for it to avoid breaking out of the vectorized path unnecessarily. - int idxOfFirstNewlineChar = this.AsSpan().IndexOfAny(IndexOfAnyValuesStorage.NewLineCharsExceptLineFeed); + int idxOfFirstNewlineChar = this.AsSpan().IndexOfAny(SearchValuesStorage.NewLineCharsExceptLineFeed); if ((uint)idxOfFirstNewlineChar >= (uint)Length) { return this; @@ -1501,7 +1500,7 @@ private string ReplaceLineEndingsWithLineFeed() var builder = new ValueStringBuilder(stackalloc char[StackallocCharBufferSizeLimit]); while (true) { - int idx = remaining.IndexOfAny(IndexOfAnyValuesStorage.NewLineCharsExceptLineFeed); + int idx = remaining.IndexOfAny(SearchValuesStorage.NewLineCharsExceptLineFeed); if ((uint)idx >= (uint)remaining.Length) break; // no more newline chars stride = remaining[idx] == '\r' && (uint)(idx + 1) < (uint)remaining.Length && remaining[idx + 1] == '\n' ? 2 : 1; builder.Append('\n'); diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs index 57b345043e92e0..4d02033b642bfb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs @@ -322,13 +322,8 @@ public override unsafe int GetBytes(ReadOnlySpan chars, Span bytes) } } - // TODO https://github.com/dotnet/runtime/issues/84425: Make this public. - /// Encodes into a span of bytes a set of characters from the specified read-only span if the destination is large enough. - /// The span containing the set of characters to encode. - /// The byte span to hold the encoded bytes. - /// Upon successful completion of the operation, the number of bytes encoded into . - /// if all of the characters were encoded into the destination; if the destination was too small to contain all the encoded bytes. - internal override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) + /// + public override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) { fixed (char* charsPtr = &MemoryMarshal.GetReference(chars)) fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes)) @@ -618,8 +613,26 @@ public override unsafe int GetChars(ReadOnlySpan bytes, Span chars) } } + /// + public override unsafe bool TryGetChars(ReadOnlySpan bytes, Span chars, out int charsWritten) + { + fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes)) + fixed (char* charsPtr = &MemoryMarshal.GetReference(chars)) + { + int written = GetCharsCommon(bytesPtr, bytes.Length, charsPtr, chars.Length, throwForDestinationOverflow: false); + if (written >= 0) + { + charsWritten = written; + return true; + } + + charsWritten = 0; + return false; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe int GetCharsCommon(byte* pBytes, int byteCount, char* pChars, int charCount) + private unsafe int GetCharsCommon(byte* pBytes, int byteCount, char* pChars, int charCount, bool throwForDestinationOverflow = true) { // Common helper method for all non-DecoderNLS entry points to GetChars. // A modification of this method should be copied in to each of the supported encodings: ASCII, UTF8, UTF16, UTF32. @@ -643,7 +656,7 @@ private unsafe int GetCharsCommon(byte* pBytes, int byteCount, char* pChars, int { // Simple narrowing conversion couldn't operate on entire buffer - invoke fallback. - return GetCharsWithFallback(pBytes, byteCount, pChars, charCount, bytesConsumed, charsWritten); + return GetCharsWithFallback(pBytes, byteCount, pChars, charCount, bytesConsumed, charsWritten, throwForDestinationOverflow); } } @@ -654,7 +667,7 @@ private protected sealed override unsafe int GetCharsFast(byte* pBytes, int byte return bytesConsumed; } - private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan bytes, int originalBytesLength, Span chars, int originalCharsLength, DecoderNLS? decoder) + private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan bytes, int originalBytesLength, Span chars, int originalCharsLength, DecoderNLS? decoder, bool throwForDestinationOverflow = true) { // We special-case DecoderReplacementFallback if it's telling us to write a single BMP char, // since we believe this to be relatively common and we can handle it more efficiently than @@ -699,7 +712,7 @@ private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan + /// Determines whether the provided buffers contain equal ASCII characters. + /// + /// The buffer to compare with . + /// The buffer to compare with . + /// if the corresponding elements in and were equal and ASCII. otherwise. + /// If both buffers contain equal, but non-ASCII characters, the method returns . + public static bool Equals(ReadOnlySpan left, ReadOnlySpan right) + { + if (left.Length != right.Length) + { + return false; + } + + if (!Vector128.IsHardwareAccelerated || right.Length < Vector128.Count) + { + for (int i = 0; i < right.Length; i++) + { + byte b = left[i]; + char c = right[i]; + + if (b != c) + { + return false; + } + + if (!UnicodeUtility.IsAsciiCodePoint((uint)(b | c))) + { + return false; + } + } + } + else if (Vector256.IsHardwareAccelerated && right.Length >= Vector256.Count) + { + ref ushort currentCharsSearchSpace = ref Unsafe.As(ref MemoryMarshal.GetReference(right)); + ref ushort oneVectorAwayFromCharsEnd = ref Unsafe.Add(ref currentCharsSearchSpace, right.Length - Vector256.Count); + ref byte currentBytesSearchSpace = ref MemoryMarshal.GetReference(left); + ref byte oneVectorAwayFromBytesEnd = ref Unsafe.Add(ref currentBytesSearchSpace, left.Length - Vector128.Count); + + Vector128 byteValues; + Vector256 charValues; + + // Loop until either we've finished all elements or there's less than a vector's-worth remaining. + do + { + byteValues = Vector128.LoadUnsafe(ref currentBytesSearchSpace); + charValues = Vector256.LoadUnsafe(ref currentCharsSearchSpace); + + // it's OK to widen the bytes, it's NOT OK to narrow the chars (we could loose some information) + if (Vector256.Equals(Widen(byteValues), charValues) != Vector256.AllBitsSet) + { + return false; + } + + if (byteValues.ExtractMostSignificantBits() != 0 || charValues.AsByte().ExtractMostSignificantBits() != 0) + { + return false; + } + + currentCharsSearchSpace = ref Unsafe.Add(ref currentCharsSearchSpace, Vector256.Count); + currentBytesSearchSpace = ref Unsafe.Add(ref currentBytesSearchSpace, Vector128.Count); + } + while (!Unsafe.IsAddressGreaterThan(ref currentCharsSearchSpace, ref oneVectorAwayFromCharsEnd)); + + // If any elements remain, process the last vector in the search space. + if ((uint)right.Length % Vector256.Count != 0) + { + byteValues = Vector128.LoadUnsafe(ref oneVectorAwayFromBytesEnd); + charValues = Vector256.LoadUnsafe(ref oneVectorAwayFromCharsEnd); + + // it's OK to widen the bytes, it's NOT OK to narrow the chars (we could loose some information) + if (Vector256.Equals(Widen(byteValues), charValues) != Vector256.AllBitsSet) + { + return false; + } + + if (byteValues.ExtractMostSignificantBits() != 0 || charValues.AsByte().ExtractMostSignificantBits() != 0) + { + return false; + } + } + } + else + { + ref ushort currentCharsSearchSpace = ref Unsafe.As(ref MemoryMarshal.GetReference(right)); + ref ushort oneVectorAwayFromCharsEnd = ref Unsafe.Add(ref currentCharsSearchSpace, right.Length - Vector128.Count); + ref byte currentBytesSearchSpace = ref MemoryMarshal.GetReference(left); + ref byte oneVectorAwayFromBytesEnd = ref Unsafe.Add(ref currentBytesSearchSpace, left.Length - Vector64.Count); + + Vector64 byteValues; + Vector128 charValues; + + // Loop until either we've finished all elements or there's less than a vector's-worth remaining. + do + { + byteValues = Vector64.LoadUnsafe(ref currentBytesSearchSpace); + charValues = Vector128.LoadUnsafe(ref currentCharsSearchSpace); + + // it's OK to widen the bytes, it's NOT OK to narrow the chars (we could loose some information) + if (Vector128.Equals(Widen(byteValues), charValues) != Vector128.AllBitsSet) + { + return false; + } + + if (VectorContainsNonAsciiChar(byteValues) | VectorContainsNonAsciiChar(charValues)) + { + return false; + } + + currentBytesSearchSpace = ref Unsafe.Add(ref currentBytesSearchSpace, Vector64.Count); + currentCharsSearchSpace = ref Unsafe.Add(ref currentCharsSearchSpace, Vector128.Count); + } + while (!Unsafe.IsAddressGreaterThan(ref currentCharsSearchSpace, ref oneVectorAwayFromCharsEnd)); + + // If any elements remain, process the last vector in the search space. + if ((uint)right.Length % Vector128.Count != 0) + { + charValues = Vector128.LoadUnsafe(ref oneVectorAwayFromCharsEnd); + byteValues = Vector64.LoadUnsafe(ref oneVectorAwayFromBytesEnd); + + // it's OK to widen the bytes, it's NOT OK to narrow the chars (we could loose some information) + if (Vector128.Equals(Widen(byteValues), charValues) != Vector128.AllBitsSet) + { + return false; + } + + if (VectorContainsNonAsciiChar(byteValues) || VectorContainsNonAsciiChar(charValues)) + { + return false; + } + } + } + + return true; + } + + /// + public static bool Equals(ReadOnlySpan left, ReadOnlySpan right) + => left.Length == right.Length && Equals(left, right); + + /// + public static bool Equals(ReadOnlySpan left, ReadOnlySpan right) + => Equals(right, left); + + /// + public static bool Equals(ReadOnlySpan left, ReadOnlySpan right) + => left.Length == right.Length && Equals(MemoryMarshal.Cast(left), MemoryMarshal.Cast(right)); + + private static bool Equals(ReadOnlySpan left, ReadOnlySpan right) where T : unmanaged, INumberBase + { + if (!Vector128.IsHardwareAccelerated || right.Length < Vector128.Count) + { + for (int i = 0; i < right.Length; i++) + { + uint valueA = uint.CreateTruncating(left[i]); + uint valueB = uint.CreateTruncating(right[i]); + + if (valueA != valueB) + { + return false; + } + + if (!UnicodeUtility.IsAsciiCodePoint(valueA | valueB)) + { + return false; + } + } + } + else if (Vector256.IsHardwareAccelerated && right.Length >= Vector256.Count) + { + ref T currentLeftSearchSpace = ref MemoryMarshal.GetReference(left); + ref T oneVectorAwayFromLeftEnd = ref Unsafe.Add(ref currentLeftSearchSpace, left.Length - Vector256.Count); + ref T currentRightSearchSpace = ref MemoryMarshal.GetReference(right); + ref T oneVectorAwayFromRightEnd = ref Unsafe.Add(ref currentRightSearchSpace, right.Length - Vector256.Count); + + Vector256 leftValues; + Vector256 rightValues; + + // Loop until either we've finished all elements or there's less than a vector's-worth remaining. + do + { + leftValues = Vector256.LoadUnsafe(ref currentLeftSearchSpace); + rightValues = Vector256.LoadUnsafe(ref currentRightSearchSpace); + + if (Vector256.Equals(leftValues, rightValues) != Vector256.AllBitsSet) + { + return false; + } + + if (!AllCharsInVectorAreAscii(leftValues | rightValues)) + { + return false; + } + + currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, Vector256.Count); + currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, Vector256.Count); + } + while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + + // If any elements remain, process the last vector in the search space. + if ((uint)right.Length % Vector256.Count != 0) + { + rightValues = Vector256.LoadUnsafe(ref oneVectorAwayFromRightEnd); + leftValues = Vector256.LoadUnsafe(ref oneVectorAwayFromLeftEnd); + + if (Vector256.Equals(leftValues, rightValues) != Vector256.AllBitsSet) + { + return false; + } + + if (!AllCharsInVectorAreAscii(leftValues | rightValues)) + { + return false; + } + } + } + else + { + ref T currentLeftSearchSpace = ref MemoryMarshal.GetReference(left); + ref T oneVectorAwayFromLeftEnd = ref Unsafe.Add(ref currentLeftSearchSpace, left.Length - Vector128.Count); + ref T currentRightSearchSpace = ref MemoryMarshal.GetReference(right); + ref T oneVectorAwayFromRightEnd = ref Unsafe.Add(ref currentRightSearchSpace, right.Length - Vector128.Count); + + Vector128 leftValues; + Vector128 rightValues; + + // Loop until either we've finished all elements or there's less than a vector's-worth remaining. + do + { + leftValues = Vector128.LoadUnsafe(ref currentLeftSearchSpace); + rightValues = Vector128.LoadUnsafe(ref currentRightSearchSpace); + + if (Vector128.Equals(leftValues, rightValues) != Vector128.AllBitsSet) + { + return false; + } + + if (!AllCharsInVectorAreAscii(leftValues | rightValues)) + { + return false; + } + + currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, Vector128.Count); + currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, Vector128.Count); + } + while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + + // If any elements remain, process the last vector in the search space. + if ((uint)right.Length % Vector128.Count != 0) + { + leftValues = Vector128.LoadUnsafe(ref oneVectorAwayFromLeftEnd); + rightValues = Vector128.LoadUnsafe(ref oneVectorAwayFromRightEnd); + + if (Vector128.Equals(leftValues, rightValues) != Vector128.AllBitsSet) + { + return false; + } + + if (!AllCharsInVectorAreAscii(leftValues | rightValues)) + { + return false; + } + } + } + + return true; + } + + /// + /// Determines whether the provided buffers contain equal ASCII characters, ignoring case considerations. + /// + /// The buffer to compare with . + /// The buffer to compare with . + /// if the corresponding elements in and were equal ignoring case considerations and ASCII. otherwise. + /// If both buffers contain equal, but non-ASCII characters, the method returns . + public static bool EqualsIgnoreCase(ReadOnlySpan left, ReadOnlySpan right) + => left.Length == right.Length && SequenceEqualIgnoreCase(left, right); + + /// + public static bool EqualsIgnoreCase(ReadOnlySpan left, ReadOnlySpan right) + => left.Length == right.Length && SequenceEqualIgnoreCase(right, left); + + /// + public static bool EqualsIgnoreCase(ReadOnlySpan left, ReadOnlySpan right) + => EqualsIgnoreCase(right, left); + + /// + public static bool EqualsIgnoreCase(ReadOnlySpan left, ReadOnlySpan right) + => left.Length == right.Length && SequenceEqualIgnoreCase(right, left); + + private static bool SequenceEqualIgnoreCase(ReadOnlySpan left, ReadOnlySpan right) + where TLeft : unmanaged, INumberBase + where TRight : unmanaged, INumberBase + { + Debug.Assert(left.Length == right.Length); + + for (int i = 0; i < left.Length; i++) + { + uint valueA = uint.CreateTruncating(left[i]); + uint valueB = uint.CreateTruncating(right[i]); + + if (!UnicodeUtility.IsAsciiCodePoint(valueA | valueB)) + { + return false; + } + + if (valueA == valueB) + { + continue; // exact match + } + + valueA |= 0x20u; + if ((uint)(valueA - 'a') > (uint)('z' - 'a')) + { + return false; // not exact match, and first input isn't in [A-Za-z] + } + + if (valueA != (valueB | 0x20u)) + { + return false; + } + } + + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 Widen(Vector64 bytes) + { + if (AdvSimd.IsSupported) + { + return AdvSimd.ZeroExtendWideningLower(bytes); + } + else + { + (Vector64 lower, Vector64 upper) = Vector64.Widen(bytes); + return Vector128.Create(lower, upper); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 Widen(Vector128 bytes) + { + (Vector128 lower, Vector128 upper) = Vector128.Widen(bytes); + return Vector256.Create(lower, upper); + } + + private static bool VectorContainsNonAsciiChar(Vector64 bytes) + => !Utf8Utility.AllBytesInUInt64AreAscii(bytes.AsUInt64().ToScalar()); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs b/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs index 27b3df29e82134..3ecac9036eb2e8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs @@ -74,37 +74,24 @@ public static CompositeFormat Parse([StringSyntax(StringSyntaxAttribute.Composit { ArgumentNullException.ThrowIfNull(format); - if (!TryParse(format, out CompositeFormat? compositeFormat)) + var segments = new List<(string? Literal, int ArgIndex, int Alignment, string? Format)>(); + int failureOffset = default; + ExceptionResource failureReason = default; + if (!TryParseLiterals(format, segments, ref failureOffset, ref failureReason)) { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(failureOffset, failureReason); } - return compositeFormat; - } - - /// Try to parse the composite format string . - /// The string to parse. - /// The parsed if parsing was successful; otherwise, null. - /// the can be parsed successfully; otherwise, . - public static bool TryParse([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? format, [NotNullWhen(true)] out CompositeFormat? compositeFormat) - { - if (format is not null) - { - var segments = new List<(string? Literal, int ArgIndex, int Alignment, string? Format)>(); - if (TryParseLiterals(format, segments)) - { - compositeFormat = new CompositeFormat(format, segments.ToArray()); - return true; - } - } - - compositeFormat = null; - return false; + return new CompositeFormat(format, segments.ToArray()); } /// Gets the original composite format string used to create this instance. public string Format { get; } + /// Gets the minimum number of arguments that must be passed to a formatting operation using this . + /// It's permissible to supply more arguments than this value, but it's an error to pass fewer. + public int MinimumArgumentCount => _argsRequired; + /// Throws an exception if the specified number of arguments is fewer than the number required. /// The number of arguments provided by the caller. /// An insufficient number of arguments were provided. @@ -119,8 +106,10 @@ internal void ValidateNumberOfArgs(int numArgs) /// Parse the composite format string into segments. /// The format string. /// The list into which to store the segments. + /// The offset at which a parsing error occured if is returned. + /// The reason for a parsing failure if is returned. /// true if the format string can be parsed successfully; otherwise, false. - private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Literal, int ArgIndex, int Alignment, string? Format)> segments) + private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Literal, int ArgIndex, int Alignment, string? Format)> segments, ref int failureOffset, ref ExceptionResource failureReason) { // This parsing logic is copied from string.Format. It's the same code modified to not format // as part of parsing and instead store the parsed literals and argument specifiers (alignment @@ -161,7 +150,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li char brace = format[pos]; if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } if (brace == ch) { @@ -173,7 +162,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li // This wasn't an escape, so it must be an opening brace. if (brace != '{') { - return false; + goto FailureUnexpectedClosingBrace; } // Proceed to parse the hole. @@ -197,14 +186,14 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li int index = ch - '0'; if ((uint)index >= 10u) { - return false; + goto FailureExpectedAsciiDigit; } // Common case is a single digit index followed by a closing brace. If it's not a closing brace, // proceed to finish parsing the full hole format. if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } if (ch != '}') { @@ -214,7 +203,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li index = index * 10 + ch - '0'; if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } } @@ -223,7 +212,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li { if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } } @@ -240,7 +229,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li { if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } } while (ch == ' '); @@ -252,7 +241,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li leftJustify = -1; if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } } @@ -260,18 +249,18 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li width = ch - '0'; if ((uint)width >= 10u) { - return false; + goto FailureExpectedAsciiDigit; } if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } while (char.IsAsciiDigit(ch)) { width = width * 10 + ch - '0'; if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } } width *= leftJustify; @@ -281,7 +270,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li { if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } } } @@ -293,7 +282,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li if (ch != ':') { // Unexpected character - return false; + goto FailureUnclosedFormatItem; } // Search for the closing brace; everything in between is the format, @@ -303,7 +292,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li { if (!TryMoveNext(format, ref pos, out ch)) { - return false; + goto FailureUnclosedFormatItem; } if (ch == '}') @@ -315,7 +304,7 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li if (ch == '{') { // Braces inside the argument hole are not supported - return false; + goto FailureUnclosedFormatItem; } } @@ -332,6 +321,21 @@ private static bool TryParseLiterals(ReadOnlySpan format, List<(string? Li // Continue parsing the rest of the format string. } + FailureUnexpectedClosingBrace: + failureReason = ExceptionResource.Format_UnexpectedClosingBrace; + failureOffset = pos; + return false; + + FailureUnclosedFormatItem: + failureReason = ExceptionResource.Format_UnclosedFormatItem; + failureOffset = pos; + return false; + + FailureExpectedAsciiDigit: + failureReason = ExceptionResource.Format_ExpectedAsciiDigit; + failureOffset = pos; + return false; + [MethodImpl(MethodImplOptions.AggressiveInlining)] static bool TryMoveNext(ReadOnlySpan format, ref int pos, out char nextChar) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.Internal.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.Internal.cs index 874513163002a7..5ccf6b9039b8e0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.Internal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.Internal.cs @@ -1081,7 +1081,7 @@ private protected virtual unsafe int GetCharsFast(byte* pBytes, int bytesLength, /// If the destination buffer is not large enough to hold the entirety of the transcoded data. /// [MethodImpl(MethodImplOptions.NoInlining)] - private protected unsafe int GetCharsWithFallback(byte* pOriginalBytes, int originalByteCount, char* pOriginalChars, int originalCharCount, int bytesConsumedSoFar, int charsWrittenSoFar) + private protected unsafe int GetCharsWithFallback(byte* pOriginalBytes, int originalByteCount, char* pOriginalChars, int originalCharCount, int bytesConsumedSoFar, int charsWrittenSoFar, bool throwForDestinationOverflow = true) { // This is a stub method that's marked "no-inlining" so that it we don't stack-spill spans // into our immediate caller. Doing so increases the method prolog in what's supposed to @@ -1095,7 +1095,8 @@ private protected unsafe int GetCharsWithFallback(byte* pOriginalBytes, int orig originalBytesLength: originalByteCount, chars: new Span(pOriginalChars, originalCharCount).Slice(charsWrittenSoFar), originalCharsLength: originalCharCount, - decoder: null); + decoder: null, + throwForDestinationOverflow); } /// @@ -1104,7 +1105,7 @@ private protected unsafe int GetCharsWithFallback(byte* pOriginalBytes, int orig /// and signal where in the provided buffers the fallback loop /// should begin operating. The behavior of this method is to drain any leftover data in the /// instance, then to invoke the virtual method - /// after data has been drained, then to call . + /// after data has been drained, then to call GetCharsWithFallback(ReadOnlySpan{byte}, int, Span{char}, int, DecoderNLS, out bool)/>. /// /// /// The total number of chars written to , including . @@ -1183,7 +1184,7 @@ private protected unsafe int GetCharsWithFallback(byte* pOriginalBytes, int orig /// implementation, deferring to the base implementation if needed. This method calls /// if necessary. /// - private protected virtual unsafe int GetCharsWithFallback(ReadOnlySpan bytes, int originalBytesLength, Span chars, int originalCharsLength, DecoderNLS? decoder) + private protected virtual unsafe int GetCharsWithFallback(ReadOnlySpan bytes, int originalBytesLength, Span chars, int originalCharsLength, DecoderNLS? decoder, bool throwForDestinationOverflow = true) { Debug.Assert(!bytes.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer."); Debug.Assert(originalBytesLength >= 0, "Caller provided invalid parameter."); @@ -1272,11 +1273,18 @@ private protected virtual unsafe int GetCharsWithFallback(ReadOnlySpan byt if (!bytes.IsEmpty) { - // The line below will also throw if the decoder couldn't make any progress at all - // because the output buffer wasn't large enough to contain the result of even - // a single scalar conversion or fallback. - - ThrowCharsOverflow(decoder, nothingDecoded: chars.Length == originalCharsLength); + if (throwForDestinationOverflow) + { + // The line below will also throw if the decoder couldn't make any progress at all + // because the output buffer wasn't large enough to contain the result of even + // a single scalar conversion or fallback. + ThrowCharsOverflow(decoder, nothingDecoded: chars.Length == originalCharsLength); + } + else + { + Debug.Assert(decoder is null); + return -1; + } } // If a DecoderNLS instance is active, update its "total consumed byte count" value. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs index 5ebbeeafcfadd4..9935024ae8fc33 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs @@ -733,13 +733,12 @@ public virtual unsafe int GetBytes(ReadOnlySpan chars, Span bytes) } } - // TODO https://github.com/dotnet/runtime/issues/84425: Make this public. /// Encodes into a span of bytes a set of characters from the specified read-only span if the destination is large enough. /// The span containing the set of characters to encode. /// The byte span to hold the encoded bytes. /// Upon successful completion of the operation, the number of bytes encoded into . /// if all of the characters were encoded into the destination; if the destination was too small to contain all the encoded bytes. - internal virtual bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) + public virtual bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) { int required = GetByteCount(chars); if (required <= bytes.Length) @@ -883,6 +882,24 @@ public virtual unsafe int GetChars(ReadOnlySpan bytes, Span chars) } } + /// Decodes into a span of chars a set of bytes from the specified read-only span if the destination is large enough. + /// A read-only span containing the sequence of bytes to decode. + /// The character span receiving the decoded bytes. + /// Upon successful completion of the operation, the number of chars decoded into . + /// if all of the characters were decoded into the destination; if the destination was too small to contain all the decoded chars. + public virtual bool TryGetChars(ReadOnlySpan bytes, Span chars, out int charsWritten) + { + int required = GetCharCount(bytes); + if (required <= chars.Length) + { + charsWritten = GetChars(bytes, chars); + return true; + } + + charsWritten = 0; + return false; + } + [CLSCompliant(false)] public unsafe string GetString(byte* bytes, int byteCount) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs index 7167d4de6d6dbf..04d0e4f93e09a7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs @@ -234,13 +234,8 @@ public override unsafe int GetBytes(ReadOnlySpan chars, Span bytes) } } - // TODO https://github.com/dotnet/runtime/issues/84425: Make this public. - /// Encodes into a span of bytes a set of characters from the specified read-only span if the destination is large enough. - /// The span containing the set of characters to encode. - /// The byte span to hold the encoded bytes. - /// Upon successful completion of the operation, the number of bytes encoded into . - /// if all of the characters were encoded into the destination; if the destination was too small to contain all the encoded bytes. - internal override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) + /// + public override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) { fixed (char* charsPtr = &MemoryMarshal.GetReference(chars)) fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes)) @@ -534,6 +529,23 @@ public override unsafe int GetChars(ReadOnlySpan bytes, Span chars) } } + /// + public override unsafe bool TryGetChars(ReadOnlySpan bytes, Span chars, out int charsWritten) + { + if (bytes.Length <= chars.Length) + { + fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes)) + fixed (char* charsPtr = &MemoryMarshal.GetReference(chars)) + { + charsWritten = GetCharsCommon(bytesPtr, bytes.Length, charsPtr, chars.Length); + return true; + } + } + + charsWritten = 0; + return false; + } + public override unsafe string GetString(byte[] bytes) { if (bytes is null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/SpanLineEnumerator.cs b/src/libraries/System.Private.CoreLib/src/System/Text/SpanLineEnumerator.cs index a9b13d67e51a26..3741d16eaa200c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/SpanLineEnumerator.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/SpanLineEnumerator.cs @@ -48,7 +48,7 @@ public bool MoveNext() ReadOnlySpan remaining = _remaining; - int idx = remaining.IndexOfAny(string.IndexOfAnyValuesStorage.NewLineChars); + int idx = remaining.IndexOfAny(string.SearchValuesStorage.NewLineChars); if ((uint)idx < (uint)remaining.Length) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs index 2d59fc8e08b85e..e2ea2a6b5d1455 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs @@ -1439,7 +1439,7 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form // This wasn't an escape, so it must be an opening brace. if (brace != '{') { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnexpectedClosingBrace); } // Proceed to parse the hole. @@ -1462,7 +1462,7 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form int index = ch - '0'; if ((uint)index >= 10u) { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_ExpectedAsciiDigit); } // Common case is a single digit index followed by a closing brace. If it's not a closing brace, @@ -1509,7 +1509,7 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form width = ch - '0'; if ((uint)width >= 10u) { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_ExpectedAsciiDigit); } ch = MoveNext(format, ref pos); while (char.IsAsciiDigit(ch) && width < WidthLimit) @@ -1532,7 +1532,7 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form if (ch != ':') { // Unexpected character - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnclosedFormatItem); } // Search for the closing brace; everything in between is the format, @@ -1551,7 +1551,7 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form if (ch == '{') { // Braces inside the argument hole are not supported - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnclosedFormatItem); } } @@ -1652,7 +1652,7 @@ static char MoveNext(string format, ref int pos) pos++; if ((uint)pos >= (uint)format.Length) { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnclosedFormatItem); } return format[pos]; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.Sealed.cs b/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.Sealed.cs index 3679e90e34d593..dc5f36deca8de2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.Sealed.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.Sealed.cs @@ -147,9 +147,9 @@ private unsafe string GetStringForSmallInput(byte[] bytes) return new string(new ReadOnlySpan(ref *pDestination, charsWritten)); // this overload of ROS ctor doesn't validate length } - // TODO https://github.com/dotnet/runtime/issues/84425: Make this public. // TODO: Make this [Intrinsic] and handle JIT-time UTF8 encoding of literal `chars`. - internal override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) + /// + public override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) { return base.TryGetBytes(chars, bytes, out bytesWritten); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.cs index 9bb500f5ddf074..f4eb8a5358a20a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/UTF8Encoding.cs @@ -369,13 +369,8 @@ public override unsafe int GetBytes(ReadOnlySpan chars, Span bytes) } } - // TODO https://github.com/dotnet/runtime/issues/84425: Make this public. - /// Encodes into a span of bytes a set of characters from the specified read-only span if the destination is large enough. - /// The span containing the set of characters to encode. - /// The byte span to hold the encoded bytes. - /// Upon successful completion of the operation, the number of bytes encoded into . - /// if all of the characters were encoded into the destination; if the destination was too small to contain all the encoded bytes. - internal override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) + /// + public override unsafe bool TryGetBytes(ReadOnlySpan chars, Span bytes, out int bytesWritten) { fixed (char* charsPtr = &MemoryMarshal.GetReference(chars)) fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes)) @@ -569,6 +564,24 @@ public override unsafe int GetChars(ReadOnlySpan bytes, Span chars) } } + /// + public override unsafe bool TryGetChars(ReadOnlySpan bytes, Span chars, out int charsWritten) + { + fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes)) + fixed (char* charsPtr = &MemoryMarshal.GetReference(chars)) + { + int written = GetCharsCommon(bytesPtr, bytes.Length, charsPtr, chars.Length, throwForDestinationOverflow: false); + if (written >= 0) + { + charsWritten = written; + return true; + } + + charsWritten = 0; + return false; + } + } + // WARNING: If we throw an error, then System.Resources.ResourceReader calls this method. // So if we're really broken, then that could also throw an error... recursively. // So try to make sure GetChars can at least process all uses by @@ -577,7 +590,7 @@ public override unsafe int GetChars(ReadOnlySpan bytes, Span chars) // Note: We throw exceptions on individually encoded surrogates and other non-shortest forms. // If exceptions aren't turned on, then we drop all non-shortest &individual surrogates. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe int GetCharsCommon(byte* pBytes, int byteCount, char* pChars, int charCount) + private unsafe int GetCharsCommon(byte* pBytes, int byteCount, char* pChars, int charCount, bool throwForDestinationOverflow = true) { // Common helper method for all non-DecoderNLS entry points to GetChars. // A modification of this method should be copied in to each of the supported encodings: ASCII, UTF8, UTF16, UTF32. @@ -601,7 +614,7 @@ private unsafe int GetCharsCommon(byte* pBytes, int byteCount, char* pChars, int { // Simple narrowing conversion couldn't operate on entire buffer - invoke fallback. - return GetCharsWithFallback(pBytes, byteCount, pChars, charCount, bytesConsumed, charsWritten); + return GetCharsWithFallback(pBytes, byteCount, pChars, charCount, bytesConsumed, charsWritten, throwForDestinationOverflow); } } @@ -618,7 +631,7 @@ private protected sealed override unsafe int GetCharsFast(byte* pBytes, int byte return (int)(pOutputBufferRemaining - pChars); } - private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan bytes, int originalBytesLength, Span chars, int originalCharsLength, DecoderNLS? decoder) + private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan bytes, int originalBytesLength, Span chars, int originalCharsLength, DecoderNLS? decoder, bool throwForDestinationOverflow = true) { // We special-case DecoderReplacementFallback if it's telling us to write a single U+FFFD char, // since we believe this to be relatively common and we can handle it more efficiently than @@ -649,7 +662,7 @@ private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan(T value) return AppendCustomFormatter(value, format: null); } + // Special-case enums to avoid boxing them. + if (typeof(T).IsEnum) + { + // TODO https://github.com/dotnet/runtime/issues/81500: + // Once Enum.TryFormat provides direct UTF8 support, use that here instead. + return AppendEnum(value, format: null); + } + // If the value can format itself directly into our buffer, do so. if (value is IUtf8SpanFormattable) { @@ -373,6 +381,14 @@ public bool AppendFormatted(T value, string? format) return AppendCustomFormatter(value, format); } + // Special-case enums to avoid boxing them. + if (typeof(T).IsEnum) + { + // TODO https://github.com/dotnet/runtime/issues/81500: + // Once Enum.TryFormat provides direct UTF8 support, use that here instead. + return AppendEnum(value, format); + } + // If the value can format itself directly into our buffer, do so. if (value is IUtf8SpanFormattable) { @@ -546,7 +562,7 @@ private bool AppendCustomFormatter(T value, string? format) } /// Writes the specified ISpanFormattable to the handler. - /// The value to write. It must be an ISpanFormattable but isn't constrained because the caller doesn't have a cosntraint. + /// The value to write. It must be an ISpanFormattable but isn't constrained because the caller doesn't have a constraint. /// The format string. [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool AppendSpanFormattable(T value, string? format) @@ -590,6 +606,53 @@ static bool GrowAndAppendFormatted(scoped ref TryWriteInterpolatedStringHandler } } + // TODO https://github.com/dotnet/runtime/issues/81500: + // Remove once Enum.TryFormat(Span, ...) is available. + /// Writes the specified enum to the handler. + /// The value to write. It must be an enum but isn't constrained because the caller doesn't have a constraint. + /// The format string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool AppendEnum(T value, string? format) + { + Debug.Assert(typeof(T).IsEnum); + + Span utf16 = stackalloc char[256]; + return Enum.TryFormatUnconstrained(value, utf16, out int charsWritten, format) ? + AppendFormatted(utf16.Slice(0, charsWritten)) : + GrowAndAppendFormatted(ref this, value, utf16.Length, out charsWritten, format); + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool GrowAndAppendFormatted(scoped ref TryWriteInterpolatedStringHandler thisRef, T value, int length, out int charsWritten, string? format) + { + Debug.Assert(value is ISpanFormattable); + + while (true) + { + int newLength = length * 2; + if ((uint)newLength > Array.MaxLength) + { + newLength = length == Array.MaxLength ? + Array.MaxLength + 1 : // force OOM + Array.MaxLength; + } + length = newLength; + + char[] array = ArrayPool.Shared.Rent(length); + try + { + if (Enum.TryFormatUnconstrained(value, array, out charsWritten, format)) + { + return thisRef.AppendFormatted(array.AsSpan(0, charsWritten)); + } + } + finally + { + ArrayPool.Shared.Return(array); + } + } + } + } + /// Handles adding any padding required for aligning a formatted value in an interpolation expression. /// The position at which the written value started. /// Non-zero minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ValueStringBuilder.AppendFormat.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ValueStringBuilder.AppendFormat.cs index 2226831448dcb4..4c618953c237a7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ValueStringBuilder.AppendFormat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ValueStringBuilder.AppendFormat.cs @@ -64,7 +64,7 @@ internal void AppendFormatHelper(IFormatProvider? provider, string format, ReadO // This wasn't an escape, so it must be an opening brace. if (brace != '{') { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnexpectedClosingBrace); } // Proceed to parse the hole. @@ -87,7 +87,7 @@ internal void AppendFormatHelper(IFormatProvider? provider, string format, ReadO int index = ch - '0'; if ((uint)index >= 10u) { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_ExpectedAsciiDigit); } // Common case is a single digit index followed by a closing brace. If it's not a closing brace, @@ -134,7 +134,7 @@ internal void AppendFormatHelper(IFormatProvider? provider, string format, ReadO width = ch - '0'; if ((uint)width >= 10u) { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_ExpectedAsciiDigit); } ch = MoveNext(format, ref pos); while (char.IsAsciiDigit(ch) && width < WidthLimit) @@ -157,7 +157,7 @@ internal void AppendFormatHelper(IFormatProvider? provider, string format, ReadO if (ch != ':') { // Unexpected character - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnclosedFormatItem); } // Search for the closing brace; everything in between is the format, @@ -176,7 +176,7 @@ internal void AppendFormatHelper(IFormatProvider? provider, string format, ReadO if (ch == '{') { // Braces inside the argument hole are not supported - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnclosedFormatItem); } } @@ -269,7 +269,7 @@ static char MoveNext(string format, ref int pos) pos++; if ((uint)pos >= (uint)format.Length) { - ThrowHelper.ThrowFormatInvalidString(); + ThrowHelper.ThrowFormatInvalidString(pos, ExceptionResource.Format_UnclosedFormatItem); } return format[pos]; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs index 7b6e7e7bf1427b..c9d5582e72759b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs @@ -50,7 +50,7 @@ public bool WaitCore(int timeoutMs) return success; } - public void ReleaseCore(int count) + protected override void ReleaseCore(int count) { Debug.Assert(count > 0); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.cs index 25a229c87ef66a..f555dff7d4eb59 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.cs @@ -11,29 +11,13 @@ namespace System.Threading /// A LIFO semaphore. /// Waits on this semaphore are uninterruptible. /// - internal sealed partial class LowLevelLifoSemaphore : IDisposable + internal sealed partial class LowLevelLifoSemaphore : LowLevelLifoSemaphoreBase, IDisposable { - private CacheLineSeparatedCounts _separated; - - private readonly int _maximumSignalCount; - private readonly int _spinCount; - private readonly Action _onWait; - private const int SpinSleep0Threshold = 10; public LowLevelLifoSemaphore(int initialSignalCount, int maximumSignalCount, int spinCount, Action onWait) + : base (initialSignalCount, maximumSignalCount, spinCount, onWait) { - Debug.Assert(initialSignalCount >= 0); - Debug.Assert(initialSignalCount <= maximumSignalCount); - Debug.Assert(maximumSignalCount > 0); - Debug.Assert(spinCount >= 0); - - _separated = default; - _separated._counts.SignalCount = (uint)initialSignalCount; - _maximumSignalCount = maximumSignalCount; - _spinCount = spinCount; - _onWait = onWait; - Create(maximumSignalCount); } @@ -144,55 +128,6 @@ public bool Wait(int timeoutMs, bool spinWait) } } - public void Release(int releaseCount) - { - Debug.Assert(releaseCount > 0); - Debug.Assert(releaseCount <= _maximumSignalCount); - - int countOfWaitersToWake; - Counts counts = _separated._counts; - while (true) - { - Counts newCounts = counts; - - // Increase the signal count. The addition doesn't overflow because of the limit on the max signal count in constructor. - newCounts.AddSignalCount((uint)releaseCount); - - // Determine how many waiters to wake, taking into account how many spinners and waiters there are and how many waiters - // have previously been signaled to wake but have not yet woken - countOfWaitersToWake = - (int)Math.Min(newCounts.SignalCount, (uint)counts.WaiterCount + counts.SpinnerCount) - - counts.SpinnerCount - - counts.CountOfWaitersSignaledToWake; - if (countOfWaitersToWake > 0) - { - // Ideally, limiting to a maximum of releaseCount would not be necessary and could be an assert instead, but since - // WaitForSignal() does not have enough information to tell whether a woken thread was signaled, and due to the cap - // below, it's possible for countOfWaitersSignaledToWake to be less than the number of threads that have actually - // been signaled to wake. - if (countOfWaitersToWake > releaseCount) - { - countOfWaitersToWake = releaseCount; - } - - // Cap countOfWaitersSignaledToWake to its max value. It's ok to ignore some woken threads in this count, it just - // means some more threads will be woken next time. Typically, it won't reach the max anyway. - newCounts.AddUpToMaxCountOfWaitersSignaledToWake((uint)countOfWaitersToWake); - } - - Counts countsBeforeUpdate = _separated._counts.InterlockedCompareExchange(newCounts, counts); - if (countsBeforeUpdate == counts) - { - Debug.Assert(releaseCount <= _maximumSignalCount - counts.SignalCount); - if (countOfWaitersToWake > 0) - ReleaseCore(countOfWaitersToWake); - return; - } - - counts = countsBeforeUpdate; - } - } - private bool WaitForSignal(int timeoutMs) { Debug.Assert(timeoutMs > 0 || timeoutMs == -1); @@ -201,13 +136,15 @@ private bool WaitForSignal(int timeoutMs) while (true) { - if (!WaitCore(timeoutMs)) + int startWaitTicks = timeoutMs != -1 ? Environment.TickCount : 0; + if (timeoutMs == 0 || !WaitCore(timeoutMs)) { // Unregister the waiter. The wait subsystem used above guarantees that a thread that wakes due to a timeout does // not observe a signal to the object being waited upon. _separated._counts.InterlockedDecrementWaiterCount(); return false; } + int endWaitTicks = timeoutMs != -1 ? Environment.TickCount : 0; // Unregister the waiter if this thread will not be waiting anymore, and try to acquire the semaphore Counts counts = _separated._counts; @@ -238,132 +175,15 @@ private bool WaitForSignal(int timeoutMs) } counts = countsBeforeUpdate; + if (timeoutMs != -1) { + int waitMs = endWaitTicks - startWaitTicks; + if (waitMs >= 0 && waitMs < timeoutMs) + timeoutMs -= waitMs; + else + timeoutMs = 0; + } } } } - - private struct Counts : IEquatable - { - private const byte SignalCountShift = 0; - private const byte WaiterCountShift = 32; - private const byte SpinnerCountShift = 48; - private const byte CountOfWaitersSignaledToWakeShift = 56; - - private ulong _data; - - private Counts(ulong data) => _data = data; - - private uint GetUInt32Value(byte shift) => (uint)(_data >> shift); - private void SetUInt32Value(uint value, byte shift) => - _data = (_data & ~((ulong)uint.MaxValue << shift)) | ((ulong)value << shift); - private ushort GetUInt16Value(byte shift) => (ushort)(_data >> shift); - private void SetUInt16Value(ushort value, byte shift) => - _data = (_data & ~((ulong)ushort.MaxValue << shift)) | ((ulong)value << shift); - private byte GetByteValue(byte shift) => (byte)(_data >> shift); - private void SetByteValue(byte value, byte shift) => - _data = (_data & ~((ulong)byte.MaxValue << shift)) | ((ulong)value << shift); - - public uint SignalCount - { - get => GetUInt32Value(SignalCountShift); - set => SetUInt32Value(value, SignalCountShift); - } - - public void AddSignalCount(uint value) - { - Debug.Assert(value <= uint.MaxValue - SignalCount); - _data += (ulong)value << SignalCountShift; - } - - public void IncrementSignalCount() => AddSignalCount(1); - - public void DecrementSignalCount() - { - Debug.Assert(SignalCount != 0); - _data -= (ulong)1 << SignalCountShift; - } - - public ushort WaiterCount - { - get => GetUInt16Value(WaiterCountShift); - set => SetUInt16Value(value, WaiterCountShift); - } - - public void IncrementWaiterCount() - { - Debug.Assert(WaiterCount < ushort.MaxValue); - _data += (ulong)1 << WaiterCountShift; - } - - public void DecrementWaiterCount() - { - Debug.Assert(WaiterCount != 0); - _data -= (ulong)1 << WaiterCountShift; - } - - public void InterlockedDecrementWaiterCount() - { - var countsAfterUpdate = new Counts(Interlocked.Add(ref _data, unchecked((ulong)-1) << WaiterCountShift)); - Debug.Assert(countsAfterUpdate.WaiterCount != ushort.MaxValue); // underflow check - } - - public byte SpinnerCount - { - get => GetByteValue(SpinnerCountShift); - set => SetByteValue(value, SpinnerCountShift); - } - - public void IncrementSpinnerCount() - { - Debug.Assert(SpinnerCount < byte.MaxValue); - _data += (ulong)1 << SpinnerCountShift; - } - - public void DecrementSpinnerCount() - { - Debug.Assert(SpinnerCount != 0); - _data -= (ulong)1 << SpinnerCountShift; - } - - public byte CountOfWaitersSignaledToWake - { - get => GetByteValue(CountOfWaitersSignaledToWakeShift); - set => SetByteValue(value, CountOfWaitersSignaledToWakeShift); - } - - public void AddUpToMaxCountOfWaitersSignaledToWake(uint value) - { - uint availableCount = (uint)(byte.MaxValue - CountOfWaitersSignaledToWake); - if (value > availableCount) - { - value = availableCount; - } - _data += (ulong)value << CountOfWaitersSignaledToWakeShift; - } - - public void DecrementCountOfWaitersSignaledToWake() - { - Debug.Assert(CountOfWaitersSignaledToWake != 0); - _data -= (ulong)1 << CountOfWaitersSignaledToWakeShift; - } - - public Counts InterlockedCompareExchange(Counts newCounts, Counts oldCounts) => - new Counts(Interlocked.CompareExchange(ref _data, newCounts._data, oldCounts._data)); - - public static bool operator ==(Counts lhs, Counts rhs) => lhs.Equals(rhs); - public static bool operator !=(Counts lhs, Counts rhs) => !lhs.Equals(rhs); - - public override bool Equals([NotNullWhen(true)] object? obj) => obj is Counts other && Equals(other); - public bool Equals(Counts other) => _data == other._data; - public override int GetHashCode() => (int)_data + (int)(_data >> 32); - } - - [StructLayout(LayoutKind.Sequential)] - private struct CacheLineSeparatedCounts - { - private readonly Internal.PaddingFor32 _pad1; - public Counts _counts; - private readonly Internal.PaddingFor32 _pad2; - } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphoreBase.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphoreBase.cs new file mode 100644 index 00000000000000..cb4df549b080dd --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphoreBase.cs @@ -0,0 +1,211 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace System.Threading +{ + /// + /// A LIFO semaphore. + /// Waits on this semaphore are uninterruptible. + /// + internal abstract class LowLevelLifoSemaphoreBase + { + protected CacheLineSeparatedCounts _separated; + + protected readonly int _maximumSignalCount; + protected readonly int _spinCount; + protected readonly Action _onWait; + + public LowLevelLifoSemaphoreBase(int initialSignalCount, int maximumSignalCount, int spinCount, Action onWait) + { + Debug.Assert(initialSignalCount >= 0); + Debug.Assert(initialSignalCount <= maximumSignalCount); + Debug.Assert(maximumSignalCount > 0); + Debug.Assert(spinCount >= 0); + + _separated = default; + _separated._counts.SignalCount = (uint)initialSignalCount; + _maximumSignalCount = maximumSignalCount; + _spinCount = spinCount; + _onWait = onWait; + } + + protected abstract void ReleaseCore(int count); + + public void Release(int releaseCount) + { + Debug.Assert(releaseCount > 0); + Debug.Assert(releaseCount <= _maximumSignalCount); + + int countOfWaitersToWake; + Counts counts = _separated._counts; + while (true) + { + Counts newCounts = counts; + + // Increase the signal count. The addition doesn't overflow because of the limit on the max signal count in constructor. + newCounts.AddSignalCount((uint)releaseCount); + + // Determine how many waiters to wake, taking into account how many spinners and waiters there are and how many waiters + // have previously been signaled to wake but have not yet woken + countOfWaitersToWake = + (int)Math.Min(newCounts.SignalCount, (uint)counts.WaiterCount + counts.SpinnerCount) - + counts.SpinnerCount - + counts.CountOfWaitersSignaledToWake; + if (countOfWaitersToWake > 0) + { + // Ideally, limiting to a maximum of releaseCount would not be necessary and could be an assert instead, but since + // WaitForSignal() does not have enough information to tell whether a woken thread was signaled, and due to the cap + // below, it's possible for countOfWaitersSignaledToWake to be less than the number of threads that have actually + // been signaled to wake. + if (countOfWaitersToWake > releaseCount) + { + countOfWaitersToWake = releaseCount; + } + + // Cap countOfWaitersSignaledToWake to its max value. It's ok to ignore some woken threads in this count, it just + // means some more threads will be woken next time. Typically, it won't reach the max anyway. + newCounts.AddUpToMaxCountOfWaitersSignaledToWake((uint)countOfWaitersToWake); + } + + Counts countsBeforeUpdate = _separated._counts.InterlockedCompareExchange(newCounts, counts); + if (countsBeforeUpdate == counts) + { + Debug.Assert(releaseCount <= _maximumSignalCount - counts.SignalCount); + if (countOfWaitersToWake > 0) + ReleaseCore(countOfWaitersToWake); + return; + } + + counts = countsBeforeUpdate; + } + } + + protected struct Counts : IEquatable + { + private const byte SignalCountShift = 0; + private const byte WaiterCountShift = 32; + private const byte SpinnerCountShift = 48; + private const byte CountOfWaitersSignaledToWakeShift = 56; + + private ulong _data; + + private Counts(ulong data) => _data = data; + + private uint GetUInt32Value(byte shift) => (uint)(_data >> shift); + private void SetUInt32Value(uint value, byte shift) => + _data = (_data & ~((ulong)uint.MaxValue << shift)) | ((ulong)value << shift); + private ushort GetUInt16Value(byte shift) => (ushort)(_data >> shift); + private void SetUInt16Value(ushort value, byte shift) => + _data = (_data & ~((ulong)ushort.MaxValue << shift)) | ((ulong)value << shift); + private byte GetByteValue(byte shift) => (byte)(_data >> shift); + private void SetByteValue(byte value, byte shift) => + _data = (_data & ~((ulong)byte.MaxValue << shift)) | ((ulong)value << shift); + + public uint SignalCount + { + get => GetUInt32Value(SignalCountShift); + set => SetUInt32Value(value, SignalCountShift); + } + + public void AddSignalCount(uint value) + { + Debug.Assert(value <= uint.MaxValue - SignalCount); + _data += (ulong)value << SignalCountShift; + } + + public void IncrementSignalCount() => AddSignalCount(1); + + public void DecrementSignalCount() + { + Debug.Assert(SignalCount != 0); + _data -= (ulong)1 << SignalCountShift; + } + + public ushort WaiterCount + { + get => GetUInt16Value(WaiterCountShift); + set => SetUInt16Value(value, WaiterCountShift); + } + + public void IncrementWaiterCount() + { + Debug.Assert(WaiterCount < ushort.MaxValue); + _data += (ulong)1 << WaiterCountShift; + } + + public void DecrementWaiterCount() + { + Debug.Assert(WaiterCount != 0); + _data -= (ulong)1 << WaiterCountShift; + } + + public void InterlockedDecrementWaiterCount() + { + var countsAfterUpdate = new Counts(Interlocked.Add(ref _data, unchecked((ulong)-1) << WaiterCountShift)); + Debug.Assert(countsAfterUpdate.WaiterCount != ushort.MaxValue); // underflow check + } + + public byte SpinnerCount + { + get => GetByteValue(SpinnerCountShift); + set => SetByteValue(value, SpinnerCountShift); + } + + public void IncrementSpinnerCount() + { + Debug.Assert(SpinnerCount < byte.MaxValue); + _data += (ulong)1 << SpinnerCountShift; + } + + public void DecrementSpinnerCount() + { + Debug.Assert(SpinnerCount != 0); + _data -= (ulong)1 << SpinnerCountShift; + } + + public byte CountOfWaitersSignaledToWake + { + get => GetByteValue(CountOfWaitersSignaledToWakeShift); + set => SetByteValue(value, CountOfWaitersSignaledToWakeShift); + } + + public void AddUpToMaxCountOfWaitersSignaledToWake(uint value) + { + uint availableCount = (uint)(byte.MaxValue - CountOfWaitersSignaledToWake); + if (value > availableCount) + { + value = availableCount; + } + _data += (ulong)value << CountOfWaitersSignaledToWakeShift; + } + + public void DecrementCountOfWaitersSignaledToWake() + { + Debug.Assert(CountOfWaitersSignaledToWake != 0); + _data -= (ulong)1 << CountOfWaitersSignaledToWakeShift; + } + + public Counts InterlockedCompareExchange(Counts newCounts, Counts oldCounts) => + new Counts(Interlocked.CompareExchange(ref _data, newCounts._data, oldCounts._data)); + + public static bool operator ==(Counts lhs, Counts rhs) => lhs.Equals(rhs); + public static bool operator !=(Counts lhs, Counts rhs) => !lhs.Equals(rhs); + + public override bool Equals([NotNullWhen(true)] object? obj) => obj is Counts other && Equals(other); + public bool Equals(Counts other) => _data == other._data; + public override int GetHashCode() => (int)_data + (int)(_data >> 32); + } + + [StructLayout(LayoutKind.Sequential)] + protected struct CacheLineSeparatedCounts + { + private readonly Internal.PaddingFor32 _pad1; + public Counts _counts; + private readonly Internal.PaddingFor32 _pad2; + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs index 39e1d6453263e7..a9c4e038129a48 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs @@ -19,7 +19,9 @@ public static partial class ThreadPool { // Indicates whether the thread pool should yield the thread from the dispatch loop to the runtime periodically so that // the runtime may use the thread for processing other work +#if !(TARGET_BROWSER && FEATURE_WASM_THREADS) internal static bool YieldFromDispatchLoop => false; +#endif #if NATIVEAOT private const bool IsWorkerTrackingEnabledInConfig = false; diff --git a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs index b0100cb1d92e3e..d380e9d7533d71 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs @@ -581,6 +581,12 @@ internal static void ThrowFormatInvalidString() throw new FormatException(SR.Format_InvalidString); } + [DoesNotReturn] + internal static void ThrowFormatInvalidString(int offset, ExceptionResource resource) + { + throw new FormatException(SR.Format(SR.Format_InvalidStringWithOffsetAndReason, offset, GetResourceString(resource))); + } + [DoesNotReturn] internal static void ThrowFormatIndexOutOfRange() { @@ -1110,6 +1116,12 @@ private static string GetResourceString(ExceptionResource resource) return SR.InvalidOperation_TimeProviderNullLocalTimeZone; case ExceptionResource.InvalidOperation_TimeProviderInvalidTimestampFrequency: return SR.InvalidOperation_TimeProviderInvalidTimestampFrequency; + case ExceptionResource.Format_UnexpectedClosingBrace: + return SR.Format_UnexpectedClosingBrace; + case ExceptionResource.Format_UnclosedFormatItem: + return SR.Format_UnclosedFormatItem; + case ExceptionResource.Format_ExpectedAsciiDigit: + return SR.Format_ExpectedAsciiDigit; default: Debug.Fail("The enum value is not defined, please check the ExceptionResource Enum."); return ""; @@ -1303,5 +1315,8 @@ internal enum ExceptionResource InvalidOperation_SpanOverlappedOperation, InvalidOperation_TimeProviderNullLocalTimeZone, InvalidOperation_TimeProviderInvalidTimestampFrequency, + Format_UnexpectedClosingBrace, + Format_UnclosedFormatItem, + Format_ExpectedAsciiDigit, } } diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs index 3c8f5119b7d2ac..0cd7cb3ebf3437 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs @@ -127,6 +127,7 @@ public DateTimeKind GetCorrespondingKind(TimeZoneInfo? timeZone) public Dictionary? _systemTimeZones; public ReadOnlyCollection? _readOnlySystemTimeZones; + public Dictionary? _timeZonesUsingAlternativeIds; public bool _allSystemTimeZonesRead; } @@ -1898,6 +1899,9 @@ private static TimeZoneInfoResult TryGetTimeZone(string id, bool dstDisabled, ou } } + cachedData._timeZonesUsingAlternativeIds ??= new Dictionary(StringComparer.OrdinalIgnoreCase); + cachedData._timeZonesUsingAlternativeIds[id] = zone; + Debug.Assert(zone != null); value = zone; } @@ -1917,17 +1921,26 @@ private static TimeZoneInfoResult TryGetTimeZoneUsingId(string id, bool dstDisab // check the cache if (cachedData._systemTimeZones != null) { - if (cachedData._systemTimeZones.TryGetValue(id, out TimeZoneInfo? match)) + if (cachedData._systemTimeZones.TryGetValue(id, out value)) { - if (dstDisabled && match._supportsDaylightSavingTime) + if (dstDisabled && value._supportsDaylightSavingTime) { // we found a cache hit but we want a time zone without DST and this one has DST data - value = CreateCustomTimeZone(match._id, match._baseUtcOffset, match._displayName, match._standardDisplayName); + value = CreateCustomTimeZone(value._id, value._baseUtcOffset, value._displayName, value._standardDisplayName); } - else + + return result; + } + } + + if (cachedData._timeZonesUsingAlternativeIds != null) + { + if (cachedData._timeZonesUsingAlternativeIds.TryGetValue(id, out value)) + { + if (dstDisabled && value._supportsDaylightSavingTime) { - value = new TimeZoneInfo(match._id, match._baseUtcOffset, match._displayName, match._standardDisplayName, - match._daylightDisplayName, match._adjustmentRules, disableDaylightSavingTime: false, match.HasIanaId); + // we found a cache hit but we want a time zone without DST and this one has DST data + value = CreateCustomTimeZone(value._id, value._baseUtcOffset, value._displayName, value._standardDisplayName); } return result; @@ -1958,7 +1971,7 @@ private static TimeZoneInfoResult TryGetTimeZoneFromLocalMachine(string id, bool { TimeZoneInfoResult result; - result = TryGetTimeZoneFromLocalMachine(id, out TimeZoneInfo? match, out e); + result = TryGetTimeZoneFromLocalMachine(id, out value, out e); if (result == TimeZoneInfoResult.Success) { @@ -1971,24 +1984,15 @@ private static TimeZoneInfoResult TryGetTimeZoneFromLocalMachine(string id, bool // uses reference equality with the Utc object. if (!id.Equals(UtcId, StringComparison.OrdinalIgnoreCase)) { - cachedData._systemTimeZones.Add(id, match!); + cachedData._systemTimeZones.Add(id, value!); } - if (dstDisabled && match!._supportsDaylightSavingTime) + if (dstDisabled && value!._supportsDaylightSavingTime) { // we found a cache hit but we want a time zone without DST and this one has DST data - value = CreateCustomTimeZone(match._id, match._baseUtcOffset, match._displayName, match._standardDisplayName); - } - else - { - value = new TimeZoneInfo(match!._id, match._baseUtcOffset, match._displayName, match._standardDisplayName, - match._daylightDisplayName, match._adjustmentRules, disableDaylightSavingTime: false, match.HasIanaId); + value = CreateCustomTimeZone(value._id, value._baseUtcOffset, value._displayName, value._standardDisplayName); } } - else - { - value = null; - } return result; } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ValueHandle.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ValueHandle.cs index 98f7229c0759af..2b875e1f6b1601 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ValueHandle.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ValueHandle.cs @@ -730,9 +730,8 @@ public bool TryReadChars(char[] chars, int offset, int count, out int actual) try { // If we're asking for more than are possibly available, or more than are truly available then we can return the entire thing - if (charCount >= encoding.GetMaxCharCount(byteCount) || charCount >= encoding.GetCharCount(bytes, byteOffset, byteCount)) + if (encoding.TryGetChars(bytes.AsSpan(byteOffset, byteCount), chars.AsSpan(charOffset, charCount), out actualCharCount)) { - actualCharCount = encoding.GetChars(bytes, byteOffset, byteCount, chars, charOffset); actualByteCount = byteCount; } else diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlConverter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlConverter.cs index 59c5aebd4e39f7..55b9a1e8f24721 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlConverter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlConverter.cs @@ -31,8 +31,8 @@ internal static class XmlConverter public const int MaxPrimitiveChars = MaxDateTimeChars; // Matches IsWhitespace below - private static readonly IndexOfAnyValues s_whitespaceChars = IndexOfAnyValues.Create(" \t\r\n"); - private static readonly IndexOfAnyValues s_whitespaceBytes = IndexOfAnyValues.Create(" \t\r\n"u8); + private static readonly SearchValues s_whitespaceChars = SearchValues.Create(" \t\r\n"); + private static readonly SearchValues s_whitespaceBytes = SearchValues.Create(" \t\r\n"u8); public static bool ToBoolean(string value) { diff --git a/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs b/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs index 2cfe8bb79b3ca1..79fc70291d9f25 100644 --- a/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs @@ -17,7 +17,7 @@ internal static class DomainNameHelper // IDEOGRAPHIC FULL STOP '\u3002' // FULLWIDTH FULL STOP '\uFF0E' // HALFWIDTH IDEOGRAPHIC FULL STOP '\uFF61' - // Using IndexOfAnyValues isn't beneficial here as it would defer to IndexOfAny(char, char, char, char) anyway + // Using SearchValues isn't beneficial here as it would defer to IndexOfAny(char, char, char, char) anyway private const string IriDotCharacters = ".\u3002\uFF0E\uFF61"; // The Unicode specification allows certain code points to be normalized not to @@ -28,22 +28,22 @@ internal static class DomainNameHelper // This means that a host containing Unicode characters can be normalized to contain // URI reserved characters, changing the meaning of a URI only when certain properties // such as IdnHost are accessed. To be safe, disallow control characters in normalized hosts. - private static readonly IndexOfAnyValues s_unsafeForNormalizedHostChars = - IndexOfAnyValues.Create(@"\/?@#:[]"); + private static readonly SearchValues s_unsafeForNormalizedHostChars = + SearchValues.Create(@"\/?@#:[]"); // Takes into account the additional legal domain name characters '-' and '_' // Note that '_' char is formally invalid but is historically in use, especially on corpnets - private static readonly IndexOfAnyValues s_validChars = - IndexOfAnyValues.Create("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz."); + private static readonly SearchValues s_validChars = + SearchValues.Create("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz."); // For IRI, we're accepting anything non-ascii, so invert the condition to just check for invalid ascii characters - private static readonly IndexOfAnyValues s_iriInvalidAsciiChars = IndexOfAnyValues.Create( + private static readonly SearchValues s_iriInvalidAsciiChars = SearchValues.Create( "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F" + "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F" + " !\"#$%&'()*+,/:;<=>?@[\\]^`{|}~\u007F"); - private static readonly IndexOfAnyValues s_asciiLetterUpperOrColonChars = - IndexOfAnyValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZ:"); + private static readonly SearchValues s_asciiLetterUpperOrColonChars = + SearchValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZ:"); private static readonly IdnMapping s_idnMapping = new IdnMapping(); diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 2203e42b544566..b848cad5e8552a 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -1461,8 +1461,8 @@ public static bool IsHexEncoding(string pattern, int index) char.IsAsciiHexDigit(pattern[index + 2]); } - private static readonly IndexOfAnyValues s_schemeChars = - IndexOfAnyValues.Create("+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + private static readonly SearchValues s_schemeChars = + SearchValues.Create("+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); // CheckSchemeName // @@ -1783,8 +1783,8 @@ public Uri MakeRelativeUri(Uri uri) // // Returns true if a colon is found in the first path segment, false otherwise // - private static readonly IndexOfAnyValues s_segmentSeparatorChars = - IndexOfAnyValues.Create(@":\/?#"); + private static readonly SearchValues s_segmentSeparatorChars = + SearchValues.Create(@":\/?#"); private static bool CheckForColonInFirstPathSegment(string uriString) { diff --git a/src/libraries/System.Private.Uri/src/System/UriBuilder.cs b/src/libraries/System.Private.Uri/src/System/UriBuilder.cs index acf7cc30f81fe4..8ebf02784e4422 100644 --- a/src/libraries/System.Private.Uri/src/System/UriBuilder.cs +++ b/src/libraries/System.Private.Uri/src/System/UriBuilder.cs @@ -257,8 +257,8 @@ public Uri Uri // The following characters ("/" / "\" / "?" / "#" / "@") are from the gen-delims group. // We have to escape them to avoid corrupting the rest of the Uri string. // Other characters like spaces or non-ASCII will be escaped by Uri, we can ignore them here. - private static readonly IndexOfAnyValues s_userInfoReservedChars = - IndexOfAnyValues.Create(@"/\?#@"); + private static readonly SearchValues s_userInfoReservedChars = + SearchValues.Create(@"/\?#@"); private static string EncodeUserInfo(string input) { diff --git a/src/libraries/System.Private.Uri/src/System/UriHelper.cs b/src/libraries/System.Private.Uri/src/System/UriHelper.cs index bcd8c0dfde3329..1c8081b6dce60a 100644 --- a/src/libraries/System.Private.Uri/src/System/UriHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/UriHelper.cs @@ -107,7 +107,7 @@ internal static unsafe bool TestForSubPath(char* selfPtr, int selfLength, char* return true; } - internal static string EscapeString(string stringToEscape, bool checkExistingEscaped, IndexOfAnyValues noEscape) + internal static string EscapeString(string stringToEscape, bool checkExistingEscaped, SearchValues noEscape) { ArgumentNullException.ThrowIfNull(stringToEscape); @@ -130,7 +130,7 @@ internal static string EscapeString(string stringToEscape, bool checkExistingEsc } internal static unsafe void EscapeString(ReadOnlySpan stringToEscape, ref ValueStringBuilder dest, - bool checkExistingEscaped, IndexOfAnyValues noEscape) + bool checkExistingEscaped, SearchValues noEscape) { Debug.Assert(!noEscape.Contains('%'), "Need to treat % specially; it should be part of any escaped set"); @@ -150,7 +150,7 @@ internal static unsafe void EscapeString(ReadOnlySpan stringToEscape, ref private static void EscapeStringToBuilder( ReadOnlySpan stringToEscape, ref ValueStringBuilder vsb, - IndexOfAnyValues noEscape, bool checkExistingEscaped) + SearchValues noEscape, bool checkExistingEscaped) { Debug.Assert(!stringToEscape.IsEmpty && !noEscape.Contains(stringToEscape[0])); @@ -485,18 +485,18 @@ internal static bool IsNotSafeForUnescape(char ch) } // true for all ASCII letters and digits, as well as the RFC3986 unreserved marks '-', '_', '.', and '~' - public static readonly IndexOfAnyValues Unreserved = - IndexOfAnyValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"); + public static readonly SearchValues Unreserved = + SearchValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"); // true for all ASCII letters and digits, as well as the RFC3986 reserved characters, unreserved characters, and hash - public static readonly IndexOfAnyValues UnreservedReserved = - IndexOfAnyValues.Create("!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"); + public static readonly SearchValues UnreservedReserved = + SearchValues.Create("!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"); - public static readonly IndexOfAnyValues UnreservedReservedExceptHash = - IndexOfAnyValues.Create("!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"); + public static readonly SearchValues UnreservedReservedExceptHash = + SearchValues.Create("!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"); - public static readonly IndexOfAnyValues UnreservedReservedExceptQuestionMarkHash = - IndexOfAnyValues.Create("!$&'()*+,-./0123456789:;=@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"); + public static readonly SearchValues UnreservedReservedExceptQuestionMarkHash = + SearchValues.Create("!$&'()*+,-./0123456789:;=@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"); // // Is this a gen delim char from RFC 3986 diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs index 684e45ad5ffa1f..280e28a1fa246d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs @@ -16,9 +16,6 @@ namespace System.Xml { internal sealed partial class XmlSqlBinaryReader : XmlReader, IXmlNamespaceResolver { - internal static readonly Type TypeOfObject = typeof(object); - internal static readonly Type TypeOfString = typeof(string); - private static volatile Type?[] s_tokenTypeMap = null!; private static ReadOnlySpan XsdKatmaiTimeScaleToValueLengthMap => new byte[8] { // rely on C# compiler optimization to eliminate allocation @@ -350,7 +347,7 @@ public XmlSqlBinaryReader(Stream stream, byte[] data, int len, string baseUri, b AddInitNamespace(string.Empty, string.Empty); AddInitNamespace(_xml, _xnt.Add(XmlReservedNs.NsXml)); AddInitNamespace(_xmlns, _nsxmlns); - _valueType = TypeOfString; + _valueType = typeof(string); // init buffer position, etc _inStrm = stream; if (data != null) @@ -854,7 +851,7 @@ public override bool ReadAttributeValue() else { _token = BinXmlToken.Error; - _valueType = TypeOfString; + _valueType = typeof(string); _state = ScanState.AttrValPseudoValue; } _qnameOther.Clear(); @@ -2404,7 +2401,7 @@ private void PositionOnAttribute(int i) _token = BinXmlToken.Attr; _nodetype = XmlNodeType.Attribute; _state = ScanState.Attr; - _valueType = TypeOfObject; + _valueType = typeof(object); _stringValue = null; } @@ -2828,7 +2825,7 @@ private bool ReadDoc() ClearAttributes(); _attrCount = 0; - _valueType = TypeOfString; + _valueType = typeof(string); _stringValue = null; _hasTypedValue = false; @@ -2960,7 +2957,7 @@ private void ImplReadData(BinXmlToken tokenType) case BinXmlToken.SQL_NCHAR: case BinXmlToken.SQL_NVARCHAR: case BinXmlToken.SQL_NTEXT: - _valueType = TypeOfString; + _valueType = typeof(string); _hasTypedValue = false; break; default: @@ -3090,7 +3087,7 @@ private void ImplReadElement() } } _nodetype = XmlNodeType.Element; - _valueType = TypeOfObject; + _valueType = typeof(object); _posAfterAttrs = _pos; } @@ -3308,6 +3305,7 @@ private void CheckAllowContent() map[(int)BinXmlToken.SQL_UDT] = TypeOfByteArray; map[(int)BinXmlToken.XSD_BINHEX] = TypeOfByteArray; map[(int)BinXmlToken.XSD_BASE64] = TypeOfByteArray; + Type TypeOfString = typeof(string); map[(int)BinXmlToken.SQL_CHAR] = TypeOfString; map[(int)BinXmlToken.SQL_VARCHAR] = TypeOfString; map[(int)BinXmlToken.SQL_TEXT] = TypeOfString; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/DataTypeImplementation.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/DataTypeImplementation.cs index d2d01d4c5616e0..6453243fb64ffd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/DataTypeImplementation.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/DataTypeImplementation.cs @@ -1154,8 +1154,6 @@ static Array ToArray(ArrayList values, Type arrayType) //Union datatype internal sealed class Datatype_union : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(object); - private static readonly Type s_listValueType = typeof(object[]); private readonly XmlSchemaSimpleType[] _types; internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) @@ -1190,13 +1188,13 @@ internal override int Compare(object value1, object value2) return -1; } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(object); } } public override XmlTypeCode TypeCode { get { return XmlTypeCode.AnyAtomicType; } } internal override FacetsChecker FacetsChecker { get { return unionFacetsChecker; } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(object[]); } } internal override RestrictionFlags ValidRestrictionFlags { @@ -1351,9 +1349,6 @@ internal bool IsUnionBaseOf(DatatypeImplementation derivedType) // Primitive datatypes internal class Datatype_anySimpleType : DatatypeImplementation { - private static readonly Type s_atomicValueType = typeof(string); - private static readonly Type s_listValueType = typeof(string[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlUntypedConverter.Untyped; @@ -1361,11 +1356,11 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp internal override FacetsChecker FacetsChecker { get { return miscFacetsChecker; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(string); } } public override XmlTypeCode TypeCode { get { return XmlTypeCode.AnyAtomicType; } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(string[]); } } public override XmlTokenizedType TokenizedType { get { return XmlTokenizedType.None; } } @@ -1502,9 +1497,6 @@ internal override RestrictionFlags ValidRestrictionFlags */ internal sealed class Datatype_boolean : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(bool); - private static readonly Type s_listValueType = typeof(bool[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlBooleanConverter.Create(schemaType!); @@ -1514,9 +1506,9 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.Boolean; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(bool); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(bool[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -1582,9 +1574,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_float : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(float); - private static readonly Type s_listValueType = typeof(float[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlNumeric2Converter.Create(schemaType); @@ -1594,9 +1583,9 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.Float; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(float); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(float[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -1671,9 +1660,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_double : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(double); - private static readonly Type s_listValueType = typeof(double[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlNumeric2Converter.Create(schemaType); @@ -1683,9 +1669,9 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.Double; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(double); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(double[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -1762,8 +1748,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_decimal : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(decimal); - private static readonly Type s_listValueType = typeof(decimal[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(decimal.MinValue, decimal.MaxValue); internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) @@ -1775,9 +1759,9 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.Decimal; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(decimal); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(decimal[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -1855,9 +1839,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_duration : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(TimeSpan); - private static readonly Type s_listValueType = typeof(TimeSpan[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlMiscConverter.Create(schemaType); @@ -1867,9 +1848,9 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.Duration; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(TimeSpan); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(TimeSpan[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -2000,8 +1981,6 @@ internal sealed class Datatype_dayTimeDuration : Datatype_duration internal class Datatype_dateTimeBase : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(DateTime); - private static readonly Type s_listValueType = typeof(DateTime[]); private readonly XsdDateTimeFlags _dateTimeFlags; internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) @@ -2018,9 +1997,9 @@ internal Datatype_dateTimeBase(XsdDateTimeFlags dateTimeFlags) _dateTimeFlags = dateTimeFlags; } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(DateTime); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(DateTime[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -2399,9 +2378,6 @@ internal Datatype_month() : base(XsdDateTimeFlags.GMonth) { } */ internal sealed class Datatype_hexBinary : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(byte[]); - private static readonly Type s_listValueType = typeof(byte[][]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlMiscConverter.Create(schemaType); @@ -2411,9 +2387,9 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.HexBinary; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(byte[]); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(byte[][]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -2500,9 +2476,6 @@ internal override int Compare(object value1, object value2) */ internal sealed class Datatype_base64Binary : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(byte[]); - private static readonly Type s_listValueType = typeof(byte[][]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlMiscConverter.Create(schemaType); @@ -2512,9 +2485,9 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.Base64Binary; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(byte[]); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(byte[][]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -2600,9 +2573,6 @@ internal override int Compare(object value1, object value2) */ internal sealed class Datatype_anyURI : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(Uri); - private static readonly Type s_listValueType = typeof(Uri[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlMiscConverter.Create(schemaType); @@ -2612,7 +2582,7 @@ internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaTyp public override XmlTypeCode TypeCode { get { return XmlTypeCode.AnyUri; } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(Uri); } } internal override bool HasValueFacets { @@ -2621,7 +2591,7 @@ internal override bool HasValueFacets return true; //Built-in facet to check validity of Uri } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(Uri[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -2698,9 +2668,6 @@ internal override int Compare(object value1, object value2) */ internal sealed class Datatype_QName : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(XmlQualifiedName); - private static readonly Type s_listValueType = typeof(XmlQualifiedName[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlMiscConverter.Create(schemaType); @@ -2725,9 +2692,9 @@ internal override RestrictionFlags ValidRestrictionFlags } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(XmlQualifiedName); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(XmlQualifiedName[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -3034,9 +3001,6 @@ facet whose value is the name of a NOTATION declared in the */ internal sealed class Datatype_NOTATION : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(XmlQualifiedName); - private static readonly Type s_listValueType = typeof(XmlQualifiedName[]); - internal override XmlValueConverter CreateValueConverter(XmlSchemaType schemaType) { return XmlMiscConverter.Create(schemaType); @@ -3061,9 +3025,9 @@ internal override RestrictionFlags ValidRestrictionFlags } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(XmlQualifiedName); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(XmlQualifiedName[]); } } internal override XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get { return XmlSchemaWhiteSpace.Collapse; } } @@ -3240,8 +3204,6 @@ internal sealed class Datatype_negativeInteger : Datatype_nonPositiveInteger */ internal class Datatype_long : Datatype_integer { - private static readonly Type s_atomicValueType = typeof(long); - private static readonly Type s_listValueType = typeof(long[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(long.MinValue, long.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3261,9 +3223,9 @@ internal override int Compare(object value1, object value2) return ((long)value1).CompareTo((long)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(long); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(long[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3304,8 +3266,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_int : Datatype_long { - private static readonly Type s_atomicValueType = typeof(int); - private static readonly Type s_listValueType = typeof(int[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(int.MinValue, int.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3317,9 +3277,9 @@ internal override int Compare(object value1, object value2) return ((int)value1).CompareTo((int)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(int); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(int[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3361,8 +3321,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_short : Datatype_int { - private static readonly Type s_atomicValueType = typeof(short); - private static readonly Type s_listValueType = typeof(short[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(short.MinValue, short.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3374,9 +3332,9 @@ internal override int Compare(object value1, object value2) return ((short)value1).CompareTo((short)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(short); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(short[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3417,8 +3375,6 @@ internal override int Compare(object value1, object value2) */ internal sealed class Datatype_byte : Datatype_short { - private static readonly Type s_atomicValueType = typeof(sbyte); - private static readonly Type s_listValueType = typeof(sbyte[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(sbyte.MinValue, sbyte.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3430,9 +3386,9 @@ internal override int Compare(object value1, object value2) return ((sbyte)value1).CompareTo((sbyte)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(sbyte); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(sbyte[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3505,8 +3461,6 @@ internal override bool HasValueFacets */ internal class Datatype_unsignedLong : Datatype_nonNegativeInteger { - private static readonly Type s_atomicValueType = typeof(ulong); - private static readonly Type s_listValueType = typeof(ulong[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(ulong.MinValue, ulong.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3518,9 +3472,9 @@ internal override int Compare(object value1, object value2) return ((ulong)value1).CompareTo((ulong)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(ulong); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(ulong[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3561,8 +3515,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_unsignedInt : Datatype_unsignedLong { - private static readonly Type s_atomicValueType = typeof(uint); - private static readonly Type s_listValueType = typeof(uint[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(uint.MinValue, uint.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3574,9 +3526,9 @@ internal override int Compare(object value1, object value2) return ((uint)value1).CompareTo((uint)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(uint); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(uint[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3617,8 +3569,6 @@ internal override int Compare(object value1, object value2) */ internal class Datatype_unsignedShort : Datatype_unsignedInt { - private static readonly Type s_atomicValueType = typeof(ushort); - private static readonly Type s_listValueType = typeof(ushort[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(ushort.MinValue, ushort.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3630,9 +3580,9 @@ internal override int Compare(object value1, object value2) return ((ushort)value1).CompareTo((ushort)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(ushort); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(ushort[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3672,8 +3622,6 @@ internal override int Compare(object value1, object value2) */ internal sealed class Datatype_unsignedByte : Datatype_unsignedShort { - private static readonly Type s_atomicValueType = typeof(byte); - private static readonly Type s_listValueType = typeof(byte[]); private static readonly Numeric10FacetsChecker s_numeric10FacetsChecker = new Numeric10FacetsChecker(byte.MinValue, byte.MaxValue); internal override FacetsChecker FacetsChecker { get { return s_numeric10FacetsChecker; } } @@ -3685,9 +3633,9 @@ internal override int Compare(object value1, object value2) return ((byte)value1).CompareTo((byte)value2); } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(byte); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(byte[]); } } internal override Exception? TryParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr, out object? typedValue) { @@ -3783,9 +3731,6 @@ public override object ParseValue(string s, XmlNameTable? nameTable, IXmlNamespa internal sealed class Datatype_QNameXdr : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(XmlQualifiedName); - private static readonly Type s_listValueType = typeof(XmlQualifiedName[]); - public override XmlTokenizedType TokenizedType { get { return XmlTokenizedType.QName; } } public override object ParseValue(string s, XmlNameTable? nameTable, IXmlNamespaceResolver? nsmgr) @@ -3811,9 +3756,9 @@ public override object ParseValue(string s, XmlNameTable? nameTable, IXmlNamespa } } - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(XmlQualifiedName); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(XmlQualifiedName[]); } } } internal sealed class Datatype_ENUMERATION : Datatype_NMTOKEN @@ -3823,12 +3768,9 @@ internal sealed class Datatype_ENUMERATION : Datatype_NMTOKEN internal sealed class Datatype_char : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(char); - private static readonly Type s_listValueType = typeof(char[]); - - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(char); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(char[]); } } internal override RestrictionFlags ValidRestrictionFlags { get { return 0; } } //XDR only @@ -3923,12 +3865,9 @@ public override object ParseValue(string s, XmlNameTable? nameTable, IXmlNamespa internal sealed class Datatype_uuid : Datatype_anySimpleType { - private static readonly Type s_atomicValueType = typeof(Guid); - private static readonly Type s_listValueType = typeof(Guid[]); - - public override Type ValueType { get { return s_atomicValueType; } } + public override Type ValueType { get { return typeof(Guid); } } - internal override Type ListValueType { get { return s_listValueType; } } + internal override Type ListValueType { get { return typeof(Guid[]); } } internal override RestrictionFlags ValidRestrictionFlags { get { return 0; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs index 5131a7d50bd923..f6f5b5448904c7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs @@ -398,15 +398,13 @@ internal int LookupNamespaces(XPathNode[] pageElem, int idxElem, out XPathNode[] Debug.Assert(pageElem[idxElem].NodeType == XPathNodeType.Element); // Check whether this element has any local namespaces - if (_mapNmsp == null || !_mapNmsp.ContainsKey(nodeRef)) + if (_mapNmsp == null || !_mapNmsp.TryGetValue(nodeRef, out nodeRef)) { pageNmsp = null; return 0; } // Yes, so return the page and index of the first local namespace node - nodeRef = _mapNmsp[nodeRef]; - pageNmsp = nodeRef.Page; return nodeRef.Index; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs index 72547a9065a1f1..3039572cc9e64d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs @@ -57,9 +57,9 @@ static XmlCharType() private const string AsciiCharDataChars = "\t\n\r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; private const string WhiteSpaceChars = "\t\n\r "; - private static readonly IndexOfAnyValues s_publicIdChars = IndexOfAnyValues.Create(PublicIdChars); - private static readonly IndexOfAnyValues s_asciiCharDataChars = IndexOfAnyValues.Create(AsciiCharDataChars); - private static readonly IndexOfAnyValues s_whitespaceChars = IndexOfAnyValues.Create(WhiteSpaceChars); + private static readonly SearchValues s_publicIdChars = SearchValues.Create(PublicIdChars); + private static readonly SearchValues s_asciiCharDataChars = SearchValues.Create(AsciiCharDataChars); + private static readonly SearchValues s_whitespaceChars = SearchValues.Create(WhiteSpaceChars); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsWhiteSpace(char ch) => (GetCharProperties(ch) & Whitespace) != 0u; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs index fe968530108235..b69fa67cc23f56 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs @@ -5407,7 +5407,7 @@ private QilNode FoldXsltConvert(QilNode ndLiteral, XmlQueryType typTarget) else if (typTarget == XmlQueryTypeFactory.IntegerX) return this.f.LiteralInt64(value.ValueAsLong); else if (typTarget == XmlQueryTypeFactory.DecimalX) - return this.f.LiteralDecimal((decimal)value.ValueAs(XsltConvert.DecimalType)); + return this.f.LiteralDecimal((decimal)value.ValueAs(typeof(decimal))); else if (typTarget == XmlQueryTypeFactory.DoubleX) return this.f.LiteralDouble(value.ValueAsDouble); else if (typTarget == XmlQueryTypeFactory.BooleanX) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs index f1a423d8df238b..80c3fa5c2d32a7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs @@ -312,7 +312,7 @@ public IList InvokeXsltLateBoundFunction(string name, string namespac objRet = extFunc.Invoke(instance, objActualArgs); // 2. Convert to IList - if (objRet == null && extFunc.ClrReturnType == XsltConvert.VoidType) + if (objRet == null && extFunc.ClrReturnType == typeof(void)) return XmlQueryNodeSequence.Empty; return (IList)_runtime.ChangeTypeXsltResult(XmlQueryTypeFactory.ItemS, objRet); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs index ce0adbb961fd08..3ae6b73cb4d410 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs @@ -480,18 +480,18 @@ internal static object ChangeTypeXsltArgument(XmlQueryType xmlType, object value Debug.Assert(XmlILTypeHelper.GetStorageType(xmlType).IsAssignableFrom(value.GetType()), "Values passed to ChangeTypeXsltArgument should be in ILGen's default Clr representation."); - Debug.Assert(destinationType == XsltConvert.ObjectType || !destinationType.IsAssignableFrom(value.GetType()), + Debug.Assert(destinationType == typeof(object) || !destinationType.IsAssignableFrom(value.GetType()), $"No need to call ChangeTypeXsltArgument since value is already assignable to destinationType {destinationType}"); switch (xmlType.TypeCode) { case XmlTypeCode.String: - if (destinationType == XsltConvert.DateTimeType) + if (destinationType == typeof(DateTime)) value = XsltConvert.ToDateTime((string)value); break; case XmlTypeCode.Double: - if (destinationType != XsltConvert.DoubleType) + if (destinationType != typeof(double)) value = Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture); break; @@ -499,11 +499,11 @@ internal static object ChangeTypeXsltArgument(XmlQueryType xmlType, object value Debug.Assert(xmlType != XmlQueryTypeFactory.Node && xmlType != XmlQueryTypeFactory.NodeS, "Rtf values should have been eliminated by caller."); - if (destinationType == XsltConvert.XPathNodeIteratorType) + if (destinationType == typeof(XPathNodeIterator)) { value = new XPathArrayIterator((IList)value); } - else if (destinationType == XsltConvert.XPathNavigatorArrayType) + else if (destinationType == typeof(XPathNavigator[])) { // Copy sequence to XPathNavigator[] IList seq = (IList)value; @@ -519,7 +519,7 @@ internal static object ChangeTypeXsltArgument(XmlQueryType xmlType, object value case XmlTypeCode.Item: { // Only typeof(object) is supported as a destination type - if (destinationType != XsltConvert.ObjectType) + if (destinationType != typeof(object)) throw new XslTransformException(SR.Xslt_UnsupportedClrType, destinationType.Name); // Convert to default, backwards-compatible representation @@ -579,12 +579,12 @@ internal object ChangeTypeXsltResult(XmlQueryType xmlType, object? value) switch (xmlType.TypeCode) { case XmlTypeCode.String: - if (value.GetType() == XsltConvert.DateTimeType) + if (value.GetType() == typeof(DateTime)) value = XsltConvert.ToString((DateTime)value); break; case XmlTypeCode.Double: - if (value.GetType() != XsltConvert.DoubleType) + if (value.GetType() != typeof(double)) value = ((IConvertible)value).ToDouble(null); break; @@ -641,7 +641,7 @@ internal object ChangeTypeXsltResult(XmlQueryType xmlType, object? value) break; case XmlTypeCode.String: - if (sourceType == XsltConvert.DateTimeType) + if (sourceType == typeof(DateTime)) value = new XmlQueryItemSequence(new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), XsltConvert.ToString((DateTime)value))); else value = new XmlQueryItemSequence(new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), value)); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltConvert.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltConvert.cs index 6db938c5cb2184..79b9128f560f5d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltConvert.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltConvert.cs @@ -1,15 +1,11 @@ // 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; using System.Collections.Generic; -using System.Xml.XPath; -using System.Xml.Xsl; -using System.Xml.Schema; -using System.Diagnostics; using System.ComponentModel; -using System.Reflection; +using System.Diagnostics; +using System.Xml.Schema; +using System.Xml.XPath; namespace System.Xml.Xsl.Runtime { @@ -25,37 +21,6 @@ namespace System.Xml.Xsl.Runtime [EditorBrowsable(EditorBrowsableState.Never)] public static class XsltConvert { - internal static readonly Type BooleanType = typeof(bool); - internal static readonly Type ByteArrayType = typeof(byte[]); - internal static readonly Type ByteType = typeof(byte); - internal static readonly Type DateTimeType = typeof(DateTime); - internal static readonly Type DecimalType = typeof(decimal); - internal static readonly Type DoubleType = typeof(double); - internal static readonly Type ICollectionType = typeof(ICollection); - internal static readonly Type IEnumerableType = typeof(IEnumerable); - internal static readonly Type IListType = typeof(IList); - internal static readonly Type Int16Type = typeof(short); - internal static readonly Type Int32Type = typeof(int); - internal static readonly Type Int64Type = typeof(long); - internal static readonly Type IXPathNavigableType = typeof(IXPathNavigable); - internal static readonly Type ObjectType = typeof(object); - internal static readonly Type SByteType = typeof(sbyte); - internal static readonly Type SingleType = typeof(float); - internal static readonly Type StringType = typeof(string); - internal static readonly Type TimeSpanType = typeof(TimeSpan); - internal static readonly Type UInt16Type = typeof(ushort); - internal static readonly Type UInt32Type = typeof(uint); - internal static readonly Type UInt64Type = typeof(ulong); - internal static readonly Type UriType = typeof(Uri); - internal static readonly Type VoidType = typeof(void); - internal static readonly Type XmlAtomicValueType = typeof(XmlAtomicValue); - internal static readonly Type XmlQualifiedNameType = typeof(XmlQualifiedName); - internal static readonly Type XPathItemType = typeof(XPathItem); - internal static readonly Type XPathNavigatorArrayType = typeof(XPathNavigator[]); - internal static readonly Type XPathNavigatorType = typeof(XPathNavigator); - internal static readonly Type XPathNodeIteratorType = typeof(XPathNodeIterator); - - //------------------------------------------------------------------------ // ToBoolean (internal type to internal type) //------------------------------------------------------------------------ @@ -69,11 +34,11 @@ public static bool ToBoolean(XPathItem item) Type itemType = item.ValueType; - if (itemType == StringType) + if (itemType == typeof(string)) { return item.Value.Length != 0; } - else if (itemType == DoubleType) + else if (itemType == typeof(double)) { // (x < 0 || 0 < x) == (x != 0) && !Double.IsNaN(x) double dbl = item.ValueAsDouble; @@ -81,7 +46,7 @@ public static bool ToBoolean(XPathItem item) } else { - Debug.Assert(itemType == BooleanType, $"Unexpected type of atomic sequence {itemType}"); + Debug.Assert(itemType == typeof(bool), $"Unexpected type of atomic sequence {itemType}"); return item.ValueAsBoolean; } } @@ -115,17 +80,17 @@ public static double ToDouble(XPathItem item) Type itemType = item.ValueType; - if (itemType == StringType) + if (itemType == typeof(string)) { return XPathConvert.StringToDouble(item.Value); } - else if (itemType == DoubleType) + else if (itemType == typeof(double)) { return item.ValueAsDouble; } else { - Debug.Assert(itemType == BooleanType, $"Unexpected type of atomic sequence {itemType}"); + Debug.Assert(itemType == typeof(bool), $"Unexpected type of atomic sequence {itemType}"); return item.ValueAsBoolean ? 1d : 0d; } } @@ -211,7 +176,7 @@ public static string ToString(XPathItem item) XsltLibrary.CheckXsltValue(item); // Use XPath 1.0 rules to convert double to string - if (!item.IsNode && item.ValueType == DoubleType) + if (!item.IsNode && item.ValueType == typeof(double)) return XPathConvert.DoubleToString(item.ValueAsDouble); return item.Value; @@ -318,7 +283,7 @@ internal static XmlAtomicValue ConvertToType(XmlAtomicValue value, XmlQueryType return new XmlAtomicValue(destinationType.SchemaType, ToDouble(value)); case XmlTypeCode.Decimal: - return new XmlAtomicValue(destinationType.SchemaType, ToDouble((decimal)value.ValueAs(DecimalType, null))); + return new XmlAtomicValue(destinationType.SchemaType, ToDouble((decimal)value.ValueAs(typeof(decimal), null))); case XmlTypeCode.Int: case XmlTypeCode.Long: @@ -382,26 +347,26 @@ public static IList EnsureNodeSet(IList listItems) /// internal static XmlQueryType InferXsltType(Type clrType) { - if (clrType == BooleanType) return XmlQueryTypeFactory.BooleanX; - if (clrType == ByteType) return XmlQueryTypeFactory.DoubleX; - if (clrType == DecimalType) return XmlQueryTypeFactory.DoubleX; - if (clrType == DateTimeType) return XmlQueryTypeFactory.StringX; - if (clrType == DoubleType) return XmlQueryTypeFactory.DoubleX; - if (clrType == Int16Type) return XmlQueryTypeFactory.DoubleX; - if (clrType == Int32Type) return XmlQueryTypeFactory.DoubleX; - if (clrType == Int64Type) return XmlQueryTypeFactory.DoubleX; - if (clrType == IXPathNavigableType) return XmlQueryTypeFactory.NodeNotRtf; - if (clrType == SByteType) return XmlQueryTypeFactory.DoubleX; - if (clrType == SingleType) return XmlQueryTypeFactory.DoubleX; - if (clrType == StringType) return XmlQueryTypeFactory.StringX; - if (clrType == UInt16Type) return XmlQueryTypeFactory.DoubleX; - if (clrType == UInt32Type) return XmlQueryTypeFactory.DoubleX; - if (clrType == UInt64Type) return XmlQueryTypeFactory.DoubleX; - if (clrType == XPathNavigatorArrayType) return XmlQueryTypeFactory.NodeSDod; - if (clrType == XPathNavigatorType) return XmlQueryTypeFactory.NodeNotRtf; - if (clrType == XPathNodeIteratorType) return XmlQueryTypeFactory.NodeSDod; + if (clrType == typeof(bool)) return XmlQueryTypeFactory.BooleanX; + if (clrType == typeof(byte)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(decimal)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(DateTime)) return XmlQueryTypeFactory.StringX; + if (clrType == typeof(double)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(short)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(int)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(long)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(IXPathNavigable)) return XmlQueryTypeFactory.NodeNotRtf; + if (clrType == typeof(sbyte)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(float)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(string)) return XmlQueryTypeFactory.StringX; + if (clrType == typeof(ushort)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(uint)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(ulong)) return XmlQueryTypeFactory.DoubleX; + if (clrType == typeof(XPathNavigator[])) return XmlQueryTypeFactory.NodeSDod; + if (clrType == typeof(XPathNavigator)) return XmlQueryTypeFactory.NodeNotRtf; + if (clrType == typeof(XPathNodeIterator)) return XmlQueryTypeFactory.NodeSDod; if (clrType.IsEnum) return XmlQueryTypeFactory.DoubleX; - if (clrType == VoidType) return XmlQueryTypeFactory.Empty; + if (clrType == typeof(void)) return XmlQueryTypeFactory.Empty; return XmlQueryTypeFactory.ItemS; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs index 9fc471b376cc0d..81b9af43568fb8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs @@ -327,17 +327,17 @@ public static double MSNumber(IList value) else { Type itemType = item.ValueType; - if (itemType == XsltConvert.StringType) + if (itemType == typeof(string)) { stringValue = item.Value; } - else if (itemType == XsltConvert.DoubleType) + else if (itemType == typeof(double)) { return item.ValueAsDouble; } else { - Debug.Assert(itemType == XsltConvert.BooleanType, $"Unexpected type of atomic value {itemType}"); + Debug.Assert(itemType == typeof(bool), $"Unexpected type of atomic value {itemType}"); return item.ValueAsBoolean ? 1d : 0d; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltLibrary.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltLibrary.cs index f528102390edb3..acedb054118c47 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltLibrary.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltLibrary.cs @@ -336,17 +336,17 @@ private static TypeCode GetTypeCode(XPathItem item) // Faster implementation of Type.GetTypeCode(item.ValueType); Debug.Assert(!item.IsNode, "Atomic value expected"); Type itemType = item.ValueType; - if (itemType == XsltConvert.StringType) + if (itemType == typeof(string)) { return TypeCode.String; } - else if (itemType == XsltConvert.DoubleType) + else if (itemType == typeof(double)) { return TypeCode.Double; } else { - Debug.Assert(itemType == XsltConvert.BooleanType, $"Unexpected type of atomic value {itemType}"); + Debug.Assert(itemType == typeof(bool), $"Unexpected type of atomic value {itemType}"); return TypeCode.Boolean; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs index 5694e9f107427c..30e32b4fe6169c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs @@ -658,13 +658,13 @@ private QilNode CompileSystemProperty(QilNode name) if (EvaluateFuncCalls) { XPathItem propValue = XsltFunctions.SystemProperty(qname); - if (propValue.ValueType == XsltConvert.StringType) + if (propValue.ValueType == typeof(string)) { return _f.String(propValue.Value); } else { - Debug.Assert(propValue.ValueType == XsltConvert.DoubleType); + Debug.Assert(propValue.ValueType == typeof(double)); return _f.Double((double)propValue.ValueAsDouble); } } diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs b/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs index fbcc94202c48b8..1a200d8a56f71e 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs +++ b/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs @@ -72,9 +72,9 @@ internal LocalBuilder() { } public override int LocalIndex { get { throw null; } } public override System.Type LocalType { get { throw null; } } } - public partial class ParameterBuilder + public abstract partial class ParameterBuilder { - internal ParameterBuilder() { } + protected ParameterBuilder() { } public virtual int Attributes { get { throw null; } } public bool IsIn { get { throw null; } } public bool IsOptional { get { throw null; } } @@ -84,6 +84,7 @@ internal ParameterBuilder() { } public virtual void SetConstant(object? defaultValue) { } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); } public sealed partial class SignatureHelper { diff --git a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln index d71e15aa37b804..b4fa6af73eaece 100644 --- a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln +++ b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln @@ -43,8 +43,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Metadata" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime", "..\System.Runtime\src\System.Runtime.csproj", "{BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CodeDom", "..\System.CodeDom\src\System.CodeDom.csproj", "{D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.MetadataLoadContext", "..\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj", "{9F3970FF-F138-4F23-A2F8-2387858E723D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections.Immutable", "..\System.Collections.Immutable\src\System.Collections.Immutable.csproj", "{C2FF5BC7-825E-437E-92C3-F505EB6D1D40}" @@ -53,8 +51,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections.Immutabl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.MetadataLoadContext", "..\System.Reflection.MetadataLoadContext\ref\System.Reflection.MetadataLoadContext.csproj", "{B2FAA0B4-2976-4742-B186-9C4928BCF9AF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CodeDom", "..\System.CodeDom\ref\System.CodeDom.csproj", "{501C1EA6-F7DB-4D3E-A212-F06689A831CD}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Metadata", "..\System.Reflection.Metadata\ref\System.Reflection.Metadata.csproj", "{E468274C-8F7E-49FC-BC2A-82C8B9E5B026}" EndProject Global @@ -319,24 +315,6 @@ Global {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}.Release|x64.Build.0 = Release|Any CPU {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}.Release|x86.ActiveCfg = Release|Any CPU {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}.Release|x86.Build.0 = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|Any CPU.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x64.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x64.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x86.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x86.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x64.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x64.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x86.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x86.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|Any CPU.Build.0 = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x64.ActiveCfg = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x64.Build.0 = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x86.ActiveCfg = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x86.Build.0 = Release|Any CPU {9F3970FF-F138-4F23-A2F8-2387858E723D}.Checked|Any CPU.ActiveCfg = Debug|Any CPU {9F3970FF-F138-4F23-A2F8-2387858E723D}.Checked|Any CPU.Build.0 = Debug|Any CPU {9F3970FF-F138-4F23-A2F8-2387858E723D}.Checked|x64.ActiveCfg = Debug|Any CPU @@ -409,24 +387,6 @@ Global {B2FAA0B4-2976-4742-B186-9C4928BCF9AF}.Release|x64.Build.0 = Release|Any CPU {B2FAA0B4-2976-4742-B186-9C4928BCF9AF}.Release|x86.ActiveCfg = Release|Any CPU {B2FAA0B4-2976-4742-B186-9C4928BCF9AF}.Release|x86.Build.0 = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|Any CPU.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x64.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x64.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x86.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x86.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x64.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x64.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x86.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x86.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|Any CPU.Build.0 = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x64.ActiveCfg = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x64.Build.0 = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x86.ActiveCfg = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x86.Build.0 = Release|Any CPU {E468274C-8F7E-49FC-BC2A-82C8B9E5B026}.Checked|Any CPU.ActiveCfg = Debug|Any CPU {E468274C-8F7E-49FC-BC2A-82C8B9E5B026}.Checked|Any CPU.Build.0 = Debug|Any CPU {E468274C-8F7E-49FC-BC2A-82C8B9E5B026}.Checked|x64.ActiveCfg = Debug|Any CPU @@ -466,12 +426,10 @@ Global {613C42F2-847A-42B3-9F5E-F5A670356BF7} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} {F33093A8-FF33-4F95-B256-F2AB712C956A} = {74F4AB97-3DBC-48FB-A2EA-2B4141749800} {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A} = {74F4AB97-3DBC-48FB-A2EA-2B4141749800} - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E} = {2FC35C2F-76DB-4D84-B421-9700BEA4D161} {9F3970FF-F138-4F23-A2F8-2387858E723D} = {2FC35C2F-76DB-4D84-B421-9700BEA4D161} {C2FF5BC7-825E-437E-92C3-F505EB6D1D40} = {74F4AB97-3DBC-48FB-A2EA-2B4141749800} {DE04D45B-7E15-409D-A176-985D814A6AEB} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} {B2FAA0B4-2976-4742-B186-9C4928BCF9AF} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} - {501C1EA6-F7DB-4D3E-A212-F06689A831CD} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} {E468274C-8F7E-49FC-BC2A-82C8B9E5B026} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs index 14b8c7b36d9c17..f3cd61d33e8964 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -55,9 +55,8 @@ protected AssemblyBuilder() { } public override System.Type? GetType(string name, bool throwOnError, bool ignoreCase) { throw null; } public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); } [System.FlagsAttribute] public enum AssemblyBuilderAccess @@ -91,9 +90,8 @@ protected ConstructorBuilder() { } public override object Invoke(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object?[]? parameters, System.Globalization.CultureInfo? culture) { throw null; } public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { } protected abstract void SetImplementationFlagsCore(System.Reflection.MethodImplAttributes attributes); public override string ToString() { throw null; } @@ -186,9 +184,8 @@ protected EnumBuilder() { } public override System.Type MakeByRefType() { throw null; } public override System.Type MakePointerType() { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); } public abstract partial class EventBuilder { @@ -198,9 +195,8 @@ public void AddOtherMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { } public void SetAddOnMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { } protected abstract void SetAddOnMethodCore(System.Reflection.Emit.MethodBuilder mdBuilder); public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); public void SetRaiseMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { } protected abstract void SetRaiseMethodCore(System.Reflection.Emit.MethodBuilder mdBuilder); public void SetRemoveOnMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { } @@ -224,9 +220,8 @@ protected FieldBuilder() { } public void SetConstant(object? defaultValue) { } protected abstract void SetConstantCore(object? defaultValue); public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); public void SetOffset(int iOffset) { } protected abstract void SetOffsetCore(int iOffset); public override void SetValue(object? obj, object? val, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, System.Globalization.CultureInfo? culture) { } @@ -327,9 +322,8 @@ protected GenericTypeParameterBuilder() { } public void SetBaseTypeConstraint([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type? baseTypeConstraint) { } protected abstract void SetBaseTypeConstraintCore([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] Type? baseTypeConstraint); public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); public void SetGenericParameterAttributes(System.Reflection.GenericParameterAttributes genericParameterAttributes) { } protected abstract void SetGenericParameterAttributesCore(System.Reflection.GenericParameterAttributes genericParameterAttributes); public void SetInterfaceConstraints(params System.Type[]? interfaceConstraints) { } @@ -380,9 +374,8 @@ protected MethodBuilder() { } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public override System.Reflection.MethodInfo MakeGenericMethod(params System.Type[] typeArguments) { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { } protected abstract void SetImplementationFlagsCore(System.Reflection.MethodImplAttributes attributes); public void SetParameters(params System.Type[] parameterTypes) { } @@ -474,9 +467,8 @@ public void CreateGlobalFunctions() { } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Trimming changes metadata tokens")] public override System.Type ResolveType(int metadataToken, System.Type[]? genericTypeArguments, System.Type[]? genericMethodArguments) { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); } public abstract partial class PropertyBuilder : System.Reflection.PropertyInfo { @@ -503,9 +495,8 @@ public void AddOtherMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { } public void SetConstant(object? defaultValue) { } protected abstract void SetConstantCore(object? defaultValue); public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); public void SetGetMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { } protected abstract void SetGetMethodCore(System.Reflection.Emit.MethodBuilder mdBuilder); public void SetSetMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { } @@ -671,9 +662,8 @@ public void DefineMethodOverride(System.Reflection.MethodInfo methodInfoBody, Sy public override System.Type MakeGenericType(params System.Type[] typeArguments) { throw null; } public override System.Type MakePointerType() { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } - protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, byte[] binaryAttribute); public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } - protected abstract void SetCustomAttributeCore(System.Reflection.Emit.CustomAttributeBuilder customBuilder); + protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute); public void SetParent([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type? parent) { } protected abstract void SetParentCore([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type? parent); public override string ToString() { throw null; } diff --git a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx index b3ad859f052538..02f0c2865c2e8f 100644 --- a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx +++ b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx @@ -126,9 +126,6 @@ Interface must be declared abstract. - - The signature {0} is not supported. - Assembly needs at least one module defined. @@ -141,7 +138,37 @@ The invoked member is not supported in a dynamic module. - - Invalid name. + + The type code may not be used as a type argument of a custom attribute . + + + 'UnmanagedType.{0}' named parameter is only valid for fields. + + + Custom attribute '{0}' data length is only '{1}'. + + + Custom attribute '{0}' prolog invalid. + + + Custom attribute '{0}' has unknown named type '{1}'. + + + Type '{0}' not handled in the custom attribute value decoder. + + + DllName cannot be empty. + + + The specified parameter index is not in range. + + + Invalid constructor argument {0} provided for MarshalAs atttribute. + + + Named parameter {0} is not valid for UnmanagedType.{1} type. + + + SizeConst parameter must be specified for UnmanagedType.ByValTStr type. \ No newline at end of file diff --git a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj index 7da2c955d52e60..2e7f66ddc2a37c 100644 --- a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj +++ b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj @@ -5,11 +5,13 @@ true - + + + diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs index ea7ec68d9d7e1d..238be3976a40d0 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs @@ -11,10 +11,13 @@ namespace System.Reflection.Emit { internal sealed class AssemblyBuilderImpl : AssemblyBuilder { - private bool _previouslySaved; private readonly AssemblyName _assemblyName; private readonly Assembly _coreAssembly; + private readonly MetadataBuilder _metadataBuilder; private ModuleBuilderImpl? _module; + private bool _previouslySaved; + + internal List? _customAttributes; internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerable? assemblyAttributes) { @@ -29,6 +32,7 @@ internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerab _assemblyName = name; _coreAssembly = coreAssembly; + _metadataBuilder = new MetadataBuilder(); if (assemblyAttributes != null) { @@ -42,7 +46,7 @@ internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerab internal static AssemblyBuilderImpl DefinePersistedAssembly(AssemblyName name, Assembly coreAssembly, IEnumerable? assemblyAttributes) => new AssemblyBuilderImpl(name, coreAssembly, assemblyAttributes); - private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder) + private void WritePEImage(Stream peStream, BlobBuilder ilBuilder) { // Create executable with the managed metadata from the specified MetadataBuilder. var peHeaderBuilder = new PEHeaderBuilder( @@ -51,7 +55,7 @@ private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilde var peBuilder = new ManagedPEBuilder( peHeaderBuilder, - new MetadataRootBuilder(metadataBuilder), + new MetadataRootBuilder(_metadataBuilder), ilBuilder); // Write executable into the specified stream. @@ -75,24 +79,23 @@ internal void Save(Stream stream) } // Add assembly metadata - var metadata = new MetadataBuilder(); - - metadata.AddAssembly( - metadata.GetOrAddString(value: _assemblyName.Name!), + AssemblyDefinitionHandle assemblyHandle = _metadataBuilder.AddAssembly( + _metadataBuilder.GetOrAddString(value: _assemblyName.Name!), version: _assemblyName.Version ?? new Version(0, 0, 0, 0), - culture: _assemblyName.CultureName == null ? default : metadata.GetOrAddString(value: _assemblyName.CultureName), - publicKey: _assemblyName.GetPublicKey() is byte[] publicKey ? metadata.GetOrAddBlob(value: publicKey) : default, + culture: _assemblyName.CultureName == null ? default : _metadataBuilder.GetOrAddString(value: _assemblyName.CultureName), + publicKey: _assemblyName.GetPublicKey() is byte[] publicKey ? _metadataBuilder.GetOrAddBlob(value: publicKey) : default, flags: AddContentType((AssemblyFlags)_assemblyName.Flags, _assemblyName.ContentType), #pragma warning disable SYSLIB0037 // Type or member is obsolete hashAlgorithm: (AssemblyHashAlgorithm)_assemblyName.HashAlgorithm #pragma warning restore SYSLIB0037 ); + _module.WriteCustomAttributes(_customAttributes, assemblyHandle); // Add module's metadata - _module.AppendMetadata(metadata); + _module.AppendMetadata(); var ilBuilder = new BlobBuilder(); - WritePEImage(stream, metadata, ilBuilder); + WritePEImage(stream, ilBuilder); _previouslySaved = true; } @@ -114,7 +117,7 @@ protected override ModuleBuilder DefineDynamicModuleCore(string name) throw new InvalidOperationException(SR.InvalidOperation_NoMultiModuleAssembly); } - _module = new ModuleBuilderImpl(name, _coreAssembly); + _module = new ModuleBuilderImpl(name, _coreAssembly, _metadataBuilder); return _module; } @@ -128,8 +131,10 @@ protected override ModuleBuilder DefineDynamicModuleCore(string name) return null; } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) => throw new NotImplementedException(); - - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) => throw new NotImplementedException(); + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + _customAttributes ??= new List(); + _customAttributes.Add(new CustomAttributeWrapper(con, binaryAttribute)); + } } } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/CustomAttributeWrapper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/CustomAttributeWrapper.cs new file mode 100644 index 00000000000000..01813788bf7716 --- /dev/null +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/CustomAttributeWrapper.cs @@ -0,0 +1,179 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers.Binary; +using System.Diagnostics; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; + +namespace System.Reflection.Emit +{ + internal readonly struct CustomAttributeWrapper + { + private readonly ConstructorInfo _constructorInfo; + private readonly byte[] _binaryAttribute; + + public CustomAttributeWrapper(ConstructorInfo constructorInfo, ReadOnlySpan binaryAttribute) + { + _constructorInfo = constructorInfo; + _binaryAttribute = binaryAttribute.ToArray(); // TODO: Update to BlobHandle when public API public APi for MetadataBuilder.GetOrAddBlob(ReadOnlySpan) added + } + + public ConstructorInfo Ctor => _constructorInfo; + public byte[] Data => _binaryAttribute; + } + + internal struct CustomAttributeInfo + { + public ConstructorInfo _ctor; + public object?[] _ctorArgs; + public string[] _namedParamNames; + public object?[] _namedParamValues; + private const int Field = 0x53; + private const int EnumType = 0x55; + private const int NullValue = 0xff; + private const int OneByteMask = 0x7f; + private const int TwoByteMask = 0x3f; + private const int FourByteMask = 0x1f; + + internal static CustomAttributeInfo DecodeCustomAttribute(ConstructorInfo ctor, ReadOnlySpan binaryAttribute) + { + int pos = 2; + CustomAttributeInfo info = default; + + if (binaryAttribute.Length < 2) + { + throw new ArgumentException(SR.Format(SR.Argument_InvalidCustomAttributeLength, ctor.DeclaringType, binaryAttribute.Length), nameof(binaryAttribute)); + } + if ((binaryAttribute[0] != 0x01) || (binaryAttribute[1] != 0x00)) + { + throw new ArgumentException(SR.Format(SR.Argument_InvalidProlog, ctor.DeclaringType), nameof(binaryAttribute)); + } + + ParameterInfo[] pi = ctor.GetParameters(); + info._ctor = ctor; + info._ctorArgs = new object?[pi.Length]; + for (int i = 0; i < pi.Length; ++i) + { + info._ctorArgs[i] = DecodeCustomAttributeValue(pi[i].ParameterType, binaryAttribute, pos, out pos); + } + int numNamed = BinaryPrimitives.ReadUInt16LittleEndian(binaryAttribute.Slice(pos)); + pos += 2; + + info._namedParamNames = new string[numNamed]; + info._namedParamValues = new object[numNamed]; + for (int i = 0; i < numNamed; ++i) + { + int namedType = binaryAttribute[pos++]; + int dataType = binaryAttribute[pos++]; + + if (dataType == EnumType) + { + // skip bytes for Enum type name; + int len2 = DecodeLen(binaryAttribute, pos, out pos); + pos += len2; + } + + int len = DecodeLen(binaryAttribute, pos, out pos); + string name = StringFromBytes(binaryAttribute, pos, len); + info._namedParamNames[i] = name; + pos += len; + + if (namedType == Field) + { + // For known pseudo custom attributes underlying Enum type is int + Type fieldType = dataType == EnumType ? typeof(int) : ElementTypeToType((PrimitiveSerializationTypeCode)dataType); + info._namedParamValues[i] = DecodeCustomAttributeValue(fieldType, binaryAttribute, pos, out pos); ; + } + else + { + throw new ArgumentException(SR.Format(SR.Argument_UnknownNamedType, ctor.DeclaringType, namedType), nameof(binaryAttribute)); + } + } + + return info; + } + + private static string StringFromBytes(ReadOnlySpan data, int pos, int len) + { + return Text.Encoding.UTF8.GetString(data.Slice(pos, len)); + } + + private static int DecodeLen(ReadOnlySpan data, int pos, out int rpos) + { + int len; + if ((data[pos] & 0x80) == 0) + { + len = (data[pos++] & OneByteMask); + } + else if ((data[pos] & 0x40) == 0) + { + len = ((data[pos] & TwoByteMask) << 8) + data[pos + 1]; + pos += 2; + } + else + { + len = ((data[pos] & FourByteMask) << 24) + (data[pos + 1] << 16) + (data[pos + 2] << 8) + data[pos + 3]; + pos += 4; + } + rpos = pos; + return len; + } + + private static object? DecodeCustomAttributeValue(Type t, ReadOnlySpan data, int pos, out int rpos) + { + switch (Type.GetTypeCode(t)) + { + case TypeCode.String: + if (data[pos] == NullValue) + { + rpos = pos + 1; + return null; + } + int len = DecodeLen(data, pos, out pos); + rpos = pos + len; + return StringFromBytes(data, pos, len); + case TypeCode.Int32: + rpos = pos + 4; + return BinaryPrimitives.ReadInt32LittleEndian(data.Slice(pos)); + case TypeCode.Int16: + rpos = pos + 2; + return BinaryPrimitives.ReadInt16LittleEndian(data.Slice(pos)); + case TypeCode.Boolean: + rpos = pos + 1; + return (data[pos] == 0) ? false : true; + case TypeCode.Object: + int subtype = data[pos]; + pos += 1; + + if (subtype >= 0x02 && subtype <= 0x0e) + { + return DecodeCustomAttributeValue(ElementTypeToType((PrimitiveSerializationTypeCode)subtype), data, pos, out rpos); + } + break; + } + + throw new NotImplementedException(SR.Format(SR.NotImplemented_TypeForValue, t)); + } + + private static Type ElementTypeToType(PrimitiveSerializationTypeCode elementType) => + elementType switch + { + PrimitiveSerializationTypeCode.Boolean => typeof(bool), + PrimitiveSerializationTypeCode.Char => typeof(char), + PrimitiveSerializationTypeCode.SByte => typeof(sbyte), + PrimitiveSerializationTypeCode.Byte => typeof(byte), + PrimitiveSerializationTypeCode.Int16 => typeof(short), + PrimitiveSerializationTypeCode.UInt16 => typeof(ushort), + PrimitiveSerializationTypeCode.Int32 => typeof(int), + PrimitiveSerializationTypeCode.UInt32 => typeof(uint), + PrimitiveSerializationTypeCode.Int64 => typeof(long), + PrimitiveSerializationTypeCode.UInt64 => typeof(ulong), + PrimitiveSerializationTypeCode.Single => typeof(float), + PrimitiveSerializationTypeCode.Double => typeof(double), + PrimitiveSerializationTypeCode.String => typeof(string), + _ => throw new ArgumentException(SR.Argument_InvalidTypeCodeForTypeArgument, "binaryAttribute"), + }; + } +} diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/FieldBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/FieldBuilderImpl.cs index c017afa9f3580d..0e4fe230fb8cd2 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/FieldBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/FieldBuilderImpl.cs @@ -1,7 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; namespace System.Reflection.Emit { @@ -9,8 +16,12 @@ internal sealed class FieldBuilderImpl : FieldBuilder { private readonly TypeBuilderImpl _typeBuilder; private readonly string _fieldName; - private readonly FieldAttributes _attributes; private readonly Type _fieldType; + private FieldAttributes _attributes; + + internal MarshallingData? _marshallingData; + internal int _offset; + internal List? _customAttributes; internal FieldBuilderImpl(TypeBuilderImpl typeBuilder, string fieldName, Type type, FieldAttributes attributes) { @@ -18,14 +29,45 @@ internal FieldBuilderImpl(TypeBuilderImpl typeBuilder, string fieldName, Type ty _typeBuilder = typeBuilder; _fieldType = type; _attributes = attributes & ~FieldAttributes.ReservedMask; + _offset = -1; } - #region MemberInfo Overrides protected override void SetConstantCore(object? defaultValue) => throw new NotImplementedException(); - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) => throw new NotImplementedException(); + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + // Handle pseudo custom attributes + switch (con.ReflectedType!.FullName) + { + case "System.Runtime.InteropServices.FieldOffsetAttribute": + Debug.Assert(binaryAttribute.Length >= 6); + _offset = BinaryPrimitives.ReadInt32LittleEndian(binaryAttribute.Slice(2)); + return; + case "System.NonSerializedAttribute": +#pragma warning disable SYSLIB0050 // 'FieldAttributes.NotSerialized' is obsolete: 'Formatter-based serialization is obsolete and should not be used'. + _attributes |= FieldAttributes.NotSerialized; +#pragma warning restore SYSLIB0050 + return; + case "System.Runtime.CompilerServices.SpecialNameAttribute": + _attributes |= FieldAttributes.SpecialName; + return; + case "System.Runtime.InteropServices.MarshalAsAttribute": + _attributes |= FieldAttributes.HasFieldMarshal; + _marshallingData = MarshallingData.CreateMarshallingData(con, binaryAttribute, isField : true); + return; + } + + _customAttributes ??= new List(); + _customAttributes.Add(new CustomAttributeWrapper(con, binaryAttribute)); + } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) => throw new NotImplementedException(); - protected override void SetOffsetCore(int iOffset) => throw new NotImplementedException(); + protected override void SetOffsetCore(int iOffset) + { + ArgumentOutOfRangeException.ThrowIfNegative(iOffset); + + _offset = iOffset; + } + + #region MemberInfo Overrides public override int MetadataToken => throw new NotImplementedException(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs deleted file mode 100644 index 869c5ef3f11130..00000000000000 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs +++ /dev/null @@ -1,78 +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.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; - -namespace System.Reflection.Emit -{ - // This static helper class adds common entities to a MetadataBuilder. - internal static class MetadataHelper - { - internal static AssemblyReferenceHandle AddAssemblyReference(Assembly assembly, MetadataBuilder metadata) - { - AssemblyName assemblyName = assembly.GetName(); - - return AddAssemblyReference(metadata, assemblyName.Name!, assemblyName.Version, assemblyName.CultureName, - assemblyName.GetPublicKeyToken(), assemblyName.Flags, assemblyName.ContentType); - } - - internal static AssemblyReferenceHandle AddAssemblyReference(MetadataBuilder metadata, string name, Version? version, - string? culture, byte[]? publicKeyToken, AssemblyNameFlags flags, AssemblyContentType contentType) - { - return metadata.AddAssemblyReference( - name: metadata.GetOrAddString(name), - version: version ?? new Version(0, 0, 0, 0), - culture: (culture == null) ? default : metadata.GetOrAddString(value: culture), - publicKeyOrToken: (publicKeyToken == null) ? default : metadata.GetOrAddBlob(publicKeyToken), // reference has token, not full public key - flags: (AssemblyFlags)((int)contentType << 9) | ((flags & AssemblyNameFlags.Retargetable) != 0 ? AssemblyFlags.Retargetable : 0), - hashValue: default); // .file directive assemblies not supported, no need to handle this value. - } - - internal static TypeDefinitionHandle AddTypeDefinition(MetadataBuilder metadata, TypeBuilderImpl typeBuilder, EntityHandle baseType, int methodToken, int fieldToken) - { - // Add type metadata - return metadata.AddTypeDefinition( - attributes: typeBuilder.Attributes, - @namespace: (typeBuilder.Namespace == null) ? default : metadata.GetOrAddString(typeBuilder.Namespace), - name: metadata.GetOrAddString(typeBuilder.Name), - baseType: baseType, - fieldList: MetadataTokens.FieldDefinitionHandle(fieldToken), - methodList: MetadataTokens.MethodDefinitionHandle(methodToken)); - } - - internal static TypeReferenceHandle AddTypeReference(MetadataBuilder metadata, Type type, AssemblyReferenceHandle parent) - { - return AddTypeReference(metadata, parent, type.Name, type.Namespace); - } - - internal static TypeReferenceHandle AddTypeReference(MetadataBuilder metadata, AssemblyReferenceHandle parent, string name, string? nameSpace) - { - return metadata.AddTypeReference( - resolutionScope: parent, - @namespace: (nameSpace == null) ? default : metadata.GetOrAddString(nameSpace), - name: metadata.GetOrAddString(name) - ); - } - - internal static MethodDefinitionHandle AddMethodDefinition(MetadataBuilder metadata, MethodBuilderImpl methodBuilder, BlobBuilder methodSignatureBlob) - { - return metadata.AddMethodDefinition( - attributes: methodBuilder.Attributes, - implAttributes: MethodImplAttributes.IL, - name: metadata.GetOrAddString(methodBuilder.Name), - signature: metadata.GetOrAddBlob(methodSignatureBlob), - bodyOffset: -1, // No body supported yet - parameterList: MetadataTokens.ParameterHandle(1) - ); - } - - internal static FieldDefinitionHandle AddFieldDefinition(MetadataBuilder metadata, FieldInfo field, BlobBuilder fieldSignatureBlob) - { - return metadata.AddFieldDefinition( - attributes: field.Attributes, - name: metadata.GetOrAddString(field.Name), - signature: metadata.GetOrAddBlob(fieldSignatureBlob)); - } - } -} diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs index c63e4c26e5d47c..99cdaceeb9f8cf 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs @@ -1,9 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection.Metadata; +using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -12,10 +16,15 @@ internal sealed class MethodBuilderImpl : MethodBuilder private readonly Type _returnType; private readonly Type[]? _parameterTypes; private readonly ModuleBuilderImpl _module; - private readonly MethodAttributes _attributes; private readonly string _name; private readonly CallingConventions _callingConventions; private readonly TypeBuilderImpl _declaringType; + private MethodAttributes _attributes; + private MethodImplAttributes _methodImplFlags; + + internal DllImportData? _dllImportData; + internal List? _customAttributes; + internal ParameterBuilderImpl[]? _parameters; internal MethodBuilderImpl(string name, MethodAttributes attributes, CallingConventions callingConventions, Type? returnType, Type[]? parameterTypes, ModuleBuilderImpl module, TypeBuilderImpl declaringType) @@ -30,23 +39,72 @@ internal MethodBuilderImpl(string name, MethodAttributes attributes, CallingConv if (parameterTypes != null) { _parameterTypes = new Type[parameterTypes.Length]; + _parameters = new ParameterBuilderImpl[parameterTypes.Length + 1]; // parameter 0 reserved for return type for (int i = 0; i < parameterTypes.Length; i++) { ArgumentNullException.ThrowIfNull(_parameterTypes[i] = parameterTypes[i], nameof(parameterTypes)); } } + + _methodImplFlags = MethodImplAttributes.IL; } internal BlobBuilder GetMethodSignatureBlob() => - MetadataSignatureHelper.MethodSignatureEncoder(_module, _parameterTypes, ReturnType, IsStatic); + MetadataSignatureHelper.MethodSignatureEncoder(_module, _parameterTypes, ReturnType, !IsStatic); protected override bool InitLocalsCore { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } protected override GenericTypeParameterBuilder[] DefineGenericParametersCore(params string[] names) => throw new NotImplementedException(); - protected override ParameterBuilder DefineParameterCore(int position, ParameterAttributes attributes, string? strParamName) => throw new NotImplementedException(); + protected override ParameterBuilder DefineParameterCore(int position, ParameterAttributes attributes, string? strParamName) + { + if (position > 0 && (_parameterTypes == null || position > _parameterTypes.Length)) + throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_ParamSequence); + + _parameters ??= new ParameterBuilderImpl[1]; + + attributes &= ~ParameterAttributes.ReservedMask; + ParameterBuilderImpl parameter = new ParameterBuilderImpl(this, position, attributes, strParamName); + _parameters[position] = parameter; + return parameter; + } protected override ILGenerator GetILGeneratorCore(int size) => throw new NotImplementedException(); - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) => throw new NotImplementedException(); - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) => throw new NotImplementedException(); - protected override void SetImplementationFlagsCore(MethodImplAttributes attributes) => throw new NotImplementedException(); + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + // Handle pseudo custom attributes + switch (con.ReflectedType!.FullName) + { + case "System.Runtime.CompilerServices.MethodImplAttribute": + int implValue = BinaryPrimitives.ReadUInt16LittleEndian(binaryAttribute.Slice(2)); + _methodImplFlags |= (MethodImplAttributes)implValue; + return; + case "System.Runtime.InteropServices.DllImportAttribute": + { + _dllImportData = DllImportData.CreateDllImportData(CustomAttributeInfo.DecodeCustomAttribute(con, binaryAttribute), out var preserveSig); + _attributes |= MethodAttributes.PinvokeImpl; + if (preserveSig) + { + _methodImplFlags |= MethodImplAttributes.PreserveSig; + } + } + return; + case "System.Runtime.InteropServices.PreserveSigAttribute": + _methodImplFlags |= MethodImplAttributes.PreserveSig; + return; + case "System.Runtime.CompilerServices.SpecialNameAttribute": + _attributes |= MethodAttributes.SpecialName; + return; + case "System.Security.SuppressUnmanagedCodeSecurityAttribute": + _attributes |= MethodAttributes.HasSecurity; + break; + } + + _customAttributes ??= new List(); + _customAttributes.Add(new CustomAttributeWrapper(con, binaryAttribute)); + } + + protected override void SetImplementationFlagsCore(MethodImplAttributes attributes) + { + _methodImplFlags = attributes; + } protected override void SetSignatureCore(Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers) => throw new NotImplementedException(); public override string Name => _name; @@ -83,7 +141,7 @@ public override int GetHashCode() => throw new NotImplementedException(); public override MethodImplAttributes GetMethodImplementationFlags() - => throw new NotImplementedException(); + => _methodImplFlags; public override ParameterInfo[] GetParameters() => throw new NotImplementedException(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index 07dde6a0746ee6..8d2600d84542e2 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -13,24 +14,31 @@ internal sealed class ModuleBuilderImpl : ModuleBuilder { private readonly Assembly _coreAssembly; private readonly string _name; - private Type?[]? _coreTypes; - private readonly Dictionary _assemblyRefStore = new(); - private readonly Dictionary _typeRefStore = new(); - private readonly List _typeDefStore = new(); + private readonly MetadataBuilder _metadataBuilder; + private readonly Dictionary _assemblyReferences = new(); + private readonly Dictionary _typeReferences = new(); + private readonly List _typeDefinitions = new(); + private readonly Dictionary _ctorReferences = new(); + private Dictionary? _moduleReferences; + private List? _customAttributes; + private int _nextTypeDefRowId = 1; private int _nextMethodDefRowId = 1; private int _nextFieldDefRowId = 1; - private bool _coreTypesFullPopulated; + private int _nextParameterRowId = 1; + private bool _coreTypesFullyPopulated; + private Type?[]? _coreTypes; private static readonly Type[] s_coreTypes = { typeof(void), typeof(object), typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), - typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(nint), typeof(nuint) }; + typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(nint), typeof(nuint), typeof(TypedReference) }; - internal ModuleBuilderImpl(string name, Assembly coreAssembly) + internal ModuleBuilderImpl(string name, Assembly coreAssembly, MetadataBuilder builder) { _coreAssembly = coreAssembly; _name = name; + _metadataBuilder = builder; } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Types are preserved via s_coreTypes")] - internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) + internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) { if (_coreTypes == null) { @@ -38,7 +46,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) if (_coreAssembly == typeof(object).Assembly) { _coreTypes = s_coreTypes; - _coreTypesFullPopulated = true; + _coreTypesFullyPopulated = true; } else { @@ -59,7 +67,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) if (_coreAssembly == typeof(object).Assembly) { _coreTypes = s_coreTypes; - _coreTypesFullPopulated = true; + _coreTypesFullyPopulated = true; } else { @@ -67,7 +75,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) } } - if (!_coreTypesFullPopulated) + if (!_coreTypesFullyPopulated) { for (int i = 0; i < _coreTypes.Length; i++) { @@ -76,7 +84,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) _coreTypes[i] = _coreAssembly.GetType(s_coreTypes[i].FullName!, throwOnError: false)!; } } - _coreTypesFullPopulated = true; + _coreTypesFullyPopulated = true; } for (int i = 0; i < _coreTypes.Length; i++) @@ -90,72 +98,267 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) return null; } - internal void AppendMetadata(MetadataBuilder metadata) + internal void AppendMetadata() { // Add module metadata - metadata.AddModule( + ModuleDefinitionHandle moduleHandle = _metadataBuilder.AddModule( generation: 0, - moduleName: metadata.GetOrAddString(_name), - mvid: metadata.GetOrAddGuid(Guid.NewGuid()), + moduleName: _metadataBuilder.GetOrAddString(_name), + mvid: _metadataBuilder.GetOrAddGuid(Guid.NewGuid()), encId: default, encBaseId: default); // Create type definition for the special type that holds global functions - metadata.AddTypeDefinition( + _metadataBuilder.AddTypeDefinition( attributes: default, @namespace: default, - name: metadata.GetOrAddString(""), + name: _metadataBuilder.GetOrAddString(""), baseType: default, fieldList: MetadataTokens.FieldDefinitionHandle(1), - methodList: MetadataTokens.MethodDefinitionHandle(1)); ; + methodList: MetadataTokens.MethodDefinitionHandle(1)); + + WriteCustomAttributes(_customAttributes, moduleHandle); // Add each type definition to metadata table. - foreach (TypeBuilderImpl typeBuilder in _typeDefStore) + foreach (TypeBuilderImpl typeBuilder in _typeDefinitions) { - TypeReferenceHandle parent = default; + EntityHandle parent = default; if (typeBuilder.BaseType is not null) { - // TODO: need to handle the case when the base is from same assembly - parent = GetTypeReference(metadata, typeBuilder.BaseType); + parent = GetTypeHandle(typeBuilder.BaseType); } - TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(metadata, typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); + TypeDefinitionHandle typeDefinitionHandle = AddTypeDefinition(typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); + Debug.Assert(typeBuilder._handle.Equals(typeDefinitionHandle)); + WriteCustomAttributes(typeBuilder._customAttributes, typeDefinitionHandle); + + if ((typeBuilder.Attributes & TypeAttributes.ExplicitLayout) != 0) + { + _metadataBuilder.AddTypeLayout(typeDefinitionHandle, (ushort)typeBuilder.PackingSize, (uint)typeBuilder.Size); + } - // Add each method definition to metadata table. - foreach (MethodBuilderImpl method in typeBuilder._methodDefStore) + if (typeBuilder._interfaces != null) { - MetadataHelper.AddMethodDefinition(metadata, method, method.GetMethodSignatureBlob()); + foreach(Type iface in typeBuilder._interfaces) + { + _metadataBuilder.AddInterfaceImplementation(typeDefinitionHandle, GetTypeHandle(iface)); + // TODO: need to add interface mapping between interface method and implemented method + } + } + + if (typeBuilder.DeclaringType != null) + { + _metadataBuilder.AddNestedType(typeDefinitionHandle, (TypeDefinitionHandle)GetTypeHandle(typeBuilder.DeclaringType)); + } + + foreach (MethodBuilderImpl method in typeBuilder._methodDefinitions) + { + MethodDefinitionHandle methodHandle = AddMethodDefinition(method, method.GetMethodSignatureBlob(), _nextParameterRowId); + WriteCustomAttributes(method._customAttributes, methodHandle); _nextMethodDefRowId++; + + if (method._parameters != null) + { + foreach (ParameterBuilderImpl parameter in method._parameters) + { + if (parameter != null) + { + ParameterHandle parameterHandle = AddParameter(parameter); + WriteCustomAttributes(parameter._customAttributes, parameterHandle); + _nextParameterRowId++; + + if (parameter._marshallingData != null) + { + AddMarshalling(parameterHandle, parameter._marshallingData.SerializeMarshallingData()); + } + + if (parameter._defaultValue != DBNull.Value) + { + AddDefaultValue(parameterHandle, parameter._defaultValue); + } + } + } + } + + if (method._dllImportData != null) + { + AddMethodImport(methodHandle, method._dllImportData.EntryPoint ?? method.Name, + method._dllImportData.Flags, GetModuleReference(method._dllImportData.ModuleName)); + } } - foreach (FieldBuilderImpl field in typeBuilder._fieldDefStore) + foreach (FieldBuilderImpl field in typeBuilder._fieldDefinitions) { - MetadataHelper.AddFieldDefinition(metadata, field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); + FieldDefinitionHandle fieldHandle = AddFieldDefinition(field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); + WriteCustomAttributes(field._customAttributes, fieldHandle); _nextFieldDefRowId++; + + if (field._offset > 0 && (typeBuilder.Attributes & TypeAttributes.ExplicitLayout) != 0) + { + AddFieldLayout(fieldHandle, field._offset); + } + + if (field._marshallingData != null) + { + AddMarshalling(fieldHandle, field._marshallingData.SerializeMarshallingData()); + } + } + } + } + + private ModuleReferenceHandle GetModuleReference(string moduleName) + { + _moduleReferences ??= new Dictionary(); + + if (!_moduleReferences.TryGetValue(moduleName, out var handle)) + { + handle = AddModuleReference(moduleName); + _moduleReferences.Add(moduleName, handle); + } + + return handle; + } + + internal void WriteCustomAttributes(List? customAttributes, EntityHandle parent) + { + if (customAttributes != null) + { + foreach (CustomAttributeWrapper customAttribute in customAttributes) + { + _metadataBuilder.AddCustomAttribute(parent, GetConstructorHandle(customAttribute.Ctor), + _metadataBuilder.GetOrAddBlob(customAttribute.Data)); } } } - private TypeReferenceHandle GetTypeReference(MetadataBuilder metadata, Type type) + private MemberReferenceHandle GetConstructorHandle(ConstructorInfo constructorInfo) { - if (!_typeRefStore.TryGetValue(type, out var parentHandle)) + if (!_ctorReferences.TryGetValue(constructorInfo, out var constructorHandle)) { - parentHandle = MetadataHelper.AddTypeReference(metadata, type, - GetAssemblyReference(type.Assembly, metadata)); + TypeReferenceHandle parentHandle = GetTypeReference(constructorInfo.DeclaringType!); + constructorHandle = AddConstructorReference(parentHandle, constructorInfo); + _ctorReferences.Add(constructorInfo, constructorHandle); } - return parentHandle; + return constructorHandle; } - private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly, MetadataBuilder metadata) + private TypeReferenceHandle GetTypeReference(Type type) { - if (_assemblyRefStore.TryGetValue(assembly, out var handle)) + if (!_typeReferences.TryGetValue(type, out var typeHandle)) { - return handle; + typeHandle = AddTypeReference(type, GetAssemblyReference(type.Assembly)); + _typeReferences.Add(type, typeHandle); } - return MetadataHelper.AddAssemblyReference(assembly, metadata); + return typeHandle; + } + + private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly) + { + if (!_assemblyReferences.TryGetValue(assembly, out var handle)) + { + AssemblyName aName = assembly.GetName(); + handle = AddAssemblyReference(aName.Name!, aName.Version, aName.CultureName, aName.GetPublicKeyToken(), aName.Flags, aName.ContentType); + _assemblyReferences.Add(assembly, handle); + } + + return handle; + } + + private void AddDefaultValue(ParameterHandle parameterHandle, object? defaultValue) => + _metadataBuilder.AddConstant(parameterHandle, defaultValue); + + private FieldDefinitionHandle AddFieldDefinition(FieldBuilderImpl field, BlobBuilder fieldSignature) => + _metadataBuilder.AddFieldDefinition( + attributes: field.Attributes, + name: _metadataBuilder.GetOrAddString(field.Name), + signature: _metadataBuilder.GetOrAddBlob(fieldSignature)); + + private TypeDefinitionHandle AddTypeDefinition(TypeBuilderImpl type, EntityHandle parent, int methodToken, int fieldToken) => + _metadataBuilder.AddTypeDefinition( + attributes: type.Attributes, + @namespace: (type.Namespace == null) ? default : _metadataBuilder.GetOrAddString(type.Namespace), + name: _metadataBuilder.GetOrAddString(type.Name), + baseType: parent, + fieldList: MetadataTokens.FieldDefinitionHandle(fieldToken), + methodList: MetadataTokens.MethodDefinitionHandle(methodToken)); + + private MethodDefinitionHandle AddMethodDefinition(MethodBuilderImpl method, BlobBuilder methodSignature, int parameterToken) => + _metadataBuilder.AddMethodDefinition( + attributes: method.Attributes, + implAttributes: method.GetMethodImplementationFlags(), + name: _metadataBuilder.GetOrAddString(method.Name), + signature: _metadataBuilder.GetOrAddBlob(methodSignature), + bodyOffset: -1, // No body supported yet + parameterList: MetadataTokens.ParameterHandle(parameterToken)); + + private TypeReferenceHandle AddTypeReference(Type type, AssemblyReferenceHandle parent) => + _metadataBuilder.AddTypeReference( + resolutionScope: parent, + @namespace: (type.Namespace == null) ? default : _metadataBuilder.GetOrAddString(type.Namespace), + name: _metadataBuilder.GetOrAddString(type.Name)); + + private MemberReferenceHandle AddConstructorReference(TypeReferenceHandle parent, ConstructorInfo method) + { + var blob = MetadataSignatureHelper.ConstructorSignatureEncoder(method.GetParameters(), this); + return _metadataBuilder.AddMemberReference( + parent: parent, + name: _metadataBuilder.GetOrAddString(method.Name), + signature: _metadataBuilder.GetOrAddBlob(blob)); } + + private void AddMethodImport(MethodDefinitionHandle methodHandle, string name, + MethodImportAttributes attributes, ModuleReferenceHandle moduleHandle) => + _metadataBuilder.AddMethodImport( + method: methodHandle, + attributes: attributes, + name: _metadataBuilder.GetOrAddString(name), + module: moduleHandle); + + private ModuleReferenceHandle AddModuleReference(string moduleName) => + _metadataBuilder.AddModuleReference(moduleName: _metadataBuilder.GetOrAddString(moduleName)); + + private void AddFieldLayout(FieldDefinitionHandle fieldHandle, int offset) => + _metadataBuilder.AddFieldLayout(field: fieldHandle, offset: offset); + + private void AddMarshalling(EntityHandle fieldHandle, BlobBuilder builder) => + _metadataBuilder.AddMarshallingDescriptor(fieldHandle, _metadataBuilder.GetOrAddBlob(builder)); + + private ParameterHandle AddParameter(ParameterBuilderImpl parameter) => + _metadataBuilder.AddParameter( + attributes: (ParameterAttributes)parameter.Attributes, + name: parameter.Name != null ? _metadataBuilder.GetOrAddString(parameter.Name) : default, + sequenceNumber: parameter.Position); + + private AssemblyReferenceHandle AddAssemblyReference(string name, Version? version, string? culture, + byte[]? publicKeyToken, AssemblyNameFlags flags, AssemblyContentType contentType) => + _metadataBuilder.AddAssemblyReference( + name: _metadataBuilder.GetOrAddString(name), + version: version ?? new Version(0, 0, 0, 0), + culture: (culture == null) ? default : _metadataBuilder.GetOrAddString(value: culture), + publicKeyOrToken: (publicKeyToken == null) ? default : _metadataBuilder.GetOrAddBlob(publicKeyToken), // reference has token, not full public key + flags: (AssemblyFlags)((int)contentType << 9) | ((flags & AssemblyNameFlags.Retargetable) != 0 ? AssemblyFlags.Retargetable : 0), + hashValue: default); // .file directive assemblies not supported, no need to handle this value. + + internal EntityHandle GetTypeHandle(Type type) + { + if (type is TypeBuilderImpl tb && Equals(tb.Module)) + { + return tb._handle; + } + + return GetTypeReference(type); + } + internal TypeBuilder DefineNestedType(string name, TypeAttributes attr, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, + Type[]? interfaces, PackingSize packingSize, int typesize, TypeBuilderImpl? enclosingType) + { + TypeDefinitionHandle typeHandle = MetadataTokens.TypeDefinitionHandle(++_nextTypeDefRowId); + TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this, typeHandle, interfaces, packingSize, typesize, enclosingType); + _typeDefinitions.Add(_type); + return _type; + } + [RequiresAssemblyFiles("Returns for modules with no file path")] public override string Name => ""; public override string ScopeName => _name; @@ -171,16 +374,21 @@ private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly, Metadata protected override FieldBuilder DefineInitializedDataCore(string name, byte[] data, FieldAttributes attributes) => throw new NotImplementedException(); [RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")] protected override MethodBuilder DefinePInvokeMethodCore(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) => throw new NotImplementedException(); - protected override TypeBuilder DefineTypeCore(string name, TypeAttributes attr, [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type? parent, Type[]? interfaces, PackingSize packingSize, int typesize) + protected override TypeBuilder DefineTypeCore(string name, TypeAttributes attr, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, Type[]? interfaces, PackingSize packingSize, int typesize) { - TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this); - _typeDefStore.Add(_type); + TypeDefinitionHandle typeHandle = MetadataTokens.TypeDefinitionHandle(++_nextTypeDefRowId); + TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this, typeHandle, interfaces, packingSize, typesize, null); + _typeDefinitions.Add(_type); return _type; } protected override FieldBuilder DefineUninitializedDataCore(string name, int size, FieldAttributes attributes) => throw new NotImplementedException(); protected override MethodInfo GetArrayMethodCore(Type arrayClass, string methodName, CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes) => throw new NotImplementedException(); - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) => throw new NotSupportedException(); - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) => throw new NotSupportedException(); + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + _customAttributes ??= new List(); + _customAttributes.Add(new CustomAttributeWrapper(con, binaryAttribute)); + } public override int GetSignatureMetadataToken(SignatureHelper signature) => throw new NotImplementedException(); } } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ParameterBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ParameterBuilderImpl.cs new file mode 100644 index 00000000000000..4d64a644ab47e9 --- /dev/null +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ParameterBuilderImpl.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; + +namespace System.Reflection.Emit +{ + internal sealed class ParameterBuilderImpl : ParameterBuilder + { + private readonly string? _name; + private readonly int _position; + private readonly MethodBuilderImpl _methodBuilder; + private ParameterAttributes _attributes; + + internal List? _customAttributes; + internal MarshallingData? _marshallingData; + internal object? _defaultValue = DBNull.Value; + + public ParameterBuilderImpl(MethodBuilderImpl methodBuilder, int sequence, ParameterAttributes attributes, string? paramName) + { + _position = sequence; + _name = paramName; + _methodBuilder = methodBuilder; + _attributes = attributes; + } + + public override int Attributes => (int)_attributes; + + public override string? Name => _name; + + public override int Position => _position; + + public override void SetConstant(object? defaultValue) => _defaultValue = defaultValue; + + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + switch (con.ReflectedType!.FullName) + { + case "System.Runtime.InteropServices.InAttribute": + _attributes |= ParameterAttributes.In; + return; + case "System.Runtime.InteropServices.OutAttribute": + _attributes |= ParameterAttributes.Out; + return; + case "System.Runtime.InteropServices.OptionalAttribute": + _attributes |= ParameterAttributes.Optional; + return; + case "System.Runtime.InteropServices.MarshalAsAttribute": + _attributes |= ParameterAttributes.HasFieldMarshal; + _marshallingData = MarshallingData.CreateMarshallingData(con, binaryAttribute, isField: false); + return; + case "System.Runtime.InteropServices.DefaultParameterValueAttribute": + // MS.NET doesn't handle this attribute but we handle it for consistency TODO: not sure if we need to handle this + CustomAttributeInfo caInfo = CustomAttributeInfo.DecodeCustomAttribute(con, binaryAttribute); + SetConstant(caInfo._ctorArgs[0]); + return; + } + + _customAttributes ??= new List(); + _customAttributes.Add(new CustomAttributeWrapper(con, binaryAttribute)); + } + } +} diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/PseudoCustomAttributesData.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/PseudoCustomAttributesData.cs new file mode 100644 index 00000000000000..93dd864ccedf10 --- /dev/null +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/PseudoCustomAttributesData.cs @@ -0,0 +1,495 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Reflection.Metadata; +using System.Runtime.InteropServices; + +namespace System.Reflection.Emit +{ + internal sealed class DllImportData + { + private readonly string _moduleName; + private readonly string? _entryPoint; + private readonly MethodImportAttributes _flags; + + internal DllImportData(string moduleName, string? entryPoint, MethodImportAttributes flags) + { + _moduleName = moduleName; + _entryPoint = entryPoint; + _flags = flags; + } + + public string ModuleName => _moduleName; + + public string? EntryPoint => _entryPoint; + + public MethodImportAttributes Flags => _flags; + + internal static DllImportData CreateDllImportData(CustomAttributeInfo attr, out bool preserveSig) + { + string? moduleName = (string?)attr._ctorArgs[0]; + if (moduleName == null || moduleName.Length == 0) + { + throw new ArgumentException(SR.Argument_DllNameCannotBeEmpty); + } + + MethodImportAttributes importAttributes = MethodImportAttributes.None; + string? entryPoint = null; + preserveSig = true; + for (int i = 0; i < attr._namedParamNames.Length; ++i) + { + string name = attr._namedParamNames[i]; + object value = attr._namedParamValues[i]!; + switch (name) + { + case "PreserveSig": + preserveSig = (bool)value; + break; + case "CallingConvention": + importAttributes |= (CallingConvention)value switch + { + CallingConvention.Cdecl => MethodImportAttributes.CallingConventionCDecl, + CallingConvention.FastCall => MethodImportAttributes.CallingConventionFastCall, + CallingConvention.StdCall => MethodImportAttributes.CallingConventionStdCall, + CallingConvention.ThisCall => MethodImportAttributes.CallingConventionThisCall, + _ => MethodImportAttributes.CallingConventionWinApi // Roslyn defaults with this + }; + break; + case "CharSet": + importAttributes |= (CharSet)value switch + { + CharSet.Ansi => MethodImportAttributes.CharSetAnsi, + CharSet.Auto => MethodImportAttributes.CharSetAuto, + CharSet.Unicode => MethodImportAttributes.CharSetUnicode, + _ => MethodImportAttributes.CharSetAuto + }; + break; + case "EntryPoint": + entryPoint = (string?)value; + break; + case "ExactSpelling": + if ((bool)value) + { + importAttributes |= MethodImportAttributes.ExactSpelling; + } + break; + case "SetLastError": + if ((bool)value) + { + importAttributes |= MethodImportAttributes.SetLastError; + } + break; + case "BestFitMapping": + if ((bool)value) + { + importAttributes |= MethodImportAttributes.BestFitMappingEnable; + } + else + { + importAttributes |= MethodImportAttributes.BestFitMappingDisable; + } + break; + case "ThrowOnUnmappableChar": + if ((bool)value) + { + importAttributes |= MethodImportAttributes.ThrowOnUnmappableCharEnable; + } + else + { + importAttributes |= MethodImportAttributes.ThrowOnUnmappableCharDisable; + } + break; + } + } + + return new DllImportData(moduleName, entryPoint, importAttributes); + } + } + + internal sealed class MarshallingData + { + private UnmanagedType _marshalType; + private int _marshalArrayElementType; // safe array: VarEnum; array: UnmanagedType + private int _marshalArrayElementCount; // number of elements in an array, length of a string, or Unspecified + private int _marshalParameterIndex; // index of parameter that specifies array size (short) or IID (int), or Unspecified + private object? _marshalTypeNameOrSymbol; // custom marshaller: string or Type; safe array: element type + private string? _marshalCookie; + + internal const int Invalid = -1; + private const UnmanagedType InvalidUnmanagedType = (UnmanagedType)Invalid; + private const VarEnum InvalidVariantType = (VarEnum)Invalid; + private const int MaxMarshalInteger = 0x1fffffff; + + // The logic imported from https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs#L3543 + internal BlobBuilder SerializeMarshallingData() + { + BlobBuilder writer = new BlobBuilder(); ; + writer.WriteCompressedInteger((int)_marshalType); + switch (_marshalType) + { + case UnmanagedType.ByValArray: // NATIVE_TYPE_FIXEDARRAY + Debug.Assert(_marshalArrayElementCount >= 0); + writer.WriteCompressedInteger(_marshalArrayElementCount); + if (_marshalArrayElementType >= 0) + { + writer.WriteCompressedInteger(_marshalArrayElementType); + } + break; + case UnmanagedType.CustomMarshaler: + writer.WriteUInt16(0); // padding + + switch (_marshalTypeNameOrSymbol) + { + case Type type: + writer.WriteSerializedString(type.FullName); // or AssemblyQualifiedName? + break; + case null: + writer.WriteByte(0); + break; + default: + writer.WriteSerializedString((string)_marshalTypeNameOrSymbol); + break; + } + + if (_marshalCookie != null) + { + writer.WriteSerializedString(_marshalCookie); + } + else + { + writer.WriteByte(0); + } + break; + case UnmanagedType.LPArray: // NATIVE_TYPE_ARRAY + Debug.Assert(_marshalArrayElementType >= 0); + writer.WriteCompressedInteger(_marshalArrayElementType); + if (_marshalParameterIndex >= 0) + { + writer.WriteCompressedInteger(_marshalParameterIndex); + if (_marshalArrayElementCount >= 0) + { + writer.WriteCompressedInteger(_marshalArrayElementCount); + writer.WriteByte(1); // The parameter number is valid + } + } + else if (_marshalArrayElementCount >= 0) + { + writer.WriteByte(0); // Dummy parameter value emitted so that NumberOfElements can be in a known position + writer.WriteCompressedInteger(_marshalArrayElementCount); + writer.WriteByte(0); // The parameter number is not valid + } + break; + case UnmanagedType.SafeArray: + VarEnum safeArrayElementSubtype = (VarEnum)_marshalArrayElementType; + if (safeArrayElementSubtype >= 0) + { + writer.WriteCompressedInteger((int)safeArrayElementSubtype); + + if (_marshalTypeNameOrSymbol is Type elementType) + { + writer.WriteSerializedString(elementType.FullName); + } + } + break; + case UnmanagedType.ByValTStr: // NATIVE_TYPE_FIXEDSYSSTRING + writer.WriteCompressedInteger(_marshalArrayElementCount); + break; + + case UnmanagedType.Interface: + case UnmanagedType.IDispatch: + case UnmanagedType.IUnknown: + if (_marshalParameterIndex >= 0) + { + writer.WriteCompressedInteger(_marshalParameterIndex); + } + break; + } + + return writer; + } + + internal void SetMarshalAsCustom(object typeSymbolOrName, string? cookie) + { + _marshalType = UnmanagedType.CustomMarshaler; + _marshalTypeNameOrSymbol = typeSymbolOrName; + _marshalCookie = cookie; + } + + internal void SetMarshalAsComInterface(UnmanagedType unmanagedType, int? parameterIndex) + { + Debug.Assert(parameterIndex == null || parameterIndex >= 0 && parameterIndex <= MaxMarshalInteger); + + _marshalType = unmanagedType; + _marshalParameterIndex = parameterIndex ?? Invalid; + } + + internal void SetMarshalAsArray(UnmanagedType? elementType, int? elementCount, short? parameterIndex) + { + Debug.Assert(elementCount == null || elementCount >= 0 && elementCount <= MaxMarshalInteger); + Debug.Assert(parameterIndex == null || parameterIndex >= 0); + + _marshalType = UnmanagedType.LPArray; + _marshalArrayElementType = (int)(elementType ?? (UnmanagedType)0x50); + _marshalArrayElementCount = elementCount ?? Invalid; + _marshalParameterIndex = parameterIndex ?? Invalid; + } + + internal void SetMarshalAsFixedArray(UnmanagedType? elementType, int? elementCount) + { + Debug.Assert(elementCount == null || elementCount >= 0 && elementCount <= MaxMarshalInteger); + Debug.Assert(elementType == null || elementType >= 0 && (int)elementType <= MaxMarshalInteger); + + _marshalType = UnmanagedType.ByValArray; + _marshalArrayElementType = (int)(elementType ?? InvalidUnmanagedType); + _marshalArrayElementCount = elementCount ?? Invalid; + } + + internal void SetMarshalAsSafeArray(VarEnum? elementType, Type? type) + { + Debug.Assert(elementType == null || elementType >= 0 && (int)elementType <= MaxMarshalInteger); + + _marshalType = UnmanagedType.SafeArray; + _marshalArrayElementType = (int)(elementType ?? InvalidVariantType); + _marshalTypeNameOrSymbol = type; + } + + internal void SetMarshalAsFixedString(int elementCount) + { + Debug.Assert(elementCount >= 0 && elementCount <= MaxMarshalInteger); + + _marshalType = UnmanagedType.ByValTStr; + _marshalArrayElementCount = elementCount; + } + + internal void SetMarshalAsSimpleType(UnmanagedType type) + { + Debug.Assert(type >= 0 && (int)type <= MaxMarshalInteger); + _marshalType = type; + } + + // The logic imported from https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs + internal static MarshallingData CreateMarshallingData(ConstructorInfo con, ReadOnlySpan binaryAttribute, bool isField) + { + CustomAttributeInfo attributeInfo = CustomAttributeInfo.DecodeCustomAttribute(con, binaryAttribute); + MarshallingData info = new(); + UnmanagedType unmanagedType; + + if (attributeInfo._ctorArgs[0] is short shortValue) + { + unmanagedType = (UnmanagedType)shortValue; + } + else + { + unmanagedType = (UnmanagedType)attributeInfo._ctorArgs[0]!; + } + + switch (unmanagedType) + { + case UnmanagedType.CustomMarshaler: + DecodeMarshalAsCustom(attributeInfo._namedParamNames, attributeInfo._namedParamValues, info); + break; + case UnmanagedType.Interface: + case UnmanagedType.IDispatch: + case UnmanagedType.IUnknown: + DecodeMarshalAsComInterface(attributeInfo._namedParamNames, attributeInfo._namedParamValues, unmanagedType, info); + break; + case UnmanagedType.LPArray: + DecodeMarshalAsArray(attributeInfo._namedParamNames, attributeInfo._namedParamValues, isFixed: false, info); + break; + case UnmanagedType.ByValArray: + if (!isField) + { + throw new NotSupportedException(SR.Format(SR.NotSupported_UnmanagedTypeOnlyForFields, nameof(UnmanagedType.ByValArray))); + } + DecodeMarshalAsArray(attributeInfo._namedParamNames, attributeInfo._namedParamValues, isFixed: true, info); + break; + case UnmanagedType.SafeArray: + DecodeMarshalAsSafeArray(attributeInfo._namedParamNames, attributeInfo._namedParamValues, info); + break; + case UnmanagedType.ByValTStr: + if (!isField) + { + throw new NotSupportedException(SR.Format(SR.NotSupported_UnmanagedTypeOnlyForFields, nameof(UnmanagedType.ByValArray))); + } + DecodeMarshalAsFixedString(attributeInfo._namedParamNames, attributeInfo._namedParamValues, info); + break; +#pragma warning disable CS0618 // Type or member is obsolete + case UnmanagedType.VBByRefStr: +#pragma warning restore CS0618 + // named parameters ignored with no error + info.SetMarshalAsSimpleType(unmanagedType); + break; + default: + if ((int)unmanagedType < 0 || (int)unmanagedType > MaxMarshalInteger) + { + throw new ArgumentException(SR.Argument_InvalidArgumentForAttribute, nameof(con)); + } + else + { + // named parameters ignored with no error + info.SetMarshalAsSimpleType(unmanagedType); + } + break; + } + + return info; + } + + private static void DecodeMarshalAsFixedString(string[] paramNames, object?[] values, MarshallingData info) + { + int elementCount = -1; + + for (int i = 0; i < paramNames.Length; i++) + { + switch (paramNames[i]) + { + case "SizeConst": + elementCount = (int)values[i]!; + break; + case "ArraySubType": + case "SizeParamIndex": + throw new ArgumentException(SR.Format(SR.Argument_InvalidParameterForUnmanagedType, paramNames[i], "ByValTStr"), "binaryAttribute"); + // other parameters ignored with no error + } + } + + if (elementCount < 0) + { + // SizeConst must be specified: + throw new ArgumentException(SR.Argument_SizeConstMustBeSpecified, "binaryAttribute"); + } + + info.SetMarshalAsFixedString(elementCount); + } + + private static void DecodeMarshalAsSafeArray(string[] paramNames, object?[] values, MarshallingData info) + { + VarEnum? elementTypeVariant = null; + Type? elementType = null; + int symbolIndex = -1; + + for (int i = 0; i < paramNames.Length; i++) + { + switch (paramNames[i]) + { + case "SafeArraySubType": + elementTypeVariant = (VarEnum)values[i]!; + break; + case "SafeArrayUserDefinedSubType": + elementType = (Type?)values[i]; + symbolIndex = i; + break; + case "ArraySubType": + case "SizeConst": + case "SizeParamIndex": + throw new ArgumentException(SR.Format(SR.Argument_InvalidParameterForUnmanagedType, paramNames[i], "SafeArray"), "binaryAttribute"); + // other parameters ignored with no error + } + } + + switch (elementTypeVariant) + { + case VarEnum.VT_DISPATCH: + case VarEnum.VT_UNKNOWN: + case VarEnum.VT_RECORD: + // only these variants accept specification of user defined subtype + break; + + default: + if (elementTypeVariant != null && symbolIndex >= 0) + { + throw new ArgumentException(SR.Format(SR.Argument_InvalidParameterForUnmanagedType, elementType, "SafeArray"), "binaryAttribute"); + } + else + { + // type ignored: + elementType = null; + } + break; + } + + info.SetMarshalAsSafeArray(elementTypeVariant, elementType); + } + + private static void DecodeMarshalAsArray(string[] paramNames, object?[] values, bool isFixed, MarshallingData info) + { + UnmanagedType? elementType = null; + int? elementCount = isFixed ? 1 : null; + short? parameterIndex = null; + + for (int i = 0; i < paramNames.Length; i++) + { + switch (paramNames[i]) + { + case "ArraySubType": + elementType = (UnmanagedType)values[i]!; + break; + case "SizeConst": + elementCount = (int?)values[i]; + break; + case "SizeParamIndex": + if (isFixed) + { + goto case "SafeArraySubType"; + } + parameterIndex = (short?)values[i]; + break; + case "SafeArraySubType": + throw new ArgumentException(SR.Format(SR.Argument_InvalidParameterForUnmanagedType, + paramNames[i], isFixed ? "ByValArray" : "LPArray"), "binaryAttribute"); + // other parameters ignored with no error + } + } + + if (isFixed) + { + info.SetMarshalAsFixedArray(elementType, elementCount); + } + else + { + info.SetMarshalAsArray(elementType, elementCount, parameterIndex); + } + } + + private static void DecodeMarshalAsComInterface(string[] paramNames, object?[] values, UnmanagedType unmanagedType, MarshallingData info) + { + int? parameterIndex = null; + for (int i = 0; i < paramNames.Length; i++) + { + if (paramNames[i] == "IidParameterIndex") + { + parameterIndex = (int?)values[i]; + break; + } + } + + info.SetMarshalAsComInterface(unmanagedType, parameterIndex); + } + + private static void DecodeMarshalAsCustom(string[] paramNames, object?[] values, MarshallingData info) + { + string? cookie = null; + Type? type = null; + string? name = null; + for (int i = 0; i < paramNames.Length; i++) + { + switch (paramNames[i]) + { + case "MarshalType": + name = (string?)values[i]; + break; + case "MarshalTypeRef": + type = (Type?)values[i]; + break; + case "MarshalCookie": + cookie = (string?)values[i]; + break; + // other parameters ignored with no error + } + } + + info.SetMarshalAsCustom((object?)name ?? type!, cookie); + } + } +} diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs index ad950b15152ac3..7bdc5cf8734d71 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs @@ -1,39 +1,58 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; namespace System.Reflection.Emit { - // TODO: Only support simple signatures. More complex signatures will be added. + // TODO: Only support simple signatures. More complex signatures (generics, array, byref, pointers etc) will be added. internal static class MetadataSignatureHelper { internal static BlobBuilder FieldSignatureEncoder(Type fieldType, ModuleBuilderImpl module) { BlobBuilder fieldSignature = new(); - WriteSignatureTypeForReflectionType(new BlobEncoder(fieldSignature).FieldSignature(), fieldType, module); + WriteSignatureForType(new BlobEncoder(fieldSignature).FieldSignature(), fieldType, module); return fieldSignature; } + internal static BlobBuilder ConstructorSignatureEncoder(ParameterInfo[]? parameters, ModuleBuilderImpl module) + { + BlobBuilder constructorSignature = new(); + + new BlobEncoder(constructorSignature). + MethodSignature(isInstanceMethod: true). + Parameters((parameters == null) ? 0 : parameters.Length, out ReturnTypeEncoder retType, out ParametersEncoder parameterEncoder); + + retType.Void(); + + if (parameters != null) + { + Type[]? typeParameters = Array.ConvertAll(parameters, parameter => parameter.ParameterType); + + foreach (Type parameter in typeParameters) + { + WriteSignatureForType(parameterEncoder.AddParameter().Type(), parameter, module); + } + } + + return constructorSignature; + } + internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Type[]? parameters, Type? returnType, bool isInstance) { // Encoding return type and parameters. BlobBuilder methodSignature = new(); - ParametersEncoder parEncoder; - ReturnTypeEncoder retEncoder; - new BlobEncoder(methodSignature). MethodSignature(isInstanceMethod: isInstance). - Parameters((parameters == null) ? 0 : parameters.Length, out retEncoder, out parEncoder); + Parameters((parameters == null) ? 0 : parameters.Length, out ReturnTypeEncoder retEncoder, out ParametersEncoder parEncoder); if (returnType != null && returnType != module.GetTypeFromCoreAssembly(CoreTypeId.Void)) { - WriteSignatureTypeForReflectionType(retEncoder.Type(), returnType, module); + WriteSignatureForType(retEncoder.Type(), returnType, module); } else // If null mark ReturnTypeEncoder as void { @@ -44,71 +63,74 @@ internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Typ { foreach (Type parameter in parameters) { - WriteSignatureTypeForReflectionType(parEncoder.AddParameter().Type(), parameter, module); + WriteSignatureForType(parEncoder.AddParameter().Type(), parameter, module); } } return methodSignature; } - private static void WriteSignatureTypeForReflectionType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module) + private static void WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module) { CoreTypeId? typeId = module.GetTypeIdFromCoreTypes(type); - // We need to translate from Reflection.Type to SignatureTypeEncoder. switch (typeId) { case CoreTypeId.Boolean: signature.Boolean(); - break; + return; case CoreTypeId.Byte: signature.Byte(); - break; + return; case CoreTypeId.SByte: signature.SByte(); - break; + return; case CoreTypeId.Char: signature.Char(); - break; + return; case CoreTypeId.Int16: signature.Int16(); - break; + return; case CoreTypeId.UInt16: signature.UInt16(); - break; + return; case CoreTypeId.Int32: signature.Int32(); - break; + return; case CoreTypeId.UInt32: signature.UInt32(); - break; + return; case CoreTypeId.Int64: signature.Int64(); - break; + return; case CoreTypeId.UInt64: signature.UInt64(); - break; + return; case CoreTypeId.Single: signature.Single(); - break; + return; case CoreTypeId.Double: signature.Double(); - break; + return; case CoreTypeId.IntPtr: signature.IntPtr(); - break; + return; case CoreTypeId.UIntPtr: signature.UIntPtr(); - break; + return; case CoreTypeId.Object: signature.Object(); - break; + return; case CoreTypeId.String: signature.String(); - break; - default: - throw new NotSupportedException(SR.Format(SR.NotSupported_Signature, type.FullName)); + return; + case CoreTypeId.TypedReference: + signature.Builder.WriteByte((byte)SignatureTypeCode.TypedReference); + return; } + + EntityHandle typeHandle = module.GetTypeHandle(type); + signature.Type(typeHandle, type.IsValueType); } } @@ -131,5 +153,6 @@ internal enum CoreTypeId String, IntPtr, UIntPtr, + TypedReference, } } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs index 71548abab22ef7..4e5fbaf7125828 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs @@ -3,29 +3,43 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; using System.Globalization; +using System.Runtime.InteropServices; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; namespace System.Reflection.Emit { internal sealed class TypeBuilderImpl : TypeBuilder { - internal List _methodDefStore = new(); - internal List _fieldDefStore = new(); private readonly ModuleBuilderImpl _module; private readonly string _name; private readonly string? _namespace; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] private Type? _typeParent; + private readonly TypeBuilderImpl? _declaringType; private TypeAttributes _attributes; + private PackingSize _packingSize; + private int _typeSize; + + internal readonly TypeDefinitionHandle _handle; + internal readonly List _methodDefinitions = new(); + internal readonly List _fieldDefinitions = new(); + internal List? _interfaces; + internal List? _customAttributes; internal TypeBuilderImpl(string fullName, TypeAttributes typeAttributes, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, ModuleBuilderImpl module) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, ModuleBuilderImpl module, + TypeDefinitionHandle handle, Type[]? interfaces, PackingSize packingSize, int typeSize, TypeBuilderImpl? enclosingType) { _name = fullName; _module = module; _attributes = typeAttributes; + _packingSize = packingSize; + _typeSize = typeSize; SetParent(parent); + _handle = handle; + _declaringType = enclosingType; // Extract namespace from fullName int idx = _name.LastIndexOf('.'); @@ -34,12 +48,28 @@ internal TypeBuilderImpl(string fullName, TypeAttributes typeAttributes, _namespace = _name[..idx]; _name = _name[(idx + 1)..]; } + + if (interfaces != null) + { + _interfaces = new List(); + for (int i = 0; i < interfaces.Length; i++) + { + Type @interface = interfaces[i]; + // cannot contain null in the interface list + ArgumentNullException.ThrowIfNull(@interface, nameof(interfaces)); + _interfaces.Add(@interface); + } + } } internal ModuleBuilderImpl GetModuleBuilder() => _module; - protected override PackingSize PackingSizeCore => throw new NotImplementedException(); - protected override int SizeCore => throw new NotImplementedException(); - protected override void AddInterfaceImplementationCore([DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type interfaceType) => throw new NotImplementedException(); + protected override PackingSize PackingSizeCore => _packingSize; + protected override int SizeCore => _typeSize; + protected override void AddInterfaceImplementationCore([DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes.All))] Type interfaceType) + { + _interfaces ??= new List(); + _interfaces.Add(interfaceType); + } [return: DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] protected override TypeInfo CreateTypeInfoCore() => throw new NotImplementedException(); protected override ConstructorBuilder DefineConstructorCore(MethodAttributes attributes, CallingConventions callingConvention, Type[]? parameterTypes, Type[][]? requiredCustomModifiers, Type[][]? optionalCustomModifiers) => throw new NotImplementedException(); @@ -48,7 +78,7 @@ internal TypeBuilderImpl(string fullName, TypeAttributes typeAttributes, protected override FieldBuilder DefineFieldCore(string fieldName, Type type, Type[]? requiredCustomModifiers, Type[]? optionalCustomModifiers, FieldAttributes attributes) { var field = new FieldBuilderImpl(this, fieldName, type, attributes); - _fieldDefStore.Add(field); + _fieldDefinitions.Add(field); return field; } protected override GenericTypeParameterBuilder[] DefineGenericParametersCore(params string[] names) => throw new NotImplementedException(); @@ -56,20 +86,102 @@ protected override FieldBuilder DefineFieldCore(string fieldName, Type type, Typ protected override MethodBuilder DefineMethodCore(string name, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers) { MethodBuilderImpl methodBuilder = new(name, attributes, callingConvention, returnType, parameterTypes, _module, this); - _methodDefStore.Add(methodBuilder); + _methodDefinitions.Add(methodBuilder); return methodBuilder; } protected override void DefineMethodOverrideCore(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) => throw new NotImplementedException(); - protected override TypeBuilder DefineNestedTypeCore(string name, TypeAttributes attr, [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type? parent, Type[]? interfaces, Emit.PackingSize packSize, int typeSize) => throw new NotImplementedException(); + protected override TypeBuilder DefineNestedTypeCore(string name, TypeAttributes attr, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, Type[]? interfaces, PackingSize packSize, int typeSize) + { + return _module.DefineNestedType(name, attr, parent, interfaces, packSize, typeSize, this); + } + [RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")] protected override MethodBuilder DefinePInvokeMethodCore(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) => throw new NotImplementedException(); protected override PropertyBuilder DefinePropertyCore(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers) => throw new NotImplementedException(); protected override ConstructorBuilder DefineTypeInitializerCore() => throw new NotImplementedException(); protected override FieldBuilder DefineUninitializedDataCore(string name, int size, FieldAttributes attributes) => throw new NotImplementedException(); protected override bool IsCreatedCore() => throw new NotImplementedException(); - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) => throw new NotImplementedException(); - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) => throw new NotImplementedException(); + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + // Handle pseudo custom attributes + switch (con.ReflectedType!.FullName) + { + case "System.Runtime.InteropServices.StructLayoutAttribute": + ParseStructLayoutAttribute(con, binaryAttribute); + return; + case "System.Runtime.CompilerServices.SpecialNameAttribute": + _attributes |= TypeAttributes.SpecialName; + return; + case "System.SerializableAttribute": +#pragma warning disable SYSLIB0050 // 'TypeAttributes.Serializable' is obsolete: 'Formatter-based serialization is obsolete and should not be used'. + _attributes |= TypeAttributes.Serializable; +#pragma warning restore SYSLIB0050 + return; + case "System.Runtime.InteropServices.ComImportAttribute": + _attributes |= TypeAttributes.Import; + return; + case "System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeImportAttribute": + _attributes |= TypeAttributes.WindowsRuntime; + return; + case "System.Security.SuppressUnmanagedCodeSecurityAttribute": // It says has no effect in .NET Core, maybe remove? + _attributes |= TypeAttributes.HasSecurity; + break; + } + + _customAttributes ??= new List(); + _customAttributes.Add(new CustomAttributeWrapper(con, binaryAttribute)); + } + + private void ParseStructLayoutAttribute(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + CustomAttributeInfo attributeInfo = CustomAttributeInfo.DecodeCustomAttribute(con, binaryAttribute); + LayoutKind layoutKind = (LayoutKind)attributeInfo._ctorArgs[0]!; + _attributes &= ~TypeAttributes.LayoutMask; + _attributes |= layoutKind switch + { + LayoutKind.Auto => TypeAttributes.AutoLayout, + LayoutKind.Explicit => TypeAttributes.ExplicitLayout, + LayoutKind.Sequential => TypeAttributes.SequentialLayout, + _ => TypeAttributes.AutoLayout, + }; + + for (int i = 0; i < attributeInfo._namedParamNames.Length; ++i) + { + string name = attributeInfo._namedParamNames[i]; + int value = (int)attributeInfo._namedParamValues[i]!; + + switch (name) + { + case "CharSet": + switch ((CharSet)value) + { + case CharSet.None: + case CharSet.Ansi: + _attributes &= ~(TypeAttributes.UnicodeClass | TypeAttributes.AutoClass); + break; + case CharSet.Unicode: + _attributes &= ~TypeAttributes.AutoClass; + _attributes |= TypeAttributes.UnicodeClass; + break; + case CharSet.Auto: + _attributes &= ~TypeAttributes.UnicodeClass; + _attributes |= TypeAttributes.AutoClass; + break; + } + break; + case "Pack": + _packingSize = (PackingSize)value; + break; + case "Size": + _typeSize = value; + break; + default: + throw new ArgumentException(SR.Format(SR.Argument_UnknownNamedType, con.DeclaringType, name), nameof(binaryAttribute)); + } + } + } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2074:DynamicallyAccessedMembers", Justification = "TODO: Need to figure out how to preserve System.Object public constructor")] @@ -103,6 +215,8 @@ protected override void SetParentCore([DynamicallyAccessedMembers(DynamicallyAcc } } public override string Name => _name; + public override Type? DeclaringType => _declaringType; + public override Type? ReflectedType => _declaringType; public override bool IsDefined(Type attributeType, bool inherit) => throw new NotImplementedException(); public override object[] GetCustomAttributes(bool inherit) => throw new NotImplementedException(); public override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw new NotImplementedException(); @@ -112,10 +226,10 @@ protected override void SetParentCore([DynamicallyAccessedMembers(DynamicallyAcc public override string? Namespace => _namespace; public override Assembly Assembly => _module.Assembly; public override Module Module => _module; - public override Type UnderlyingSystemType => throw new NotSupportedException(); + public override Type UnderlyingSystemType => this; public override Guid GUID => throw new NotSupportedException(); public override Type? BaseType => _typeParent; - + public override int MetadataToken => MetadataTokens.GetToken(_handle); [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) => throw new NotSupportedException(); @@ -157,7 +271,8 @@ protected override bool IsCOMObjectImpl() public override Type? GetInterface(string name, bool ignoreCase) => throw new NotSupportedException(); [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] - public override Type[] GetInterfaces() => throw new NotSupportedException(); + public override Type[] GetInterfaces() => _interfaces == null ? EmptyTypes : _interfaces.ToArray(); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) => throw new NotSupportedException(); [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] diff --git a/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTypeParameterBuilderSetCustomAttribute.cs b/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTypeParameterBuilderSetCustomAttribute.cs index e177c08dab26a9..aea595e0761c68 100644 --- a/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTypeParameterBuilderSetCustomAttribute.cs +++ b/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTypeParameterBuilderSetCustomAttribute.cs @@ -29,17 +29,6 @@ public void SetCustomAttribute_ConstructorInfo_ByteArray_NullAttributeConstructo AssertExtensions.Throws("con", () => typeParams[0].SetCustomAttribute(null, new byte[128])); } - [Fact] - public void SetCustomAttribute_ConstructorInfo_ByteArray_NullBinaryAttribute_ThrowsArgumentNullException() - { - TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public); - string[] typeParamNames = new string[] { "TFirst" }; - GenericTypeParameterBuilder[] typeParams = type.DefineGenericParameters(typeParamNames); - ConstructorInfo attributeConstructor = typeof(HelperAttribute).GetConstructor(new Type[0]); - - AssertExtensions.Throws("binaryAttribute", () => typeParams[0].SetCustomAttribute(attributeConstructor, null)); - } - [Fact] public void SetCustomAttribute_CustomAttributeBuilder() { diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs new file mode 100644 index 00000000000000..79b9e77bfdf140 --- /dev/null +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs @@ -0,0 +1,462 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using Xunit; + +namespace System.Reflection.Emit.Tests +{ + [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public class AssemblySaveCustomAttributeTests + { + private List _attributes = new List + { + new CustomAttributeBuilder(s_comVisiblePair.con, s_comVisiblePair.args), + new CustomAttributeBuilder(s_guidPair.con, s_guidPair.args) + }; + + private static readonly Type s_comVisibleType = typeof(ComVisibleAttribute); + private static readonly Type s_guideType = typeof(GuidAttribute); + private static readonly (ConstructorInfo con, object[] args) s_comVisiblePair = (s_comVisibleType.GetConstructor(new Type[] { typeof(bool) }), new object[] { true }); + private static readonly (ConstructorInfo con, object[] args) s_guidPair = (s_guideType.GetConstructor(new Type[] { typeof(string) }), new object[] { "9ED54F84-A89D-4fcd-A854-44251E925F09" }); + + private static AssemblyName PopulateAssemblyName() + { + AssemblyName assemblyName = new AssemblyName("MyDynamicAssembly"); + assemblyName.Version = new Version("7.0.0.0"); + assemblyName.CultureInfo = Globalization.CultureInfo.InvariantCulture; + return assemblyName; + } + + [Fact] + public void AssemblyModuleWithCustomAttributes() + { + AssemblyName assemblyName = PopulateAssemblyName(); + + using (TempFile file = TempFile.Create()) + { + WriteAssemblyToDisk(assemblyName, Type.EmptyTypes, file.Path, _attributes, _attributes); + + Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); + Module moduleFromDisk = assemblyFromDisk.Modules.First(); + + AssemblyTools.AssertAssemblyNameAndModule(assemblyName, assemblyFromDisk.GetName(), moduleFromDisk); + ValidateAttributes(assemblyFromDisk.GetCustomAttributesData()); + ValidateAttributes(moduleFromDisk.GetCustomAttributesData()); + } + } + + [Fact] + public void MethodFieldWithCustomAttributes() + { + Type[] types = new Type[] { typeof(IMultipleMethod), typeof(IOneMethod), typeof(StructWithFields) }; + + using (TempFile file = TempFile.Create()) + { + WriteAssemblyToDisk(PopulateAssemblyName(), types, file.Path, typeAttributes: _attributes, + methodAttributes: _attributes, fieldAttributes: _attributes); + + Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); + + Module moduleFromDisk = assemblyFromDisk.Modules.First(); + Type[] typesFromDisk = moduleFromDisk.GetTypes(); + + Assert.Equal(types.Length, typesFromDisk.Length); + + for (int i = 0; i < types.Length; i++) + { + Type typeFromDisk = typesFromDisk[i]; + Type sourceType = types[i]; + MethodInfo[] methodsFromDisk = typeFromDisk.IsValueType ? typeFromDisk.GetMethods(BindingFlags.DeclaredOnly) : typeFromDisk.GetMethods(); + FieldInfo[] fieldsFromDisk = typeFromDisk.GetFields(); + + AssemblyTools.AssertTypeProperties(sourceType, typeFromDisk); + AssemblyTools.AssertMethods(sourceType.IsValueType ? sourceType.GetMethods(BindingFlags.DeclaredOnly) : sourceType.GetMethods(), methodsFromDisk); + AssemblyTools.AssertFields(sourceType.GetFields(), fieldsFromDisk); + ValidateAttributes(typeFromDisk.GetCustomAttributesData()); + + for (int j = 0; j < methodsFromDisk.Length; j++) + { + ValidateAttributes(methodsFromDisk[j].GetCustomAttributesData()); + } + + for (int j = 0; j < fieldsFromDisk.Length; j++) + { + ValidateAttributes(fieldsFromDisk[j].GetCustomAttributesData()); + } + } + } + } + + private void ValidateAttributes(IList attributesFromDisk) + { + Assert.Equal(_attributes.Count, attributesFromDisk.Count); + + foreach (var attribute in attributesFromDisk) + { + if (attribute.AttributeType.Name == s_comVisibleType.Name) + { + Assert.Equal(s_comVisiblePair.con.MetadataToken, attribute.Constructor.MetadataToken); + Assert.Equal(s_comVisiblePair.args[0].GetType().FullName, attribute.ConstructorArguments[0].ArgumentType.FullName); + Assert.Equal(true, attribute.ConstructorArguments[0].Value); + } + else + { + Assert.Equal(s_guidPair.con.MetadataToken, attribute.Constructor.MetadataToken); + Assert.Equal(s_guidPair.args[0].GetType().FullName, attribute.ConstructorArguments[0].ArgumentType.FullName); + Assert.Equal(attribute.AttributeType.Name, s_guideType.Name); + Assert.Equal(s_guidPair.args[0], attribute.ConstructorArguments[0].Value); + } + } + } + + private static void WriteAssemblyToDisk(AssemblyName assemblyName, Type[] types, string fileLocation, List? assemblyAttributes = null, + List? moduleAttributes = null, List? typeAttributes = null, + List? methodAttributes = null, List? fieldAttributes = null) + { + AssemblyBuilder assemblyBuilder = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod(assemblyName, assemblyAttributes, typeof(string), out MethodInfo saveMethod); + ModuleBuilder mb = assemblyBuilder.DefineDynamicModule(assemblyName.Name); + PopulateMembersForModule(mb, types, moduleAttributes, typeAttributes, methodAttributes, fieldAttributes); + saveMethod.Invoke(assemblyBuilder, new object[] { fileLocation }); + } + + private static void PopulateMembersForModule(ModuleBuilder mb, Type[] types, List? moduleAttributes, + List? typeAttributes, List? methodAttributes, List? fieldAttributes) + { + if (moduleAttributes != null) + { + moduleAttributes.ForEach(mb.SetCustomAttribute); + } + + foreach (Type type in types) + { + TypeBuilder tb = mb.DefineType(type.FullName, type.Attributes, type.BaseType); + typeAttributes.ForEach(tb.SetCustomAttribute); + + DefineMethodsAndSetAttributes(methodAttributes, tb, type.IsInterface ? type.GetMethods() : type.GetMethods(BindingFlags.DeclaredOnly), methodAttributes); + DefineFieldsAndSetAttributes(fieldAttributes, type.GetFields(), tb); + } + } + + private static void DefineFieldsAndSetAttributes(List? fieldAttributes, FieldInfo[] fields, TypeBuilder tb) + { + foreach (FieldInfo field in fields) + { + FieldBuilder fb = tb.DefineField(field.Name, field.FieldType, field.Attributes); + fieldAttributes.ForEach(fb.SetCustomAttribute); + } + } + + private static void DefineMethodsAndSetAttributes(List methodAttributes, TypeBuilder tb, MethodInfo[] methods, List paramAttributes) + { + foreach (var method in methods) + { + ParameterInfo[] parameters = method.GetParameters(); + MethodBuilder meb = tb.DefineMethod(method.Name, method.Attributes, method.CallingConvention, method.ReturnType, parameters.Select(p => p.ParameterType).ToArray()); + methodAttributes.ForEach(meb.SetCustomAttribute); + + foreach (ParameterInfo param in parameters) + { + ParameterBuilder pb = meb.DefineParameter(param.Position + 1, param.Attributes, param.Name); + paramAttributes.ForEach(pb.SetCustomAttribute); + if (param.ParameterType.Equals(typeof(string))) + { + pb.SetConstant("Hello"); + } + } + } + } + + [Fact] + public void CreateStructWithPseudoCustomAttributesTest() + { + using (TempFile file = TempFile.Create()) + { + Type type = typeof(StructWithFields); + List typeAttributes = new() { new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(typeof(StructLayoutAttribute).GetConstructor(new Type[] { typeof(LayoutKind) }), new object[] { LayoutKind.Explicit }, + typeof(StructLayoutAttribute).GetFields() , new object[]{32, 64, CharSet.Unicode}), + new CustomAttributeBuilder(s_guidPair.con, s_guidPair.args), + new CustomAttributeBuilder(typeof(SpecialNameAttribute).GetConstructor(Type.EmptyTypes), new object[] { }) + }; + CustomAttributeBuilder[] fieldAttributes = new[] { new CustomAttributeBuilder(typeof(NonSerializedAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(typeof(FieldOffsetAttribute).GetConstructor(new Type[] { typeof(int) }), new object[] { 2 }), + new CustomAttributeBuilder(s_guidPair.con, s_guidPair.args), + new CustomAttributeBuilder(typeof(MarshalAsAttribute).GetConstructor(new Type[] { typeof(UnmanagedType) }), new object[] { UnmanagedType.I4}), + new CustomAttributeBuilder(typeof(SpecialNameAttribute).GetConstructor(Type.EmptyTypes), new object[] { }) + }; + + AssemblyBuilder ab = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod( + PopulateAssemblyName(), null, typeof(string), out MethodInfo saveMethod); + TypeBuilder tb = ab.DefineDynamicModule("Module").DefineType(type.FullName, type.Attributes, type.BaseType); + DefineFieldsAndSetAttributes(fieldAttributes.ToList(), type.GetFields(), tb); + typeAttributes.ForEach(tb.SetCustomAttribute); + saveMethod.Invoke(ab, new object[] { file.Path }); + + Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); + Module moduleFromDisk = assemblyFromDisk.Modules.First(); + Type testType = moduleFromDisk.GetTypes()[0]; + IList attributesFromDisk = testType.GetCustomAttributesData(); + + Assert.Equal(typeAttributes.Count - 3, attributesFromDisk.Count); // 3 pseudo attributes + Assert.True((testType.Attributes & TypeAttributes.Serializable) != 0); // SerializableAttribute + Assert.True((testType.Attributes & TypeAttributes.SpecialName) != 0); // SpecialNameAttribute + Assert.True((testType.Attributes & TypeAttributes.ExplicitLayout) != 0); // StructLayoutAttribute + Assert.True((testType.Attributes & TypeAttributes.UnicodeClass) != 0); // StructLayoutAttribute, not sure if we could test the PackingSize and Size + + for (int i = 0; i < attributesFromDisk.Count; i++) + { + switch (attributesFromDisk[i].AttributeType.Name) + { + case "GuidAttribute": + Assert.Equal(s_guidPair.args[0], attributesFromDisk[i].ConstructorArguments[0].Value); + break; + default: + Assert.Fail($"Not expected attribute : {attributesFromDisk[i].AttributeType.Name}"); + break; + } + } + + FieldInfo field = testType.GetFields()[0]; + IList fieldAttributesFromDisk = field.GetCustomAttributesData(); + + Assert.Equal(3, fieldAttributesFromDisk.Count); + Assert.True((field.Attributes & FieldAttributes.NotSerialized) != 0); // NonSerializedAttribute + Assert.True((field.Attributes & FieldAttributes.SpecialName) != 0); // SpecialNameAttribute + Assert.True((field.Attributes & FieldAttributes.HasFieldMarshal) != 0); // MarshalAsAttribute + + for (int i = 0; i < fieldAttributesFromDisk.Count; i++) + { + switch (fieldAttributesFromDisk[i].AttributeType.Name) + { + case "FieldOffsetAttribute": + Assert.Equal(2, fieldAttributesFromDisk[i].ConstructorArguments[0].Value); + break; + case "MarshalAsAttribute": + Assert.Equal(UnmanagedType.I4, (UnmanagedType)fieldAttributesFromDisk[i].ConstructorArguments[0].Value); + break; + case "GuidAttribute": + Assert.Equal(s_guidPair.args[0], fieldAttributesFromDisk[i].ConstructorArguments[0].Value); + break; + default: + Assert.Fail($"Not expected attribute : {fieldAttributesFromDisk[i].AttributeType.Name}"); + break; + } + } + } + } + + [Fact] + public void InterfacesWithPseudoCustomAttributes() + { + using (TempFile file = TempFile.Create()) + { + Type dllType = typeof(DllImportAttribute); + Type type = typeof(IMultipleMethod); + List typeAttributes = new() { + new CustomAttributeBuilder(typeof(ComImportAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(typeof(SuppressUnmanagedCodeSecurityAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(s_guidPair.con, s_guidPair.args)}; + List methodAttributes = new() { + new CustomAttributeBuilder(typeof(PreserveSigAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(typeof(SuppressUnmanagedCodeSecurityAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(typeof(SpecialNameAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(s_guidPair.con, s_guidPair.args), + new CustomAttributeBuilder(typeof(MethodImplAttribute).GetConstructor(new Type[] { typeof(MethodImplOptions) }), + new object[] { MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization }), + new CustomAttributeBuilder(dllType.GetConstructor(new Type[] { typeof(string) }), new object[] { "test.dll" }, new FieldInfo[] + { dllType.GetField("CharSet"), dllType.GetField("SetLastError"), dllType.GetField("CallingConvention"), dllType.GetField("BestFitMapping"), + dllType.GetField("ThrowOnUnmappableChar") }, new object[]{ CharSet.Ansi, true, CallingConvention.FastCall, true, false })}; + List parameterAttributes = new() { + new CustomAttributeBuilder(typeof(InAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(typeof(OutAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(typeof(OptionalAttribute).GetConstructor(Type.EmptyTypes), new object[] { }), + new CustomAttributeBuilder(s_guidPair.con, s_guidPair.args), + new CustomAttributeBuilder(marshalAsEnumCtor, new object[] { UnmanagedType.CustomMarshaler }, + new FieldInfo[] { typeof(MarshalAsAttribute).GetField("MarshalType")}, new object[] { typeof(EmptyTestClass).AssemblyQualifiedName })}; + + AssemblyBuilder ab = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod(PopulateAssemblyName(), null, typeof(string), out MethodInfo saveMethod); + TypeBuilder tb = ab.DefineDynamicModule("Module").DefineType(type.FullName, type.Attributes); + typeAttributes.ForEach(tb.SetCustomAttribute); + DefineMethodsAndSetAttributes(methodAttributes, tb, type.GetMethods(), parameterAttributes); + saveMethod.Invoke(ab, new object[] { file.Path }); + + Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); + Type testType = assemblyFromDisk.Modules.First().GetTypes()[0]; + IList attributesFromDisk = testType.GetCustomAttributesData(); + + Assert.Equal(typeAttributes.Count, attributesFromDisk.Count); + Assert.True((testType.Attributes & TypeAttributes.Import) != 0); // ComImportAttribute + Assert.True((testType.Attributes & TypeAttributes.HasSecurity) != 0); // SuppressUnmanagedCodeSecurityAttribute + for (int i = 0; i < attributesFromDisk.Count; i++) + { + switch (attributesFromDisk[i].AttributeType.Name) + { + case "ComImportAttribute": // just making sure that these attributes are expected + case "SuppressUnmanagedCodeSecurityAttribute": + break; + case "GuidAttribute": + Assert.Equal(s_guidPair.args[0], attributesFromDisk[i].ConstructorArguments[0].Value); + break; + default: + Assert.Fail($"Not expected attribute : {attributesFromDisk[i].AttributeType.Name}"); + break; + } + } + + foreach (var method in testType.GetMethods()) + { + IList methodAttributesFromDisk = method.GetCustomAttributesData(); + + Assert.True((method.Attributes & MethodAttributes.HasSecurity) != 0); // SuppressUnmanagedCodeSecurityAttribute + Assert.True((method.Attributes & MethodAttributes.SpecialName) != 0); // SpecialNameAttribute + MethodImplAttributes methodImpl = method.GetMethodImplementationFlags(); + Assert.True((methodImpl & MethodImplAttributes.NoInlining) != 0); // MethodImplAttribute + Assert.True((methodImpl & MethodImplAttributes.AggressiveOptimization) != 0); // MethodImplAttribute + Assert.True((methodImpl & MethodImplAttributes.PreserveSig) != 0); // PreserveSigAttribute + Assert.Equal(methodAttributes.Count - 2, methodAttributesFromDisk.Count); + + for (int i = 0; i < methodAttributesFromDisk.Count; i++) + { + switch (methodAttributesFromDisk[i].AttributeType.Name) + { + case "SuppressUnmanagedCodeSecurityAttribute": + case "PreserveSigAttribute": + break; + case "GuidAttribute": + Assert.Equal(s_guidPair.args[0], methodAttributesFromDisk[i].ConstructorArguments[0].Value); + break; + case "DllImportAttribute": + { + CustomAttributeData attribute = methodAttributesFromDisk[i]; + Assert.Equal("test.dll", attribute.ConstructorArguments[0].Value); + + for (int j = 0; j < attribute.NamedArguments.Count; j++) + { + switch (attribute.NamedArguments[j].MemberName) + { + case "CharSet": + Assert.Equal(CharSet.Ansi, (CharSet)attribute.NamedArguments[j].TypedValue.Value); + break; + case "SetLastError": + Assert.True((bool)attribute.NamedArguments[j].TypedValue.Value); + break; + case "CallingConvention": + Assert.Equal(CallingConvention.FastCall, (CallingConvention)attribute.NamedArguments[j].TypedValue.Value); + break; + case "BestFitMapping": + Assert.True((bool)attribute.NamedArguments[j].TypedValue.Value); + break; + case "ThrowOnUnmappableChar": + Assert.False((bool)attribute.NamedArguments[j].TypedValue.Value); + break; + } + } + } + break; + default: + Assert.Fail($"Not expected attribute : {methodAttributesFromDisk[i].AttributeType.Name}"); + break; + } + } + + foreach(ParameterInfo param in method.GetParameters()) + { + IList paramAttributes = param.GetCustomAttributesData(); + + Assert.Equal(5, paramAttributes.Count); + Assert.True((param.Attributes & ParameterAttributes.In) != 0); // InAttribute + Assert.True((param.Attributes & ParameterAttributes.Out) != 0); // OutAttribute + Assert.True((param.Attributes & ParameterAttributes.Optional) != 0); // OptionalAttribute + Assert.True((param.Attributes & ParameterAttributes.HasFieldMarshal) != 0); // MarshalAsAttribute + + if (param.ParameterType.Equals(typeof(string))) + { + Assert.Equal("Hello", param.DefaultValue); + } + + for (int i = 0; i < paramAttributes.Count; i++) + { + switch (paramAttributes[i].AttributeType.Name) + { + case "InAttribute": + case "OutAttribute": + case "OptionalAttribute": + break; + case "MarshalAsAttribute": + Assert.Equal(UnmanagedType.CustomMarshaler, (UnmanagedType)paramAttributes[i].ConstructorArguments[0].Value); + Assert.Equal(typeof(EmptyTestClass).AssemblyQualifiedName, + paramAttributes[i].NamedArguments.First(na => na.MemberName == "MarshalType").TypedValue.Value); + break; + case "GuidAttribute": + Assert.Equal(s_guidPair.args[0], paramAttributes[i].ConstructorArguments[0].Value); + break; + default: + Assert.Fail($"Not expected attribute : {paramAttributes[i].AttributeType.Name}"); + break; + } + } + } + } + } + } + + private static readonly ConstructorInfo marshalAsEnumCtor = typeof(MarshalAsAttribute).GetConstructor(new Type[] { typeof(UnmanagedType) }); + private static readonly ConstructorInfo marshalAsShortCtor = typeof(MarshalAsAttribute).GetConstructor(new Type[] { typeof(short) }); + + public static IEnumerable MarshalAsAttributeWithVariousFields() + { + yield return new object[] { new CustomAttributeBuilder(marshalAsEnumCtor, new object[] { UnmanagedType.LPStr }), UnmanagedType.LPStr }; + yield return new object[] { new CustomAttributeBuilder(marshalAsShortCtor, new object[] { (short)21 }), UnmanagedType.LPWStr }; + yield return new object[] { new CustomAttributeBuilder(marshalAsShortCtor, new object[] { (short)19 }), UnmanagedType.BStr }; + yield return new object[] { new CustomAttributeBuilder(marshalAsEnumCtor, new object[] { UnmanagedType.ByValTStr }, + new FieldInfo[] { typeof(MarshalAsAttribute).GetField("SizeConst") }, new object[] { 256 }) , UnmanagedType.ByValTStr }; + yield return new object[] { new CustomAttributeBuilder(marshalAsEnumCtor, new object[] { UnmanagedType.CustomMarshaler }, + new FieldInfo[] { typeof(MarshalAsAttribute).GetField("MarshalType"), typeof(MarshalAsAttribute).GetField("MarshalCookie") }, + new object[] { typeof(EmptyTestClass).AssemblyQualifiedName, "MyCookie" }) , UnmanagedType.CustomMarshaler }; + // TODO: When array support added add test for LPArray/ByValArray/SafeArray + } + + [Theory] + [MemberData(nameof(MarshalAsAttributeWithVariousFields))] + public void MarshalAsPseudoCustomAttributesTest(CustomAttributeBuilder attribute, UnmanagedType expectedType) + { + using (TempFile file = TempFile.Create()) + { + Type type = typeof(StructWithFields); + AssemblyBuilder ab = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod( + PopulateAssemblyName(), null, typeof(string), out MethodInfo saveMethod); + TypeBuilder tb = ab.DefineDynamicModule("Module").DefineType(type.FullName, type.Attributes, type.BaseType); + FieldInfo stringField = type.GetFields()[1]; + FieldBuilder fb = tb.DefineField(stringField.Name, stringField.FieldType, stringField.Attributes); + fb.SetCustomAttribute(attribute); + saveMethod.Invoke(ab, new object[] { file.Path }); + + Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); + FieldInfo field = assemblyFromDisk.Modules.First().GetTypes()[0].GetFields()[0]; + CustomAttributeData attributeFromDisk = field.GetCustomAttributesData()[0]; + + Assert.Equal(1, field.GetCustomAttributesData().Count); + Assert.True((field.Attributes & FieldAttributes.HasFieldMarshal) != 0); + Assert.Equal(expectedType, (UnmanagedType)attributeFromDisk.ConstructorArguments[0].Value); + + switch (expectedType) + { + case UnmanagedType.CustomMarshaler: + Assert.Equal(typeof(EmptyTestClass).AssemblyQualifiedName, + attributeFromDisk.NamedArguments.First(na => na.MemberName == "MarshalType").TypedValue.Value); + Assert.Equal("MyCookie", attributeFromDisk.NamedArguments.First(na => na.MemberName == "MarshalCookie").TypedValue.Value); + break; + case UnmanagedType.ByValTStr: + Assert.Equal(256, attributeFromDisk.NamedArguments.First(na => na.MemberName == "SizeConst").TypedValue.Value); + break; + } + } + } + } +} diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveWithVariousMembersTests.cs similarity index 56% rename from src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs rename to src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveWithVariousMembersTests.cs index c459a9be15a56c..7307ebd0cdf225 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveWithVariousMembersTests.cs @@ -1,15 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using Xunit; namespace System.Reflection.Emit.Tests { [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] - public class AssemblySaveTestsWithVariousTypes + public class AssemblySaveWithVariousMembersTests { private static readonly AssemblyName s_assemblyName = new AssemblyName("MyDynamicAssembly") { @@ -25,23 +28,9 @@ public void EmptyAssemblyAndModuleTest() using (TempFile file = TempFile.Create()) { Assembly assemblyFromDisk = WriteAndLoadAssembly(Type.EmptyTypes, file.Path); - AssemblyName aNameFromDisk = assemblyFromDisk.GetName(); - - // Test AssemblyName properties - Assert.Equal(s_assemblyName.Name, aNameFromDisk.Name); - Assert.Equal(s_assemblyName.Version, aNameFromDisk.Version); - Assert.Equal(s_assemblyName.CultureInfo, aNameFromDisk.CultureInfo); - Assert.Equal(s_assemblyName.CultureName, aNameFromDisk.CultureName); - Assert.Equal(s_assemblyName.ContentType, aNameFromDisk.ContentType); - // Runtime assemblies adding AssemblyNameFlags.PublicKey in Assembly.GetName() overloads - Assert.Equal(s_assemblyName.Flags | AssemblyNameFlags.PublicKey, aNameFromDisk.Flags); - Assert.Empty(assemblyFromDisk.GetTypes()); - - Module moduleFromDisk = assemblyFromDisk.Modules.FirstOrDefault(); - Assert.NotNull(moduleFromDisk); - Assert.Equal(s_assemblyName.Name, moduleFromDisk.ScopeName); - Assert.Empty(moduleFromDisk.GetTypes()); + Assert.Empty(assemblyFromDisk.GetTypes()); + AssemblyTools.AssertAssemblyNameAndModule(s_assemblyName, assemblyFromDisk.GetName(), assemblyFromDisk.Modules.FirstOrDefault()); } } @@ -56,14 +45,13 @@ public static IEnumerable VariousInterfacesStructsTestData() { yield return new object[] { new Type[] { typeof(INoMethod) } }; yield return new object[] { new Type[] { typeof(IMultipleMethod) } }; - yield return new object[] { new Type[] { typeof(INoMethod), typeof(INoMethod2) } }; yield return new object[] { new Type[] { typeof(INoMethod), typeof(IOneMethod) } }; - yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(INoMethod2) } }; - yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(INoMethod2), typeof(IAccess), typeof(IOneMethod), typeof(INoMethod) } }; + yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(EmptyTestClass) } }; + yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(EmptyTestClass), typeof(IAccess), typeof(IOneMethod), typeof(INoMethod) } }; yield return new object[] { new Type[] { typeof(EmptyStruct) } }; - yield return new object[] { new Type[] { typeof(StructWithField) } }; - yield return new object[] { new Type[] { typeof(StructWithField), typeof(EmptyStruct) } }; - yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(EmptyStruct), typeof(INoMethod2), typeof(StructWithField) } }; + yield return new object[] { new Type[] { typeof(StructWithFields) } }; + yield return new object[] { new Type[] { typeof(StructWithFields), typeof(EmptyStruct) } }; + yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(StructWithFields), typeof(ClassWithFields), typeof(EmptyTestClass) } }; } [Theory] @@ -87,51 +75,12 @@ private static void AssertTypesAndTypeMembers(Type[] types, Type[] typesFromDisk Type sourceType = types[i]; Type typeFromDisk = typesFromDisk[i]; - AssertTypeProperties(sourceType, typeFromDisk); - AssertMethods(sourceType.GetMethods(), typeFromDisk.GetMethods()); - AssertFields(sourceType.GetFields(), typeFromDisk.GetFields()); - } - } - - private static void AssertFields(FieldInfo[] declaredFields, FieldInfo[] fieldsFromDisk) - { - Assert.Equal(declaredFields.Length, fieldsFromDisk.Length); - - for (int j = 0; j < declaredFields.Length; j++) - { - FieldInfo sourceField = declaredFields[j]; - FieldInfo fieldFromDisk = fieldsFromDisk[j]; - - Assert.Equal(sourceField.Name, fieldFromDisk.Name); - Assert.Equal(sourceField.Attributes, fieldFromDisk.Attributes); - Assert.Equal(sourceField.FieldType.FullName, fieldFromDisk.FieldType.FullName); - } - } - - private static void AssertMethods(MethodInfo[] sourceMethods, MethodInfo[] methodsFromDisk) - { - Assert.Equal(sourceMethods.Length, methodsFromDisk.Length); - - for (int j = 0; j < sourceMethods.Length; j++) - { - MethodInfo sourceMethod = sourceMethods[j]; - MethodInfo methodFromDisk = methodsFromDisk[j]; - - Assert.Equal(sourceMethod.Name, methodFromDisk.Name); - Assert.Equal(sourceMethod.Attributes, methodFromDisk.Attributes); - Assert.Equal(sourceMethod.ReturnType.FullName, methodFromDisk.ReturnType.FullName); + AssemblyTools.AssertTypeProperties(sourceType, typeFromDisk); + AssemblyTools.AssertMethods(sourceType.GetMethods(), typeFromDisk.GetMethods()); + AssemblyTools.AssertFields(sourceType.GetFields(), typeFromDisk.GetFields()); } } - private static void AssertTypeProperties(Type sourceType, Type typeFromDisk) - { - Assert.Equal(sourceType.Name, typeFromDisk.Name); - Assert.Equal(sourceType.Namespace, typeFromDisk.Namespace); - Assert.Equal(sourceType.Attributes, typeFromDisk.Attributes); - Assert.Equal(sourceType.IsInterface, typeFromDisk.IsInterface); - Assert.Equal(sourceType.IsValueType, typeFromDisk.IsValueType); - } - [Theory] [MemberData(nameof(VariousInterfacesStructsTestData))] public void WriteAssemblyWithVariousTypesToStreamAndReadBackTest(Type[] types) @@ -150,9 +99,8 @@ public void CreateMembersThatUsesTypeLoadedFromCoreAssemblyTest() { using (TempFile file = TempFile.Create()) { - MethodInfo defineDynamicAssemblyMethod = AssemblyTools.PopulateMethods(typeof(string), out MethodInfo saveMethod); - AssemblyBuilder assemblyBuilder = (AssemblyBuilder)defineDynamicAssemblyMethod.Invoke(null, - new object[] { s_assemblyName, typeof(object).Assembly, null }); + AssemblyBuilder assemblyBuilder = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod( + s_assemblyName, null, typeof(string), out MethodInfo saveMethod); ModuleBuilder mb = assemblyBuilder.DefineDynamicModule("My Module"); TypeBuilder tb = mb.DefineType("TestInterface", TypeAttributes.Interface | TypeAttributes.Abstract); @@ -175,42 +123,79 @@ public void CreateMembersThatUsesTypeLoadedFromCoreAssemblyTest() Assert.Equal("System.Void", method.ReturnType.FullName); } } - } - // Test Interfaces - public interface INoMethod - { + [Fact] + public void AddInterfaceImplementationTest() + { + using (TempFile file = TempFile.Create()) + { + AssemblyBuilder assemblyBuilder = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod( + s_assemblyName, null, typeof(string), out MethodInfo saveMethod); + + ModuleBuilder mb = assemblyBuilder.DefineDynamicModule("My Module"); + TypeBuilder tb = mb.DefineType("TestInterface", TypeAttributes.Interface | TypeAttributes.Abstract, null, new Type[] { typeof(IOneMethod)}); + tb.AddInterfaceImplementation(typeof(INoMethod)); + tb.DefineNestedType("NestedType", TypeAttributes.Interface | TypeAttributes.Abstract); + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); + Type testType = assemblyFromDisk.Modules.First().GetTypes()[0]; + Type[] interfaces = testType.GetInterfaces(); + + Assert.Equal("TestInterface", testType.Name); + Assert.Equal(2, interfaces.Length); + + Type iOneMethod = testType.GetInterface("IOneMethod"); + Type iNoMethod = testType.GetInterface("INoMethod"); + Type[] nt = testType.GetNestedTypes(); + Assert.Equal(1, iOneMethod.GetMethods().Length); + Assert.Empty(iNoMethod.GetMethods()); + Assert.NotNull(testType.GetNestedType("NestedType", BindingFlags.NonPublic)); + } + } } - public interface INoMethod2 + // Test Types + public interface INoMethod { } public interface IMultipleMethod { - string Func(); - bool MoreFunc(); - double DoIExist(); + string Func(int a, string b); + IOneMethod MoreFunc(); + StructWithFields DoIExist(int a, string b, bool c); void BuildAPerpetualMotionMachine(); } internal interface IAccess { - public int BuildAI(); + public Version BuildAI(double field); public int DisableRogueAI(); } public interface IOneMethod { - string Func(); + object Func(string a, short b); } public struct EmptyStruct { } - public struct StructWithField + public struct StructWithFields + { + public int field1; + public string field2; + } + + public class EmptyTestClass + { + } + + public class ClassWithFields : EmptyTestClass { - public int field; + public EmptyTestClass field1; + public byte field2; } } diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs index 16d16ff84d7ec4..4ec230e52bc8b1 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using System.Runtime.InteropServices; +using Xunit; namespace System.Reflection.Emit.Tests { @@ -11,23 +13,16 @@ internal static class AssemblyTools { internal static void WriteAssemblyToDisk(AssemblyName assemblyName, Type[] types, string fileLocation) { - WriteAssemblyToDisk(assemblyName, types, fileLocation, null); - } - - internal static void WriteAssemblyToDisk(AssemblyName assemblyName, Type[] types, string fileLocation, List assemblyAttributes) - { - MethodInfo defineDynamicAssemblyMethod = PopulateMethods(typeof(string), out MethodInfo saveMethod); + AssemblyBuilder assemblyBuilder = PopulateAssemblyBuilderAndSaveMethod( + assemblyName, null, typeof(string), out MethodInfo saveMethod); - AssemblyBuilder assemblyBuilder = (AssemblyBuilder)defineDynamicAssemblyMethod.Invoke(null, - new object[] { assemblyName, CoreMetadataAssemblyResolver.s_coreAssembly, assemblyAttributes }); ModuleBuilder mb = assemblyBuilder.DefineDynamicModule(assemblyName.Name); - - PopulateMembersForModule(types, mb); + PopulateMembersForModule(mb, types); saveMethod.Invoke(assemblyBuilder, new object[] { fileLocation }); } - private static void PopulateMembersForModule(Type[] types, ModuleBuilder mb) + private static void PopulateMembersForModule(ModuleBuilder mb, Type[] types) { foreach (Type type in types) { @@ -36,7 +31,12 @@ private static void PopulateMembersForModule(Type[] types, ModuleBuilder mb) MethodInfo[] methods = type.IsInterface ? type.GetMethods() : type.GetMethods(BindingFlags.DeclaredOnly); foreach (var method in methods) { - MethodBuilder meb = tb.DefineMethod(method.Name, method.Attributes, method.CallingConvention, method.ReturnType, null); + ParameterInfo[] parameters = method.GetParameters(); + MethodBuilder meb = tb.DefineMethod(method.Name, method.Attributes, method.CallingConvention, method.ReturnType, parameters.Select(p => p.ParameterType).ToArray()); + foreach(ParameterInfo param in parameters) + { + meb.DefineParameter(param.Position + 1, param.Attributes, param.Name); + } } foreach (FieldInfo field in type.GetFields()) @@ -48,33 +48,27 @@ private static void PopulateMembersForModule(Type[] types, ModuleBuilder mb) internal static void WriteAssemblyToStream(AssemblyName assemblyName, Type[] types, Stream stream) { - WriteAssemblyToStream(assemblyName, types, stream, null); - } - - internal static void WriteAssemblyToStream(AssemblyName assemblyName, Type[] types, Stream stream, List? assemblyAttributes) - { - MethodInfo defineDynamicAssemblyMethod = PopulateMethods(typeof(Stream), out MethodInfo saveMethod); - - AssemblyBuilder assemblyBuilder = (AssemblyBuilder)defineDynamicAssemblyMethod.Invoke(null, - new object[] { assemblyName, CoreMetadataAssemblyResolver.s_coreAssembly, assemblyAttributes }); + AssemblyBuilder assemblyBuilder = PopulateAssemblyBuilderAndSaveMethod( + assemblyName, null, typeof(Stream), out MethodInfo saveMethod); ModuleBuilder mb = assemblyBuilder.DefineDynamicModule(assemblyName.Name); - - PopulateMembersForModule(types, mb); + PopulateMembersForModule(mb, types); saveMethod.Invoke(assemblyBuilder, new object[] { stream }); } - internal static MethodInfo PopulateMethods(Type parameterType, out MethodInfo saveMethod) + internal static AssemblyBuilder PopulateAssemblyBuilderAndSaveMethod(AssemblyName assemblyName, + List? assemblyAttributes, Type parameterType, out MethodInfo saveMethod) { - Type assemblyType = Type.GetType( - "System.Reflection.Emit.AssemblyBuilderImpl, System.Reflection.Emit", - throwOnError: true)!; + Type assemblyType = Type.GetType("System.Reflection.Emit.AssemblyBuilderImpl, System.Reflection.Emit", throwOnError: true)!; saveMethod = assemblyType.GetMethod("Save", BindingFlags.NonPublic | BindingFlags.Instance, new Type[] { parameterType }); - return assemblyType.GetMethod("DefinePersistedAssembly", BindingFlags.NonPublic | BindingFlags.Static, + MethodInfo defineDynamicAssemblyMethod = assemblyType.GetMethod("DefinePersistedAssembly", BindingFlags.NonPublic | BindingFlags.Static, new Type[] { typeof(AssemblyName), typeof(Assembly), typeof(List) }); + + return (AssemblyBuilder)defineDynamicAssemblyMethod.Invoke(null, + new object[] { assemblyName, CoreMetadataAssemblyResolver.s_coreAssembly, assemblyAttributes }); } internal static Assembly LoadAssemblyFromPath(string filePath) => @@ -82,12 +76,81 @@ internal static Assembly LoadAssemblyFromPath(string filePath) => internal static Assembly LoadAssemblyFromStream(Stream stream) => new MetadataLoadContext(new CoreMetadataAssemblyResolver()).LoadFromStream(stream); + + internal static void AssertAssemblyNameAndModule(AssemblyName sourceAName, AssemblyName aNameFromDisk, Module moduleFromDisk) + { + // Runtime assemblies adding AssemblyNameFlags.PublicKey in Assembly.GetName() overloads + Assert.Equal(sourceAName.Flags | AssemblyNameFlags.PublicKey, aNameFromDisk.Flags); + Assert.Equal(sourceAName.Name, aNameFromDisk.Name); + Assert.Equal(sourceAName.Version, aNameFromDisk.Version); + Assert.Equal(sourceAName.CultureInfo, aNameFromDisk.CultureInfo); + Assert.Equal(sourceAName.CultureName, aNameFromDisk.CultureName); + Assert.Equal(sourceAName.ContentType, aNameFromDisk.ContentType); + + Assert.NotNull(moduleFromDisk); + Assert.Equal(sourceAName.Name, moduleFromDisk.ScopeName); + Assert.Empty(moduleFromDisk.GetTypes()); + } + + internal static void AssertTypeProperties(Type sourceType, Type typeFromDisk) + { + Assert.Equal(sourceType.Name, typeFromDisk.Name); + Assert.Equal(sourceType.Namespace, typeFromDisk.Namespace); + Assert.Equal(sourceType.Attributes, typeFromDisk.Attributes); + Assert.Equal(sourceType.IsInterface, typeFromDisk.IsInterface); + Assert.Equal(sourceType.IsValueType, typeFromDisk.IsValueType); + } + + internal static void AssertFields(FieldInfo[] declaredFields, FieldInfo[] fieldsFromDisk) + { + Assert.Equal(declaredFields.Length, fieldsFromDisk.Length); + + for (int j = 0; j < declaredFields.Length; j++) + { + FieldInfo sourceField = declaredFields[j]; + FieldInfo fieldFromDisk = fieldsFromDisk[j]; + + Assert.Equal(sourceField.Name, fieldFromDisk.Name); + Assert.Equal(sourceField.Attributes, fieldFromDisk.Attributes); + Assert.Equal(sourceField.FieldType.FullName, fieldFromDisk.FieldType.FullName); + } + } + + internal static void AssertMethods(MethodInfo[] sourceMethods, MethodInfo[] methodsFromDisk) + { + Assert.Equal(sourceMethods.Length, methodsFromDisk.Length); + + for (int j = 0; j < sourceMethods.Length; j++) + { + MethodInfo sourceMethod = sourceMethods[j]; + MethodInfo methodFromDisk = methodsFromDisk[j]; + + Assert.Equal(sourceMethod.Name, methodFromDisk.Name); + Assert.Equal(sourceMethod.Attributes, methodFromDisk.Attributes); + Assert.Equal(sourceMethod.ReturnType.FullName, methodFromDisk.ReturnType.FullName); + AssertParameters(sourceMethod.GetParameters(), methodFromDisk.GetParameters()); + } + } + + private static void AssertParameters(ParameterInfo[] sourceParameters, ParameterInfo[] parametersLoaded) + { + Assert.Equal(sourceParameters.Length, parametersLoaded.Length); + + for (int i = 0; i < sourceParameters.Length; i++) + { + Assert.Equal(sourceParameters[i].Name, parametersLoaded[i].Name); + Assert.Equal(sourceParameters[i].ParameterType.FullName, parametersLoaded[i].ParameterType.FullName); + Assert.Equal(sourceParameters[i].Attributes, parametersLoaded[i].Attributes); + Assert.Equal(sourceParameters[i].Position, parametersLoaded[i].Position); + } + } } // The resolver copied from MLC tests internal sealed class CoreMetadataAssemblyResolver : MetadataAssemblyResolver { public static Assembly s_coreAssembly = typeof(object).Assembly; + public static Assembly s_emitAssembly = typeof(AssemblyTools).Assembly; public CoreMetadataAssemblyResolver() { } public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName) @@ -109,12 +172,26 @@ public override Assembly Resolve(MetadataLoadContext context, AssemblyName assem return _coreAssembly; } + if (name.Equals("System.Reflection.Emit.Tests", StringComparison.OrdinalIgnoreCase)) + { + if (_emitAssembly == null) + { + _emitAssembly = context.LoadFromStream(CreateStreamForEmitAssembly()); + } + + return _emitAssembly; + } + return null; } + private Assembly _emitAssembly; private Assembly _coreAssembly; - public static Stream CreateStreamForCoreAssembly() + private Stream CreateStreamForEmitAssembly() => + File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(s_emitAssembly)); + + private static Stream CreateStreamForCoreAssembly() { // We need a core assembly in IL form. Since this version of this code is for Jitted platforms, the System.Private.Corelib // of the underlying runtime will do just fine. diff --git a/src/libraries/System.Reflection.Emit/tests/System.Reflection.Emit.Tests.csproj b/src/libraries/System.Reflection.Emit/tests/System.Reflection.Emit.Tests.csproj index f10f0a08c4e4bc..f672dc37d9e828 100644 --- a/src/libraries/System.Reflection.Emit/tests/System.Reflection.Emit.Tests.csproj +++ b/src/libraries/System.Reflection.Emit/tests/System.Reflection.Emit.Tests.csproj @@ -62,7 +62,8 @@ - + + diff --git a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs index ee3400d6c3f79a..61314bfb7fd06c 100644 --- a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs +++ b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs @@ -3064,6 +3064,7 @@ public void Single() { } public void String() { } public System.Reflection.Metadata.Ecma335.SignatureTypeEncoder SZArray() { throw null; } public void Type(System.Reflection.Metadata.EntityHandle type, bool isValueType) { } + public void TypedReference() { } public void UInt16() { } public void UInt32() { } public void UInt64() { } diff --git a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj index ad67c99d457252..d241f17a26486d 100644 --- a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj +++ b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj @@ -110,7 +110,6 @@ The System.Reflection.Metadata library is built-in as part of the shared framewo - diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryProvider.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryProvider.cs index fae4a7196850cd..040baf783fa6eb 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryProvider.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryProvider.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Diagnostics; using System.IO; +using System.Runtime.InteropServices; using System.Threading; namespace System.Reflection.Internal @@ -45,7 +46,7 @@ internal unsafe byte* Pointer { if (_pinned == null) { - var newPinned = new PinnedObject(ImmutableByteArrayInterop.DangerousGetUnderlyingArray(_array)!); + var newPinned = new PinnedObject(ImmutableCollectionsMarshal.AsArray(_array)!); if (Interlocked.CompareExchange(ref _pinned, newPinned, null) != null) { diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableByteArrayInterop.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableByteArrayInterop.cs deleted file mode 100644 index 062133428d15d7..00000000000000 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableByteArrayInterop.cs +++ /dev/null @@ -1,80 +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.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; - -namespace System.Reflection.Internal -{ - /// - /// Provides tools for using in interop scenarios. - /// - /// - /// *** WARNING *** - /// - /// If you decide to copy this code elsewhere, please retain the documentation here - /// and the Dangerous prefixes in the API names. This will help track down and audit - /// other places where this technique (with dangerous consequences when misused) may - /// be applied. - /// - /// A generic version of this API was once public in a pre-release of immutable - /// collections, but it was deemed to be too subject to abuse when available publicly. - /// - /// This implementation is scoped to byte arrays as that is all that the metadata reader needs. - /// - /// Also, since we don't have access to immutable collection internals, we use - /// . - /// - /// The fact that is backed by a single byte array - /// field is something inherent to the design of ImmutableArray in order to get its performance - /// characteristics and therefore something we (Microsoft) are comfortable defining as a contract that - /// can be depended upon as below. - /// - internal static unsafe class ImmutableByteArrayInterop - { - /// - /// Creates a new instance of using a given mutable array as the backing - /// field, without creating a defensive copy. It is the responsibility of the caller to ensure no other mutable - /// references exist to the array. Do not mutate the array after calling this method. - /// - /// The mutable array to use as the backing field. The incoming reference is set to null - /// since it should not be retained by the caller. - /// - /// Users of this method should take extra care to ensure that the mutable array given as a parameter - /// is never modified. The returned will use the given array as its backing - /// field without creating a defensive copy, so changes made to the given mutable array will be observable - /// on the returned . Instance and static methods of - /// and may malfunction if they operate on an instance - /// whose underlying backing field is modified. - /// - /// An immutable array. - internal static ImmutableArray DangerousCreateFromUnderlyingArray(ref byte[]? array) - { - byte[] givenArray = array!; - array = null; - - return Unsafe.As>(ref givenArray); - } - - /// - /// Access the backing mutable array instance for the given , without - /// creating a defensive copy. It is the responsibility of the caller to ensure the array is not modified - /// through the returned mutable reference. Do not mutate the returned array. - /// - /// The from which to retrieve the backing field. - /// - /// Users of this method should take extra care to ensure that the returned mutable array is never modified. - /// The returned mutable array continues to be used as the backing field of the given - /// without creating a defensive copy, so changes made to the returned mutable array will be observable - /// on the given . Instance and static methods of - /// and may malfunction if they operate on an instance - /// whose underlying backing field is modified. - /// - /// The underlying array, or null if is true. - internal static byte[]? DangerousGetUnderlyingArray(ImmutableArray array) - { - return Unsafe.As, byte[]>(ref array); - } - } -} diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobBuilder.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobBuilder.cs index 98bda9ebddd8e7..9804b82cd45c7d 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobBuilder.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobBuilder.cs @@ -316,7 +316,7 @@ public ImmutableArray ToImmutableArray() public ImmutableArray ToImmutableArray(int start, int byteCount) { byte[]? array = ToArray(start, byteCount); - return ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref array); + return ImmutableCollectionsMarshal.AsImmutableArray(array); } internal bool TryGetSpan(out ReadOnlySpan buffer) diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs index 3b7041a9b373ca..3ed78ab777a1bc 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs @@ -885,10 +885,20 @@ public void Enum(string enumTypeName) } } + /// + /// Encodes a type in a signature. + /// public readonly struct SignatureTypeEncoder { + /// + /// The where the signature is written to. + /// public BlobBuilder Builder { get; } + /// + /// Creates a . + /// + /// The where the signature will be written. public SignatureTypeEncoder(BlobBuilder builder) { Builder = builder; @@ -904,27 +914,79 @@ private void ClassOrValue(bool isValueType) Builder.WriteByte(isValueType ? (byte)SignatureTypeKind.ValueType : (byte)SignatureTypeKind.Class); } + /// + /// Encodes . + /// public void Boolean() => WriteTypeCode(SignatureTypeCode.Boolean); + /// + /// Encodes . + /// public void Char() => WriteTypeCode(SignatureTypeCode.Char); + /// + /// Encodes . + /// public void SByte() => WriteTypeCode(SignatureTypeCode.SByte); + /// + /// Encodes . + /// public void Byte() => WriteTypeCode(SignatureTypeCode.Byte); + /// + /// Encodes . + /// public void Int16() => WriteTypeCode(SignatureTypeCode.Int16); + /// + /// Encodes . + /// public void UInt16() => WriteTypeCode(SignatureTypeCode.UInt16); + /// + /// Encodes . + /// public void Int32() => WriteTypeCode(SignatureTypeCode.Int32); + /// + /// Encodes . + /// public void UInt32() => WriteTypeCode(SignatureTypeCode.UInt32); + /// + /// Encodes . + /// public void Int64() => WriteTypeCode(SignatureTypeCode.Int64); + /// + /// Encodes . + /// public void UInt64() => WriteTypeCode(SignatureTypeCode.UInt64); + /// + /// Encodes . + /// public void Single() => WriteTypeCode(SignatureTypeCode.Single); + /// + /// Encodes . + /// public void Double() => WriteTypeCode(SignatureTypeCode.Double); + /// + /// Encodes . + /// public void String() => WriteTypeCode(SignatureTypeCode.String); + /// + /// Encodes . + /// + public void TypedReference() => WriteTypeCode(SignatureTypeCode.TypedReference); + /// + /// Encodes . + /// public void IntPtr() => WriteTypeCode(SignatureTypeCode.IntPtr); + /// + /// Encodes . + /// public void UIntPtr() => WriteTypeCode(SignatureTypeCode.UIntPtr); + /// + /// Encodes . + /// public void Object() => WriteTypeCode(SignatureTypeCode.Object); /// - /// Writes primitive type code. + /// Encodes a primitive type. /// - /// Any primitive type code except for and . + /// Any primitive type code except for . /// is not valid in this context. public void PrimitiveType(PrimitiveTypeCode type) { @@ -942,6 +1004,7 @@ public void PrimitiveType(PrimitiveTypeCode type) case PrimitiveTypeCode.UInt64: case PrimitiveTypeCode.Single: case PrimitiveTypeCode.Double: + case PrimitiveTypeCode.TypedReference: case PrimitiveTypeCode.IntPtr: case PrimitiveTypeCode.UIntPtr: case PrimitiveTypeCode.String: @@ -949,7 +1012,6 @@ public void PrimitiveType(PrimitiveTypeCode type) Builder.WriteByte((byte)type); return; - case PrimitiveTypeCode.TypedReference: case PrimitiveTypeCode.Void: default: Throw.ArgumentOutOfRange(nameof(type)); @@ -958,7 +1020,7 @@ public void PrimitiveType(PrimitiveTypeCode type) } /// - /// Encodes an array type. + /// Starts encoding an array type. /// Returns a pair of encoders that must be used in the order they appear in the parameter list. /// /// Use first, to encode the type of the element. @@ -1011,7 +1073,7 @@ public void Type(EntityHandle type, bool isValueType) } /// - /// Starts a function pointer signature. + /// Starts encoding a function pointer signature. /// /// Calling convention. /// Function pointer attributes. @@ -1051,7 +1113,7 @@ public MethodSignatureEncoder FunctionPointer( } /// - /// Starts a generic instantiation signature. + /// Starts encoding a generic instantiation signature. /// /// or . /// Generic argument count. @@ -1109,7 +1171,7 @@ public void GenericTypeParameter(int parameterIndex) } /// - /// Starts pointer signature. + /// Starts encoding a pointer signature. /// public SignatureTypeEncoder Pointer() { @@ -1127,7 +1189,7 @@ public void VoidPointer() } /// - /// Starts SZ array (vector) signature. + /// Starts encoding an SZ array (vector) signature. /// public SignatureTypeEncoder SZArray() { @@ -1136,7 +1198,7 @@ public SignatureTypeEncoder SZArray() } /// - /// Starts a signature of a type with custom modifiers. + /// Starts encoding a signature of a type with custom modifiers. /// public CustomModifiersEncoder CustomModifiers() { diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/IL/MethodBodyBlock.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/IL/MethodBodyBlock.cs index 6e12e43f2c09a3..6085b95d0f4b90 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/IL/MethodBodyBlock.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/IL/MethodBodyBlock.cs @@ -72,7 +72,7 @@ public ImmutableArray ExceptionRegions public ImmutableArray GetILContent() { byte[]? bytes = GetILBytes(); - return ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref bytes); + return ImmutableCollectionsMarshal.AsImmutableArray(bytes); } public BlobReader GetILReader() diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs index 89a221b3dcbdf0..a275a9b5a49242 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Reflection.Internal; using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; using System.Text; namespace System.Reflection.Metadata @@ -551,7 +552,7 @@ internal static void ReadStandalonePortablePdbStream(MemoryBlock pdbStreamBlock, externalTableRowCounts = ReadMetadataTableRowCounts(ref reader, externalTableMask); debugMetadataHeader = new DebugMetadataHeader( - ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref pdbId), + ImmutableCollectionsMarshal.AsImmutableArray(pdbId), MethodDefinitionHandle.FromRowId(entryPointRowId), idStartOffset: pdbStreamOffset); } @@ -1081,7 +1082,7 @@ public ImmutableArray GetBlobContent(BlobHandle handle) { // TODO: We can skip a copy for virtual blobs. byte[]? bytes = GetBlobBytes(handle); - return ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref bytes); + return ImmutableCollectionsMarshal.AsImmutableArray(bytes); } public BlobReader GetBlobReader(BlobHandle handle) diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs index d2e10832f1092f..042d9f984c64c7 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs @@ -7,6 +7,7 @@ using System.Reflection.Internal; using System.Reflection.Metadata; using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; using System.Threading; using ImmutableArrayExtensions = System.Linq.ImmutableArrayExtensions; @@ -659,7 +660,7 @@ internal static PdbChecksumDebugDirectoryData DecodePdbChecksumDebugDirectoryDat return new PdbChecksumDebugDirectoryData( algorithmName, - ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref checksum)); + ImmutableCollectionsMarshal.AsImmutableArray(checksum)); } /// diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/BlobEncodersTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/BlobEncodersTests.cs index 0377a9320824e8..6af6c5d90e7472 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/BlobEncodersTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/BlobEncodersTests.cs @@ -972,6 +972,10 @@ public void SignatureTypeEncoder_Primitives() AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); + e.TypedReference(); + AssertEx.Equal(new byte[] { 0x16 }, b.ToArray()); + b.Clear(); + e.IntPtr(); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); @@ -1044,6 +1048,10 @@ public void SignatureTypeEncoder_PrimitiveType() AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); + e.PrimitiveType(PrimitiveTypeCode.TypedReference); + AssertEx.Equal(new byte[] { 0x16 }, b.ToArray()); + b.Clear(); + e.PrimitiveType(PrimitiveTypeCode.IntPtr); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); @@ -1057,7 +1065,6 @@ public void SignatureTypeEncoder_PrimitiveType() b.Clear(); Assert.Throws(() => e.PrimitiveType(PrimitiveTypeCode.Void)); - Assert.Throws(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference)); Assert.Throws(() => e.PrimitiveType((PrimitiveTypeCode)255)); } diff --git a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj index c946c2e89667b0..f87afd2009b299 100644 --- a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj +++ b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj @@ -1,4 +1,5 @@ + true false @@ -9,6 +10,7 @@ true $(DefineConstants);TARGET_BROWSER + @@ -24,6 +26,7 @@ Link="Common\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" /> + @@ -87,10 +90,10 @@ - + @@ -136,16 +139,19 @@ + + - + + diff --git a/src/libraries/System.Reflection.Metadata/tests/TestUtilities/PinnedBlob.cs b/src/libraries/System.Reflection.Metadata/tests/TestUtilities/PinnedBlob.cs index 4fec831c604af4..6ac9f8bac6a2a9 100644 --- a/src/libraries/System.Reflection.Metadata/tests/TestUtilities/PinnedBlob.cs +++ b/src/libraries/System.Reflection.Metadata/tests/TestUtilities/PinnedBlob.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; -using System.Reflection.Internal; using System.Runtime.InteropServices; namespace System.Reflection.Metadata.Tests @@ -13,7 +12,7 @@ internal struct PinnedBlob : IDisposable private readonly byte[] _blob; public PinnedBlob(ImmutableArray blob) - : this(ImmutableByteArrayInterop.DangerousGetUnderlyingArray(blob)) + : this(ImmutableCollectionsMarshal.AsArray(blob)) { } diff --git a/src/libraries/System.Reflection.Metadata/tests/TestUtilities/SigningUtilities.cs b/src/libraries/System.Reflection.Metadata/tests/TestUtilities/SigningUtilities.cs index 2b0d573614c59f..4abac3e223eb90 100644 --- a/src/libraries/System.Reflection.Metadata/tests/TestUtilities/SigningUtilities.cs +++ b/src/libraries/System.Reflection.Metadata/tests/TestUtilities/SigningUtilities.cs @@ -29,20 +29,19 @@ public static byte[] CalculateRsaSignature(IEnumerable content, byte[] pri public static byte[] CalculateSha1(IEnumerable content) { - using (var hash = IncrementalHash.CreateHash(HashAlgorithmName.SHA1)) - { - var stream = new MemoryStream(); - - foreach (var blob in content) - { - var segment = blob.GetBytes(); + MemoryStream stream = new(); - stream.Write(segment.Array, segment.Offset, segment.Count); + foreach (Blob blob in content) + { + var segment = blob.GetBytes(); + stream.Write(segment.Array, segment.Offset, segment.Count); + } - hash.AppendData(segment.Array, segment.Offset, segment.Count); - } + stream.Position = 0; - return hash.GetHashAndReset(); + using (SHA1 sha1 = SHA1.Create()) + { + return sha1.ComputeHash(stream); } } diff --git a/src/libraries/System.Reflection.Metadata/tests/Utilities/ImmutableByteArrayInteropTest.cs b/src/libraries/System.Reflection.Metadata/tests/Utilities/ImmutableByteArrayInteropTest.cs deleted file mode 100644 index 63b360bd41469c..00000000000000 --- a/src/libraries/System.Reflection.Metadata/tests/Utilities/ImmutableByteArrayInteropTest.cs +++ /dev/null @@ -1,66 +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.Collections.Immutable; -using System.Reflection.Internal; -using Xunit; - -namespace System.Reflection.Metadata.Tests -{ - public class ImmutableByteArrayInteropTest - { - [Fact] - public void DangerousCreateFromUnderlyingArray() - { - byte[] array = new byte[3] { 1, 2, 3 }; - byte[] arrayCopy = array; - ImmutableArray immutable = ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref array); - - // DangerousCreateFromUnderlyingArray clears the given parameter as a signal that - // the mutable array should no longer be modified through mutable references. - Assert.Null(array); - - Assert.Equal(3, immutable.Length); - Assert.Equal(1, immutable[0]); - Assert.Equal(2, immutable[1]); - Assert.Equal(3, immutable[2]); - - arrayCopy[0] = 9; - - Assert.Equal(9, immutable[0]); - } - - [Fact] - public void DangerousCreateFromUnderlyingArrayNegativeTests() - { - byte[] array = null; - ImmutableArray immutable = ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref array); - - Assert.True(immutable.IsDefault); - } - - [Fact] - public void DangerousGetUnderlyingArray() - { - ImmutableArray immutable = ImmutableArray.Create(1, 2, 3); - byte[] array = ImmutableByteArrayInterop.DangerousGetUnderlyingArray(immutable); - - Assert.Equal(3, array.Length); - Assert.Equal(1, array[0]); - Assert.Equal(2, array[1]); - Assert.Equal(3, array[2]); - - array[0] = 9; - - Assert.Equal(9, immutable[0]); - } - - [Fact] - public void DangerousGetUnderlyingArrayNegativeTests() - { - ImmutableArray immutable = default(ImmutableArray); - - Assert.Null(ImmutableByteArrayInterop.DangerousGetUnderlyingArray(immutable)); - } - } -} diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Random.cs b/src/libraries/System.Runtime.Extensions/tests/System/Random.cs index 0903c9988a92e0..16c3a9a2353b7e 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Random.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Random.cs @@ -69,13 +69,13 @@ public void NextInt_AllValuesAreWithinSpecifiedRange(bool derived, bool seeded) Assert.InRange(r.NextInt64(20, 30), 20, 29); } - for (int i = 0; i < 1000; i++) + for (int i = 0; i < 5_000_000; i++) { float x = r.NextSingle(); Assert.True(x >= 0.0 && x < 1.0); } - for (int i = 0; i < 1000; i++) + for (int i = 0; i < 5_000_000; i++) { double x = r.NextDouble(); Assert.True(x >= 0.0 && x < 1.0); @@ -830,7 +830,7 @@ public static void GetItems_Buffer_Seeded() AssertExtensions.SequenceEqual(new byte[] { 1, 1, 3, 1, 3, 2, 2 }, buffer); } - private static Random Create(bool derived, bool seeded, int seed = 42) => + private static Random Create(bool derived, bool seeded) => (derived, seeded) switch { (false, false) => new Random(), diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs index 38605743fad931..c15b81826b0fb2 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs @@ -32,18 +32,15 @@ internal static void PreventTrimming() public static void GetCSOwnedObjectByJSHandleRef(nint jsHandle, int shouldAddInflight, out JSObject? result) { - lock (JSHostImplementation.s_csOwnedObjects) + if (JSHostImplementation.ThreadCsOwnedObjects.TryGetValue((int)jsHandle, out WeakReference? reference)) { - if (JSHostImplementation.s_csOwnedObjects.TryGetValue((int)jsHandle, out WeakReference? reference)) + reference.TryGetTarget(out JSObject? jsObject); + if (shouldAddInflight != 0) { - reference.TryGetTarget(out JSObject? jsObject); - if (shouldAddInflight != 0) - { - jsObject?.AddInFlight(); - } - result = jsObject; - return; + jsObject?.AddInFlight(); } + result = jsObject; + return; } result = null; } @@ -77,14 +74,12 @@ public static void CreateCSOwnedProxyRef(nint jsHandle, LegacyHostImplementation JSObject? res = null; - lock (JSHostImplementation.s_csOwnedObjects) + if (!JSHostImplementation.ThreadCsOwnedObjects.TryGetValue((int)jsHandle, out WeakReference? reference) || + !reference.TryGetTarget(out res) || + res.IsDisposed) { - if (!JSHostImplementation.s_csOwnedObjects.TryGetValue((int)jsHandle, out WeakReference? reference) || - !reference.TryGetTarget(out res) || - res.IsDisposed) - { #pragma warning disable CS0612 // Type or member is obsolete - res = mappedType switch + res = mappedType switch { LegacyHostImplementation.MappedType.JSObject => new JSObject(jsHandle), LegacyHostImplementation.MappedType.Array => new Array(jsHandle), @@ -95,8 +90,7 @@ public static void CreateCSOwnedProxyRef(nint jsHandle, LegacyHostImplementation _ => throw new ArgumentOutOfRangeException(nameof(mappedType)) }; #pragma warning restore CS0612 // Type or member is obsolete - JSHostImplementation.s_csOwnedObjects[(int)jsHandle] = new WeakReference(res, trackResurrection: true); - } + JSHostImplementation.ThreadCsOwnedObjects[(int)jsHandle] = new WeakReference(res, trackResurrection: true); } if (shouldAddInflight != 0) { diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs index 7738bb834fc210..b439586d213012 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs @@ -15,7 +15,20 @@ internal static partial class JSHostImplementation private const string TaskGetResultName = "get_Result"; private static MethodInfo? s_taskGetResultMethodInfo; // we use this to maintain identity of JSHandle for a JSObject proxy - public static readonly Dictionary> s_csOwnedObjects = new Dictionary>(); +#if FEATURE_WASM_THREADS + [ThreadStatic] +#endif + private static Dictionary>? s_csOwnedObjects; + + public static Dictionary> ThreadCsOwnedObjects + { + get + { + s_csOwnedObjects ??= new (); + return s_csOwnedObjects; + } + } + // we use this to maintain identity of GCHandle for a managed object public static Dictionary s_gcHandleFromJSOwnedObject = new Dictionary(ReferenceEqualityComparer.Instance); @@ -24,10 +37,7 @@ public static void ReleaseCSOwnedObject(nint jsHandle) { if (jsHandle != IntPtr.Zero) { - lock (s_csOwnedObjects) - { - s_csOwnedObjects.Remove((int)jsHandle); - } + ThreadCsOwnedObjects.Remove((int)jsHandle); Interop.Runtime.ReleaseCSOwnedObject(jsHandle); } } @@ -175,17 +185,14 @@ public static unsafe void FreeMethodSignatureBuffer(JSFunctionBinding signature) public static JSObject CreateCSOwnedProxy(nint jsHandle) { - JSObject? res = null; + JSObject? res; - lock (s_csOwnedObjects) + if (!ThreadCsOwnedObjects.TryGetValue((int)jsHandle, out WeakReference? reference) || + !reference.TryGetTarget(out res) || + res.IsDisposed) { - if (!s_csOwnedObjects.TryGetValue((int)jsHandle, out WeakReference? reference) || - !reference.TryGetTarget(out res) || - res.IsDisposed) - { - res = new JSObject(jsHandle); - s_csOwnedObjects[(int)jsHandle] = new WeakReference(res, trackResurrection: true); - } + res = new JSObject(jsHandle); + ThreadCsOwnedObjects[(int)jsHandle] = new WeakReference(res, trackResurrection: true); } return res; } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs index 6a5de6a03e5038..661b21690670a7 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs @@ -21,10 +21,7 @@ public static void ReleaseInFlight(object obj) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RegisterCSOwnedObject(JSObject proxy) { - lock (JSHostImplementation.s_csOwnedObjects) - { - JSHostImplementation.s_csOwnedObjects[(int)proxy.JSHandle] = new WeakReference(proxy, trackResurrection: true); - } + JSHostImplementation.ThreadCsOwnedObjects[(int)proxy.JSHandle] = new WeakReference(proxy, trackResurrection: true); } public static MarshalType GetMarshalTypeFromType(Type type) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs index df2c3d67f091fa..a66720c9a88fd5 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs @@ -1428,7 +1428,10 @@ public void JsExportCatchStack() { var stack = JavaScriptTestHelper.catch1stack("-t-e-s-t-", nameof(JavaScriptTestHelper.ThrowFromJSExport)); Assert.Contains(nameof(JavaScriptTestHelper.ThrowFromJSExport), stack); - Assert.Contains("catch1stack", stack); + if (PlatformDetection.IsBrowserDomSupportedOrNodeJS) + { + Assert.Contains("catch1stack", stack); + } } #endregion Exception diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Microsoft.Interop.SourceGeneration.csproj b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Microsoft.Interop.SourceGeneration.csproj index b95808cf689133..a85ea9e94678f5 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Microsoft.Interop.SourceGeneration.csproj +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Microsoft.Interop.SourceGeneration.csproj @@ -15,6 +15,7 @@ + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SafeHandleMarshallingInfoProvider.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SafeHandleMarshallingInfoProvider.cs index 0309793096e7c4..a5c2f2a1f93f98 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SafeHandleMarshallingInfoProvider.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SafeHandleMarshallingInfoProvider.cs @@ -3,8 +3,10 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Text; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; namespace Microsoft.Interop { @@ -19,11 +21,13 @@ public sealed record SafeHandleMarshallingInfo(bool AccessibleDefaultConstructor public sealed class SafeHandleMarshallingInfoProvider : ITypeBasedMarshallingInfoProvider { private readonly Compilation _compilation; + private readonly INamedTypeSymbol _safeHandleMarshallerType; private readonly ITypeSymbol _containingScope; public SafeHandleMarshallingInfoProvider(Compilation compilation, ITypeSymbol containingScope) { _compilation = compilation; + _safeHandleMarshallerType = compilation.GetBestTypeByMetadataName(TypeNames.System_Runtime_InteropServices_Marshalling_SafeHandleMarshaller_Metadata); _containingScope = containingScope; } @@ -47,6 +51,7 @@ public bool CanProvideMarshallingInfoForType(ITypeSymbol type) public MarshallingInfo GetMarshallingInfo(ITypeSymbol type, int indirectionDepth, UseSiteAttributeProvider useSiteAttributes, GetMarshallingInfoCallback marshallingInfoCallback) { + bool hasDefaultConstructor = false; bool hasAccessibleDefaultConstructor = false; if (type is INamedTypeSymbol named && !named.IsAbstract && named.InstanceConstructors.Length > 0) { @@ -54,12 +59,45 @@ public MarshallingInfo GetMarshallingInfo(ITypeSymbol type, int indirectionDepth { if (ctor.Parameters.Length == 0) { + hasDefaultConstructor = ctor.DeclaredAccessibility == Accessibility.Public; hasAccessibleDefaultConstructor = _compilation.IsSymbolAccessibleWithin(ctor, _containingScope); break; } } } - return new SafeHandleMarshallingInfo(hasAccessibleDefaultConstructor, type.IsAbstract); + + // If we don't have the SafeHandleMarshaller type, then we'll use the built-in support in the generator. + // This support will be removed when dotnet/runtime doesn't build any packages for platforms below .NET 8 + // as the downlevel support is dotnet/runtime specific. + if (_safeHandleMarshallerType is null) + { + return new SafeHandleMarshallingInfo(hasAccessibleDefaultConstructor, type.IsAbstract); + } + + INamedTypeSymbol entryPointType = _safeHandleMarshallerType.Construct(type); + if (!ManualTypeMarshallingHelper.TryGetValueMarshallersFromEntryType( + entryPointType, + type, + _compilation, + out CustomTypeMarshallers? marshallers)) + { + return NoMarshallingInfo.Instance; + } + + // If the SafeHandle-derived type doesn't have a default constructor or is abstract, + // we only support managed-to-unmanaged marshalling + if (!hasDefaultConstructor || type.IsAbstract) + { + marshallers = marshallers.Value with + { + Modes = ImmutableDictionary.Empty + .Add( + MarshalMode.ManagedToUnmanagedIn, + marshallers.Value.GetModeOrDefault(MarshalMode.ManagedToUnmanagedIn)) + }; + } + + return new NativeMarshallingAttributeInfo(ManagedTypeInfo.CreateTypeInfoForTypeSymbol(entryPointType), marshallers.Value); } } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs index 4db27ba1e0bde4..43a458a0dfa8e1 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs @@ -136,5 +136,7 @@ public static string MarshalEx(InteropGenerationOptions options) public const string GeneratedComClassAttribute = "System.Runtime.InteropServices.Marshalling.GeneratedComClassAttribute"; public const string ComExposedClassAttribute = "System.Runtime.InteropServices.Marshalling.ComExposedClassAttribute"; public const string IComExposedClass = "System.Runtime.InteropServices.Marshalling.IComExposedClass"; + + public const string System_Runtime_InteropServices_Marshalling_SafeHandleMarshaller_Metadata = "System.Runtime.InteropServices.Marshalling.SafeHandleMarshaller`1"; } } diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index 374d5ed8b0709e..5f82435829d892 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -623,6 +623,7 @@ public static partial class CollectionsMarshal public static System.Span AsSpan(System.Collections.Generic.List? list) { throw null; } public static ref TValue GetValueRefOrNullRef(System.Collections.Generic.Dictionary dictionary, TKey key) where TKey : notnull { throw null; } public static ref TValue? GetValueRefOrAddDefault(System.Collections.Generic.Dictionary dictionary, TKey key, out bool exists) where TKey : notnull { throw null; } + public static void SetCount(System.Collections.Generic.List list, int count) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, Inherited=false)] public sealed partial class ComDefaultInterfaceAttribute : System.Attribute diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/SafeHandleTests.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/SafeHandleTests.cs index 1ae443c457ee88..2d9a2cbc6326c5 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/SafeHandleTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/SafeHandleTests.cs @@ -12,7 +12,7 @@ partial class NativeExportsNE { public partial class NativeExportsSafeHandle : SafeHandleZeroOrMinusOneIsInvalid { - private NativeExportsSafeHandle() : base(ownsHandle: true) + public NativeExportsSafeHandle() : base(ownsHandle: true) { } protected override bool ReleaseHandle() diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs index 613588fb6b2173..4a948f59db1d16 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs @@ -113,6 +113,12 @@ public static IEnumerable CodeSnippetsToCompile() // Abstract SafeHandle type by reference yield return new object[] { ID(), CodeSnippets.BasicParameterWithByRefModifier("ref", "System.Runtime.InteropServices.SafeHandle"), 1, 0 }; + // SafeHandle array + yield return new object[] { ID(), CodeSnippets.MarshalAsArrayParametersAndModifiers("Microsoft.Win32.SafeHandles.SafeFileHandle"), 5, 0 }; + + // SafeHandle with private constructor by ref or out + yield return new object[] { ID(), CodeSnippets.SafeHandleWithCustomDefaultConstructorAccessibility(privateCtor: true), 3, 0 }; + // Collection with constant and element size parameter yield return new object[] { ID(), CodeSnippets.MarshalUsingCollectionWithConstantAndElementCount, 2, 0 }; diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs index f92f137f3911e5..9eb21ba33484e0 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs @@ -174,7 +174,6 @@ public static IEnumerable CodeSnippetsToCompile() yield return new[] { ID(), CodeSnippets.BasicParametersAndModifiers("Microsoft.Win32.SafeHandles.SafeFileHandle") }; yield return new[] { ID(), CodeSnippets.BasicParameterByValue("System.Runtime.InteropServices.SafeHandle") }; yield return new[] { ID(), CodeSnippets.SafeHandleWithCustomDefaultConstructorAccessibility(privateCtor: false) }; - yield return new[] { ID(), CodeSnippets.SafeHandleWithCustomDefaultConstructorAccessibility(privateCtor: true) }; // Custom type marshalling CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippets = new(new CodeSnippets()); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs index 876c0681bc6648..325c9a43de6303 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs @@ -505,5 +505,55 @@ private class IntAsObject public int Value; public int Property { get; set; } } + + [Fact] + public void ListSetCount() + { + List list = null; + Assert.Throws(() => CollectionsMarshal.SetCount(list, 3)); + + Assert.Throws(() => CollectionsMarshal.SetCount(list, -1)); + + list = new(); + Assert.Throws(() => CollectionsMarshal.SetCount(list, -1)); + + CollectionsMarshal.SetCount(list, 5); + Assert.Equal(5, list.Count); + + list = new() { 1, 2, 3, 4, 5 }; + ref int intRef = ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(list)); + + // make sure that size decrease preserves content + CollectionsMarshal.SetCount(list, 3); + Assert.Equal(3, list.Count); + Assert.Throws(() => list[3]); + AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list), new int[] { 1, 2, 3 }); + Assert.True(Unsafe.AreSame(ref intRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(list)))); + + // make sure that size increase preserves content and doesn't clear + CollectionsMarshal.SetCount(list, 5); + AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list), new int[] { 1, 2, 3, 4, 5 }); + Assert.True(Unsafe.AreSame(ref intRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(list)))); + + // make sure that reallocations preserve content + int newCount = list.Capacity * 2; + CollectionsMarshal.SetCount(list, newCount); + Assert.Equal(newCount, list.Count); + AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list)[..3], new int[] { 1, 2, 3 }); + Assert.True(!Unsafe.AreSame(ref intRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(list)))); + + List listReference = new() { "a", "b", "c", "d", "e" }; + ref string stringRef = ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(listReference)); + CollectionsMarshal.SetCount(listReference, 3); + + // verify that reference types aren't cleared + AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(listReference), new string[] { "a", "b", "c" }); + Assert.True(Unsafe.AreSame(ref stringRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(listReference)))); + CollectionsMarshal.SetCount(listReference, 5); + + // verify that removed reference types are cleared + AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(listReference), new string[] { "a", "b", "c", null, null }); + Assert.True(Unsafe.AreSame(ref stringRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(listReference)))); + } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj index 592a6f0fe24f08..4ba1f17dd095ef 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj @@ -11,7 +11,7 @@ to the apphost to make sure that it is built before this project invokes DNNE. --> false - $(OutputRid) + $(OutputRID) $(PackageRID) <_TargetsAppleOS Condition="'$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'iossimulator' or diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 26affa796b3a1d..478b78b9906b23 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4414,10 +4414,20 @@ internal Avx512BW() { } public static System.Runtime.Intrinsics.Vector512 AddSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 AddSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 AddSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } - public static System.Runtime.Intrinsics.Vector512 AlignRight(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte mask) { throw null; } - public static System.Runtime.Intrinsics.Vector512 AlignRight(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector512 AlignRight(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector512 AlignRight(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } public static System.Runtime.Intrinsics.Vector512 Average(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Average(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Byte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Byte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256ByteWithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256SByte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256SByte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256SByteWithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int16(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int16(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt16(System.Runtime.Intrinsics.Vector256 value) { throw null; } @@ -4445,26 +4455,33 @@ internal Avx512BW() { } public static System.Runtime.Intrinsics.Vector512 PackSignedSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 PackUnsignedSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 PackUnsignedSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar32x16(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar32x16(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte numBytes) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte numBytes) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte numBytes) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte numBytes) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte numBytes) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte numBytes) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte numBytes) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical128BitLane(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte numBytes) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 mask) { throw null; } public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 mask) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShuffleHigh(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShuffleHigh(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShuffleLow(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShuffleLow(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShuffleHigh(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShuffleHigh(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShuffleLow(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShuffleLow(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public new unsafe static void Store(byte* address, System.Runtime.Intrinsics.Vector512 source) { } public new unsafe static void Store(short* address, System.Runtime.Intrinsics.Vector512 source) { } public new unsafe static void Store(sbyte* address, System.Runtime.Intrinsics.Vector512 source) { } @@ -4490,6 +4507,32 @@ internal Avx512BW() { } { internal VL() { } public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PermuteVar8x16(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PermuteVar8x16(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 PermuteVar16x16(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 PermuteVar16x16(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } } public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx512F.X64 { @@ -4522,20 +4565,100 @@ internal Avx512DQ() { } public static System.Runtime.Intrinsics.Vector512 And(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 AndNot(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 AndNot(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastPairScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastPairScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastPairScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector128ToVector512(double* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector128ToVector512(long* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector128ToVector512(ulong* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector256ToVector512(int* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector256ToVector512(float* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector256ToVector512(uint* address) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Single(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Single(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Double(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Double(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int64(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int64(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int64WithTruncation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int64WithTruncation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt64(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt64(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt64WithTruncation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt64WithTruncation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static new System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static new System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } public static System.Runtime.Intrinsics.Vector512 MultiplyLow(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 MultiplyLow(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Or(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Or(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Range(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Range(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RangeScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RangeScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Reduce(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Reduce(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReduceScalar(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReduceScalar(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReduceScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReduceScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector512 Xor(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Xor(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public new abstract partial class VL : System.Runtime.Intrinsics.X86.Avx512F.VL { internal VL() { } public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector128 BroadcastPairScalarToVector128(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 BroadcastPairScalarToVector128(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 BroadcastPairScalarToVector256(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 BroadcastPairScalarToVector256(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 BroadcastPairScalarToVector256(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Double(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Double(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Double(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Double(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int64(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int64WithTruncation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt64(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt64WithTruncation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 MultiplyLow(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 MultiplyLow(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 MultiplyLow(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 MultiplyLow(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Range(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Range(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Range(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Range(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reduce(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reduce(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Reduce(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Reduce(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } } public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx512F.X64 { @@ -4572,11 +4695,62 @@ internal Avx512F() { } public static System.Runtime.Intrinsics.Vector512 AndNot(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 AndNot(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 AndNot(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 BroadcastScalarToVector512(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector128ToVector512(int* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector128ToVector512(float* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector128ToVector512(uint* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector256ToVector512(double* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector256ToVector512(long* address) { throw null; } + public static unsafe System.Runtime.Intrinsics.Vector512 BroadcastVector256ToVector512(ulong* address) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertScalarToVector128Double(System.Runtime.Intrinsics.Vector128 upper, uint value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertScalarToVector128Single(System.Runtime.Intrinsics.Vector128 upper, uint value) { throw null; } + public static uint ConvertToUInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static uint ConvertToUInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static uint ConvertToUInt32WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static uint ConvertToUInt32WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16WithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16WithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int16WithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int32WithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int32WithTruncation(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Single(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt16(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt16WithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32WithSaturation(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32WithTruncation(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Double(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Double(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Double(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int32(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int32(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int32(System.Runtime.Intrinsics.Vector128 value) { throw null; } @@ -4590,10 +4764,13 @@ internal Avx512F() { } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int64(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Int64(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Single(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512Single(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt32WithTruncation(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToVector512UInt64(System.Runtime.Intrinsics.Vector256 value) { throw null; } @@ -4605,6 +4782,74 @@ internal Avx512F() { } public static System.Runtime.Intrinsics.Vector512 DuplicateEvenIndexed(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 DuplicateEvenIndexed(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 DuplicateOddIndexed(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ExtractVector256(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Fixup(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, System.Runtime.Intrinsics.Vector512 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Fixup(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, System.Runtime.Intrinsics.Vector512 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 FixupScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, System.Runtime.Intrinsics.Vector128 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 FixupScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, System.Runtime.Intrinsics.Vector128 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplyAdd(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplyAdd(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplyAddNegated(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplyAddNegated(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplyAddSubtract(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplyAddSubtract(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplySubtract(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplySubtract(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplySubtractAdd(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplySubtractAdd(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplySubtractNegated(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 FusedMultiplySubtractNegated(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c) { throw null; } + public static System.Runtime.Intrinsics.Vector512 GetExponent(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 GetExponent(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetExponentScalar(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetExponentScalar(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetExponentScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetExponentScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 GetMantissa(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 GetMantissa(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetMantissaScalar(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetMantissaScalar(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetMantissaScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetMantissaScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector128(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector512 InsertVector256(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector256 data, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte index) { throw null; } public unsafe static System.Runtime.Intrinsics.Vector512 LoadAlignedVector512(byte* address) { throw null; } public unsafe static System.Runtime.Intrinsics.Vector512 LoadAlignedVector512(double* address) { throw null; } public unsafe static System.Runtime.Intrinsics.Vector512 LoadAlignedVector512(short* address) { throw null; } @@ -4659,30 +4904,75 @@ internal Avx512F() { } public static System.Runtime.Intrinsics.Vector512 Or(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Or(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Or(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Permute2x64(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Permute4x32(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Permute4x64(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Permute4x64(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Permute4x64(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar2x64(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar4x32(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar8x64(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar8x64(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar8x64(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar16x32(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar16x32(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar16x32(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Reciprocal14(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Reciprocal14(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reciprocal14Scalar(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reciprocal14Scalar(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reciprocal14Scalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reciprocal14Scalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14Scalar(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14Scalar(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14Scalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14Scalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RoundScale(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RoundScale(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RoundScaleScalar(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RoundScaleScalar(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RoundScaleScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RoundScaleScalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Scale(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Scale(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ScaleScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ScaleScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftLeftLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector512 ShiftRightLogical(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } - public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } - public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } - public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 Shuffle(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector512 Sqrt(System.Runtime.Intrinsics.Vector512 value) { throw null; } public static System.Runtime.Intrinsics.Vector512 Sqrt(System.Runtime.Intrinsics.Vector512 value) { throw null; } public unsafe static void Store(byte* address, System.Runtime.Intrinsics.Vector512 source) { } @@ -4747,6 +5037,90 @@ internal VL() { } public static bool IsSupported { get { throw null; } } public static System.Runtime.Intrinsics.Vector128 Abs(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector256 Abs(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128ByteWithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Double(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16WithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16WithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16WithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int16WithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int32WithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int32WithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByte(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128SByteWithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16WithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16WithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16WithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16WithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32WithSaturation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32WithSaturation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32WithTruncation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Double(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Single(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32WithTruncation(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Fixup(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, System.Runtime.Intrinsics.Vector128 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Fixup(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, System.Runtime.Intrinsics.Vector128 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Fixup(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, System.Runtime.Intrinsics.Vector256 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Fixup(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, System.Runtime.Intrinsics.Vector256 table, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetExponent(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetExponent(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 GetExponent(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 GetExponent(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetMantissa(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 GetMantissa(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 GetMantissa(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 GetMantissa(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(0x0F))] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector128 Max(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 Max(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 Max(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } @@ -4755,12 +5129,61 @@ internal VL() { } public static System.Runtime.Intrinsics.Vector128 Min(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 Min(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 Min(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 PermuteVar4x64(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 PermuteVar4x64(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 PermuteVar4x64(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reciprocal14(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Reciprocal14(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Reciprocal14(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Reciprocal14(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RoundScale(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RoundScale(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RoundScale(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RoundScale(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Scale(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Scale(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Scale(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Scale(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } - public static System.Runtime.Intrinsics.Vector256 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } public static System.Runtime.Intrinsics.Vector256 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } } public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx2.X64 + { + internal X64() { } + public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector128 ConvertScalarToVector128Double(System.Runtime.Intrinsics.Vector128 upper, ulong value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertScalarToVector128Single(System.Runtime.Intrinsics.Vector128 upper, ulong value) { throw null; } + public static ulong ConvertToUInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static ulong ConvertToUInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static ulong ConvertToUInt64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static ulong ConvertToUInt64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } + } + } + [System.CLSCompliantAttribute(false)] + public abstract partial class Avx512Vbmi : System.Runtime.Intrinsics.X86.Avx512BW + { + internal Avx512Vbmi() { } + public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector512 PermuteVar64x8(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 PermuteVar64x8(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 control) { throw null; } + public new abstract partial class VL : System.Runtime.Intrinsics.X86.Avx512BW.VL + { + internal VL() { } + public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector128 PermuteVar16x8(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PermuteVar16x8(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 PermuteVar32x8(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 PermuteVar32x8(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 control) { throw null; } + } + public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx512BW.X64 { internal X64() { } public static new bool IsSupported { get { throw null; } } @@ -5745,6 +6168,34 @@ public abstract partial class PackedSimd public static Vector128 AddPairwiseWidening(Vector128 value) { throw null; } public static Vector128 AddPairwiseWidening(Vector128 value) { throw null; } public static Vector128 AddPairwiseWidening(Vector128 value) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 MultiplyRoundedSaturateQ15(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } public static Vector128 ShiftLeft(Vector128 value, int count) { throw null; } public static Vector128 ShiftLeft(Vector128 value, int count) { throw null; } public static Vector128 ShiftLeft(Vector128 value, int count) { throw null; } @@ -5787,6 +6238,89 @@ public abstract partial class PackedSimd public static Vector128 And(Vector128 left, Vector128 right) { throw null; } public static Vector128 And(Vector128 left, Vector128 right) { throw null; } public static Vector128 And(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Or(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Xor(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 Not(Vector128 value) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AndNot(Vector128 left, Vector128 right) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 BitwiseSelect(Vector128 left, Vector128 right, Vector128 select) { throw null; } + public static Vector128 PopCount(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AnyTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } + public static bool AllTrue(Vector128 value) { throw null; } public static int Bitmask(Vector128 value) { throw null; } public static int Bitmask(Vector128 value) { throw null; } public static int Bitmask(Vector128 value) { throw null; } @@ -5821,5 +6355,53 @@ public abstract partial class PackedSimd public static Vector128 CompareNotEqual(Vector128 left, Vector128 right) { throw null; } public static Vector128 CompareNotEqual(Vector128 left, Vector128 right) { throw null; } public static Vector128 CompareNotEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareLessThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThan(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } + public static Vector128 CompareGreaterThanOrEqual(Vector128 left, Vector128 right) { throw null; } } } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs index 23626acf5af6f1..51768ff26f2a0d 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs @@ -85,5 +85,6 @@ public double FireEvents() { return Accumulator; } + public double AddedFirstProp {get => 0.0; set { Console.WriteLine (value); } } } } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs new file mode 100644 index 00000000000000..87ad6f32526f0a --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs @@ -0,0 +1,91 @@ +// 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 System.Reflection.Metadata.ApplyUpdate.Test +{ + public class AddInstanceField + { + public AddInstanceField () { + _doubleField2 = 5.5; + _stringField2 = "New Initial Value"; + NewStructField = new NewStruct { + D = -1985.0, + O = new int[2] { 15, 17 }, + }; + // a little bit ldflda testing + IncRefDouble (ref NewStructField.D); + IncRefDouble (ref _doubleField2); + + AddedStringAutoProp = "abcd"; + + AddedEvent += MyHandler; + + void MyHandler (object sender, double data) { + } + } + + public void IncRefDouble (ref double d) + { + d += 1.0; + } + + public string GetStringField => _stringField2; + public double GetDoubleField => _doubleField2; + + private string _stringField; + private string _stringField2; + private double _doubleField; + private double _doubleField2; + + private int[] _intArrayFieldWithInit = new[] { 2, 4, 6, 8, 10, 12 }; + private int[] _intArrayFieldWithInit2 = new[] { 1, 3, 5, 7, 9, 11 }; + + public void TestMethod () { + _stringField = "spqr"; + _stringField2 = "4567"; + _doubleField = 2.71828; + _doubleField2 = 0.707106; + AddedStringAutoProp = AddedStringAutoProp + "Test"; + } + + public int GetIntArrayLength() => _intArrayFieldWithInit2?.Length ?? -1; + public int GetIntArrayElt(int i) => _intArrayFieldWithInit2[i]; + + public struct NewStruct + { + public double D; + public object O; + } + + public NewStruct NewStructField; + + public string GetStringProp => AddedStringAutoProp; + + public string AddedStringAutoProp { get; set; } + + public event EventHandler ExistingEvent; + public event EventHandler AddedEvent; + + public double Accumulator; + + private void AccumHandler (object sender, double value) => Accumulator += value; + + public double FireEvents() { + Accumulator = 0.0; + ExistingEvent += AccumHandler; + ExistingEvent(this, 123.0); + ExistingEvent -= AccumHandler; + + AddedEvent += AccumHandler; + AddedEvent(this, 123.0); + AddedEvent -= AccumHandler; + + return Accumulator; + } + + public double AddedFirstProp {get => 0.0; set { Console.WriteLine (value+value); } } + public short AddedSecondProp {get; set; } + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/deltascript.json b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/deltascript.json index 3c81223a4fc7d9..7d481b9aac19ce 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/deltascript.json +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/deltascript.json @@ -1,6 +1,7 @@ { "changes": [ {"document": "AddInstanceField.cs", "update": "AddInstanceField_v1.cs"}, + {"document": "AddInstanceField.cs", "update": "AddInstanceField_v2.cs"}, ] } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index b90e373f7f0f34..e4f39888aeb07c 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -229,7 +229,6 @@ public void CustomAttributeDelete() }); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/79043", TestRuntimes.Mono)] [ConditionalFact(typeof(ApplyUpdateUtil), nameof (ApplyUpdateUtil.IsSupported))] public void AsyncMethodChanges() { @@ -410,6 +409,16 @@ public static void TestAddInstanceField() Assert.True ((addedEventToken & 0x00ffffff) < 4); + ApplyUpdateUtil.ApplyUpdate(assm); + + var addedFirstPropInfo = x2.GetType().GetProperty("AddedFirstProp"); + var firstPropSetter = addedFirstPropInfo.GetSetMethod(); + Assert.NotNull (firstPropSetter); + + var addedSecondPropInfo = x2.GetType().GetProperty("AddedSecondProp"); + var secondPropGetter = addedSecondPropInfo.GetGetMethod(); + Assert.NotNull (secondPropGetter); + }); } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index 676850c9d29608..e08bd72e2f98ad 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -1293,8 +1293,8 @@ public static IEnumerable SerializableObjects() yield return new object[] { observableCollection, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAE5XaW5kb3dzQmFzZSwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAJIBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLk9ic2VydmFibGVDb2xsZWN0aW9uYDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAACF9tb25pdG9yEkNvbGxlY3Rpb25gMStpdGVtcwQDoAFTeXN0ZW0uQ29sbGVjdGlvbnMuT2JqZWN0TW9kZWwuT2JzZXJ2YWJsZUNvbGxlY3Rpb25gMStTaW1wbGVNb25pdG9yW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAgAAAH5TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAACQMAAAAJBAAAAAUDAAAAoAFTeXN0ZW0uQ29sbGVjdGlvbnMuT2JqZWN0TW9kZWwuT2JzZXJ2YWJsZUNvbGxlY3Rpb25gMStTaW1wbGVNb25pdG9yW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAApfYnVzeUNvdW50AAgCAAAAAAAAAAQEAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uBwAACAgICQUAAAAFAAAAAAAAAA8FAAAABQAAAAgBAAAAAgAAAAMAAAAEAAAABQAAAAs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAE5XaW5kb3dzQmFzZSwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPU5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAJIBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLk9ic2VydmFibGVDb2xsZWN0aW9uYDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAACF9tb25pdG9yEkNvbGxlY3Rpb25gMStpdGVtcwQDoAFTeXN0ZW0uQ29sbGVjdGlvbnMuT2JqZWN0TW9kZWwuT2JzZXJ2YWJsZUNvbGxlY3Rpb25gMStTaW1wbGVNb25pdG9yW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAgAAAH5TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAACQMAAAAJBAAAAAUDAAAAoAFTeXN0ZW0uQ29sbGVjdGlvbnMuT2JqZWN0TW9kZWwuT2JzZXJ2YWJsZUNvbGxlY3Rpb25gMStTaW1wbGVNb25pdG9yW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAApfYnVzeUNvdW50AAgCAAAAAAAAAAQEAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uBwAACAgICQUAAAAFAAAABQAAAA8FAAAACAAAAAgBAAAAAgAAAAMAAAAEAAAABQAAAAAAAAAAAAAAAAAAAAs=", TargetFrameworkMoniker.netfx461) } }; yield return new object[] { new System.Collections.ObjectModel.ReadOnlyObservableCollection(observableCollection), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAE5XaW5kb3dzQmFzZSwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAJoBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5T2JzZXJ2YWJsZUNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAAZUmVhZE9ubHlDb2xsZWN0aW9uYDErbGlzdASSAVN5c3RlbS5Db2xsZWN0aW9ucy5PYmplY3RNb2RlbC5PYnNlcnZhYmxlQ29sbGVjdGlvbmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAgAAAAIAAAAJAwAAAAUDAAAAkgFTeXN0ZW0uQ29sbGVjdGlvbnMuT2JqZWN0TW9kZWwuT2JzZXJ2YWJsZUNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQIAAAAIX21vbml0b3ISQ29sbGVjdGlvbmAxK2l0ZW1zBAOgAVN5c3RlbS5Db2xsZWN0aW9ucy5PYmplY3RNb2RlbC5PYnNlcnZhYmxlQ29sbGVjdGlvbmAxK1NpbXBsZU1vbml0b3JbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQIAAAAJBAAAAAkFAAAABQQAAACgAVN5c3RlbS5Db2xsZWN0aW9ucy5PYmplY3RNb2RlbC5PYnNlcnZhYmxlQ29sbGVjdGlvbmAxK1NpbXBsZU1vbml0b3JbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0BAAAACl9idXN5Q291bnQACAIAAAAAAAAABAUAAAB+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24HAAAICAgJBgAAAAUAAAAAAAAADwYAAAAFAAAACAEAAAACAAAAAwAAAAQAAAAFAAAACw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAE5XaW5kb3dzQmFzZSwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPU5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAJoBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5T2JzZXJ2YWJsZUNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAAZUmVhZE9ubHlDb2xsZWN0aW9uYDErbGlzdASSAVN5c3RlbS5Db2xsZWN0aW9ucy5PYmplY3RNb2RlbC5PYnNlcnZhYmxlQ29sbGVjdGlvbmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAgAAAAIAAAAJAwAAAAUDAAAAkgFTeXN0ZW0uQ29sbGVjdGlvbnMuT2JqZWN0TW9kZWwuT2JzZXJ2YWJsZUNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQIAAAAIX21vbml0b3ISQ29sbGVjdGlvbmAxK2l0ZW1zBAOgAVN5c3RlbS5Db2xsZWN0aW9ucy5PYmplY3RNb2RlbC5PYnNlcnZhYmxlQ29sbGVjdGlvbmAxK1NpbXBsZU1vbml0b3JbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQIAAAAJBAAAAAkFAAAABQQAAACgAVN5c3RlbS5Db2xsZWN0aW9ucy5PYmplY3RNb2RlbC5PYnNlcnZhYmxlQ29sbGVjdGlvbmAxK1NpbXBsZU1vbml0b3JbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0BAAAACl9idXN5Q291bnQACAIAAAAAAAAABAUAAAB+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24HAAAICAgJBgAAAAUAAAAFAAAADwYAAAAIAAAACAEAAAACAAAAAwAAAAQAAAAFAAAAAAAAAAAAAAAAAAAACw==", TargetFrameworkMoniker.netfx461) } }; - yield return new object[] { new System.Collections.ObjectModel.ReadOnlyCollection(Enumerable.Range(1, 15).ToList()), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAJABU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5Q29sbGVjdGlvbmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAARsaXN0A35TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JAgAAAAQCAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uBwAACAgICQMAAAAPAAAADwAAAA8DAAAADwAAAAgBAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAJABU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5Q29sbGVjdGlvbmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAARsaXN0A35TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JAgAAAAQCAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uBwAACAgICQMAAAAPAAAADwAAAA8DAAAAEAAAAAgBAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAAAAAACw==", TargetFrameworkMoniker.netfx461) } }; - yield return new object[] { new System.Collections.ObjectModel.Collection(Enumerable.Range(1, 20).ToList()), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAIgBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLkNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAAFaXRlbXMDflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkCAAAABAIAAAB+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24HAAAICAgJAwAAABQAAAAUAAAADwMAAAAUAAAACAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAACw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAIgBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLkNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAAFaXRlbXMDflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkCAAAABAIAAAB+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24HAAAICAgJAwAAABQAAAAUAAAADwMAAAAgAAAACAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACw==", TargetFrameworkMoniker.netfx461) } }; + yield return new object[] { new System.Collections.ObjectModel.ReadOnlyCollection(Enumerable.Range(1, 15).ToList()), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAJABU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5Q29sbGVjdGlvbmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAARsaXN0A35TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JAgAAAAQCAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uBwAACAgICQMAAAAPAAAAAQAAAA8DAAAADwAAAAgBAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAJABU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5Q29sbGVjdGlvbmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAARsaXN0A35TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JAgAAAAQCAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uBwAACAgICQMAAAAPAAAADwAAAA8DAAAADwAAAAgBAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAJABU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5Q29sbGVjdGlvbmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAARsaXN0A35TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JAgAAAAQCAAAAflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uBwAACAgICQMAAAAPAAAADwAAAA8DAAAAEAAAAAgBAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAAAAAACw==", TargetFrameworkMoniker.netfx461) } }; + yield return new object[] { new System.Collections.ObjectModel.Collection(Enumerable.Range(1, 20).ToList()), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAIgBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLkNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAAFaXRlbXMDflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkCAAAABAIAAAB+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24HAAAICAgJAwAAABQAAAABAAAADwMAAAAUAAAACAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAACw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAIgBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLkNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAAFaXRlbXMDflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkCAAAABAIAAAB+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24HAAAICAgJAwAAABQAAAAUAAAADwMAAAAUAAAACAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAACw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAIgBU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLkNvbGxlY3Rpb25gMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAAFaXRlbXMDflN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkCAAAABAIAAAB+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24HAAAICAgJAwAAABQAAAAUAAAADwMAAAAgAAAACAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACw==", TargetFrameworkMoniker.netfx461) } }; yield return new object[] { new System.Collections.ObjectModel.ReadOnlyDictionary(dictionary), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAO0BU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5RGljdGlvbmFyeWAyW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAAxtX2RpY3Rpb25hcnkD4QFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5EaWN0aW9uYXJ5YDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JAgAAAAQCAAAA4QFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5EaWN0aW9uYXJ5YDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0EAAAAB1ZlcnNpb24IQ29tcGFyZXIISGFzaFNpemUNS2V5VmFsdWVQYWlycwADAAMIkQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5HZW5lcmljRXF1YWxpdHlDb21wYXJlcmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dCOUBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV1bXQIAAAAJAwAAAAMAAAAJBAAAAAQDAAAAkQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5HZW5lcmljRXF1YWxpdHlDb21wYXJlcmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAAAAAAcEAAAAAAEAAAACAAAAA+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0E+////+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAAA2tleQV2YWx1ZQABCAEAAAAGBgAAAAR0ZXN0Afn////7////AgAAAAYIAAAADGFub3RoZXIgdGVzdAs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAO0BU3lzdGVtLkNvbGxlY3Rpb25zLk9iamVjdE1vZGVsLlJlYWRPbmx5RGljdGlvbmFyeWAyW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAAxtX2RpY3Rpb25hcnkD4QFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5EaWN0aW9uYXJ5YDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JAgAAAAQCAAAA4QFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5EaWN0aW9uYXJ5YDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0EAAAAB1ZlcnNpb24IQ29tcGFyZXIISGFzaFNpemUNS2V5VmFsdWVQYWlycwADAAMIkQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5HZW5lcmljRXF1YWxpdHlDb21wYXJlcmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dCOUBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV1bXQIAAAAJAwAAAAMAAAAJBAAAAAQDAAAAkQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5HZW5lcmljRXF1YWxpdHlDb21wYXJlcmAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAAAAAAcEAAAAAAEAAAACAAAAA+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0E+////+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJbW1N5c3RlbS5JbnQzMiwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAAA2tleQV2YWx1ZQABCAEAAAAGBgAAAAR0ZXN0Afn////7////AgAAAAYIAAAADGFub3RoZXIgdGVzdAs=", TargetFrameworkMoniker.netfx461) } }; var simpleKeyedCollection = new SimpleKeyedCollection diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs index 2429b3ac74f199..8484775ea230a0 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs @@ -4041,6 +4041,7 @@ public static void DCS_MyPersonSurrogate() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/85690", TestPlatforms.Wasi)] public static void DCS_FileStreamSurrogate() { using (var testFile = TempFile.Create()) @@ -4108,6 +4109,7 @@ public static void DCS_SampleICollectionTExplicitWithoutDC() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsWasi))] public static void DCS_MemoryStream_Serialize_UsesBuiltInAdapter() { ValidateObject( @@ -4167,6 +4169,7 @@ static void ValidateObject(MemoryStream original, string expectedXml, byte[] exp [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsWasi))] public static void DCS_MemoryStream_Deserialize_CompatibleWithFullFramework() { // The payloads in this test were generated by a Full Framework application. diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs index 3697cb0412a43b..982cc7dc0888d4 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs @@ -88,6 +88,7 @@ public static IEnumerable CanExport_MemberData() [Theory] [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsWasi))] [MemberData(nameof(Export_MemberData))] public void Export(string testname, Action export, Action schemaCheck = null) { diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index f6103152f09bdd..5e3e26c5225f32 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -7284,15 +7284,15 @@ public partial interface IMemoryOwner : System.IDisposable { System.Memory Memory { get; } } - public class IndexOfAnyValues where T : System.IEquatable? + public class SearchValues where T : System.IEquatable? { - internal IndexOfAnyValues() { } + internal SearchValues() { } public bool Contains(T value) { throw null; } } - public static class IndexOfAnyValues + public static class SearchValues { - public static System.Buffers.IndexOfAnyValues Create(System.ReadOnlySpan values) { throw null; } - public static System.Buffers.IndexOfAnyValues Create(System.ReadOnlySpan values) { throw null; } + public static System.Buffers.SearchValues Create(System.ReadOnlySpan values) { throw null; } + public static System.Buffers.SearchValues Create(System.ReadOnlySpan values) { throw null; } } public partial interface IPinnable { @@ -7367,6 +7367,7 @@ public override void Close() { } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } public override void Flush() { } public override System.Threading.Tasks.Task FlushAsync() { throw null; } + public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } protected virtual void OutputTabs() { } protected virtual System.Threading.Tasks.Task OutputTabsAsync() { throw null; } public override void Write(bool value) { } @@ -10137,6 +10138,7 @@ protected override void Dispose(bool disposing) { } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } public override void Flush() { } public override System.Threading.Tasks.Task FlushAsync() { throw null; } + public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } public override void Write(char value) { } public override void Write(char[]? buffer) { } public override void Write(char[] buffer, int index, int count) { } @@ -10254,6 +10256,7 @@ protected virtual void Dispose(bool disposing) { } public virtual System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } public virtual void Flush() { } public virtual System.Threading.Tasks.Task FlushAsync() { throw null; } + public virtual System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } public static System.IO.TextWriter Synchronized(System.IO.TextWriter writer) { throw null; } public virtual void Write(bool value) { } public virtual void Write(char value) { } @@ -13489,6 +13492,63 @@ public static class UnmanagedToManagedOut public static System.Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements) { throw null; } } } + + [System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute.GenericPlaceholder), + System.Runtime.InteropServices.Marshalling.MarshalMode.ManagedToUnmanagedIn, + typeof(System.Runtime.InteropServices.Marshalling.SafeHandleMarshaller<>.ManagedToUnmanagedIn))] + [System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute.GenericPlaceholder), + System.Runtime.InteropServices.Marshalling.MarshalMode.ManagedToUnmanagedRef, + typeof(System.Runtime.InteropServices.Marshalling.SafeHandleMarshaller<>.ManagedToUnmanagedRef))] + [System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute.GenericPlaceholder), + System.Runtime.InteropServices.Marshalling.MarshalMode.ManagedToUnmanagedOut, + typeof(System.Runtime.InteropServices.Marshalling.SafeHandleMarshaller<>.ManagedToUnmanagedOut))] + public static class SafeHandleMarshaller<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> where T : SafeHandle + { + public struct ManagedToUnmanagedIn + { + private int _dummyPrimitive; + private T _handle; + public void FromManaged(T handle) { } + + public nint ToUnmanaged() { throw null; } + + public void Free() { } + } + + public struct ManagedToUnmanagedRef + { + private int _dummyPrimitive; + private T _handle; + + public ManagedToUnmanagedRef() { } + + public void FromManaged(T handle) { } + + public nint ToUnmanaged() { throw null; } + + public void FromUnmanaged(nint value) { } + + public void OnInvoked() { } + + public T ToManagedFinally() { throw null; } + + public void Free() { } + } + + public struct ManagedToUnmanagedOut + { + private int _dummyPrimitive; + private T _newHandle; + public ManagedToUnmanagedOut() { } + + public void FromUnmanaged(nint value) { } + + public T ToManaged() { throw null; } + + public void Free() { } + } + } + [System.CLSCompliant(false)] [System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.Span<>), System.Runtime.InteropServices.Marshalling.MarshalMode.Default, @@ -14154,6 +14214,14 @@ namespace System.Text { public static class Ascii { + public static bool Equals(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } + public static bool Equals(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } + public static bool Equals(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } + public static bool Equals(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } + public static bool EqualsIgnoreCase(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } + public static bool EqualsIgnoreCase(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } + public static bool EqualsIgnoreCase(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } + public static bool EqualsIgnoreCase(System.ReadOnlySpan left, System.ReadOnlySpan right) { throw null; } public static bool IsValid(System.ReadOnlySpan value) { throw null; } public static bool IsValid(System.ReadOnlySpan value) { throw null; } public static bool IsValid(byte value) { throw null; } @@ -14183,8 +14251,8 @@ public sealed class CompositeFormat { internal CompositeFormat() { } public static System.Text.CompositeFormat Parse([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format) { throw null; } - public static bool TryParse([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.CompositeFormat? compositeFormat) { throw null; } public string Format { get { throw null; } } + public int MinimumArgumentCount { get { throw null; } } } public abstract partial class Decoder { @@ -14433,6 +14501,8 @@ protected Encoding(int codePage, System.Text.EncoderFallback? encoderFallback, S public bool IsAlwaysNormalized() { throw null; } public virtual bool IsAlwaysNormalized(System.Text.NormalizationForm form) { throw null; } public static void RegisterProvider(System.Text.EncodingProvider provider) { } + public virtual bool TryGetBytes(System.ReadOnlySpan chars, System.Span bytes, out int bytesWritten) { throw null; } + public virtual bool TryGetChars(System.ReadOnlySpan bytes, System.Span chars, out int charsWritten) { throw null; } } public sealed partial class EncodingInfo { diff --git a/src/libraries/System.Runtime/tests/System/GCTests.cs b/src/libraries/System.Runtime/tests/System/GCTests.cs index d6d7488c1fc091..e59aea9ccdd1fb 100644 --- a/src/libraries/System.Runtime/tests/System/GCTests.cs +++ b/src/libraries/System.Runtime/tests/System/GCTests.cs @@ -35,6 +35,9 @@ public static void Collect_Int() { GC.Collect(i); } + // Also, expect GC.Collect(int.MaxValue) to work without exception since int.MaxValue represents + // a nongc heap generation (that is exactly what GC.GetGeneration returns for a non-gc heap object) + GC.Collect(int.MaxValue); } [Fact] diff --git a/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs b/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs index c481638159ff3e..bdfde206c850f4 100644 --- a/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs +++ b/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Linq; using Xunit; namespace System.Text.Tests @@ -13,9 +14,6 @@ public void NullArgument_Throws() { AssertExtensions.Throws("format", () => CompositeFormat.Parse(null)); - Assert.False(CompositeFormat.TryParse(null, out CompositeFormat? compositeFormat)); - Assert.Null(compositeFormat); - AssertExtensions.Throws("format", () => string.Format(null, (CompositeFormat)null, 0)); AssertExtensions.Throws("format", () => string.Format(null, (CompositeFormat)null, 0, 0)); AssertExtensions.Throws("format", () => string.Format(null, (CompositeFormat)null, 0, 0, 0)); @@ -55,6 +53,30 @@ public static void DebuggerDisplay_ShowsFormat() Assert.Equal($"\"{format}\"", DebuggerAttributes.ValidateDebuggerDisplayReferences(cf)); } + [Theory] + [InlineData("", 0)] + [InlineData("testing 123", 0)] + [InlineData("testing {{123}}", 0)] + [InlineData("{0}", 1)] + [InlineData("{0} {1}", 2)] + [InlineData("{2}", 3)] + [InlineData("{2} {0}", 3)] + [InlineData("{1} {34} {3}", 35)] + public static void MinimumArgumentCount_MatchesExpectedValue(string format, int expected) + { + CompositeFormat cf = CompositeFormat.Parse(format); + + Assert.Equal(expected, cf.MinimumArgumentCount); + + string s = string.Format(null, cf, Enumerable.Repeat((object)"arg", expected).ToArray()); + Assert.NotNull(s); + + if (expected != 0) + { + Assert.Throws(() => string.Format(null, cf, Enumerable.Repeat((object)"arg", expected - 1).ToArray())); + } + } + [Theory] [MemberData(nameof(System.Tests.StringTests.Format_Valid_TestData), MemberType = typeof(System.Tests.StringTests))] public static void StringFormat_Valid(IFormatProvider provider, string format, object[] values, string expected) @@ -63,10 +85,6 @@ public static void StringFormat_Valid(IFormatProvider provider, string format, o Assert.NotNull(cf); Assert.Same(format, cf.Format); - Assert.True(CompositeFormat.TryParse(format, out CompositeFormat? cf2)); - Assert.NotNull(cf2); - Assert.Same(format, cf2.Format); - Assert.Equal(expected, string.Format(provider, cf, values)); Assert.Equal(expected, string.Format(provider, cf, (ReadOnlySpan)values)); @@ -95,10 +113,6 @@ public static void StringBuilderAppendFormat_Valid(IFormatProvider provider, str Assert.NotNull(cf); Assert.Same(format, cf.Format); - Assert.True(CompositeFormat.TryParse(format, out CompositeFormat? cf2)); - Assert.NotNull(cf2); - Assert.Same(format, cf2.Format); - var sb = new StringBuilder(); Assert.Same(sb, sb.AppendFormat(provider, cf, values)); @@ -135,10 +149,6 @@ public static void MemoryExtensionsTryWrite_Valid(IFormatProvider provider, stri Assert.NotNull(cf); Assert.Same(format, cf.Format); - Assert.True(CompositeFormat.TryParse(format, out CompositeFormat? cf2)); - Assert.NotNull(cf2); - Assert.Same(format, cf2.Format); - char[] dest = new char[expected.Length]; int charsWritten; @@ -189,9 +199,6 @@ public static void Parse_Invalid_FormatExceptionFromFormat(IFormatProvider provi _ = args; Assert.Throws(() => CompositeFormat.Parse(format)); - - Assert.False(CompositeFormat.TryParse(format, out CompositeFormat? compositeFormat)); - Assert.Null(compositeFormat); } [Theory] diff --git a/src/libraries/System.Runtime/tests/default.rd.xml b/src/libraries/System.Runtime/tests/default.rd.xml index b78da0bb4022be..c594df1579d567 100644 --- a/src/libraries/System.Runtime/tests/default.rd.xml +++ b/src/libraries/System.Runtime/tests/default.rd.xml @@ -251,6 +251,12 @@ + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Cose/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.Cose/src/Resources/Strings.resx index c03febddebb117..8a49f05e5e00e0 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography.Cose/src/Resources/Strings.resx @@ -123,6 +123,12 @@ The destination is too small to hold the encoded value. + + Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. + + + Non-negative number required. + Content was not included in the message (detached message), provide a content to verify. @@ -156,6 +162,9 @@ Critical Headers must be a CBOR array of at least one element. + + The hash algorithm name cannot be null or empty. + COSE Signature must be an array of three elements. diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj index 23203e5e3e485f..3ed0bec5488ed5 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj +++ b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj @@ -1,4 +1,5 @@ + $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true @@ -7,9 +8,16 @@ - - - + + + + + @@ -34,8 +42,4 @@ - - - - diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs index 59dfff8fa188ba..388c18ac8fd6dd 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs @@ -17,7 +17,6 @@ public DESCryptoServiceProvider() : base() { // This class wraps DES _impl = DES.Create(); - _impl.FeedbackSize = 8; } public override int BlockSize diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DesImplementation.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DesImplementation.cs index e42d6a394d025f..4fb16cdf77055e 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DesImplementation.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DesImplementation.cs @@ -10,6 +10,14 @@ internal sealed partial class DesImplementation : DES { private const int BitsPerByte = 8; + public DesImplementation() + { + // Default CFB to CFB8. .NET Framework uses 8 as the default for DESCryptoServiceProvider which + // was used for DES.Create(), and .NET doesn't support anything other than 8 for the feedback size for DES, + // so also default it to the only value that works. + FeedbackSizeValue = 8; + } + public override ICryptoTransform CreateDecryptor() { return CreateTransform(Key, IV, encrypting: false); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Android.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Android.cs index 63c4ff763dac7c..47a1d1efc81ca0 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Android.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Android.cs @@ -342,12 +342,13 @@ private static Dictionary> GetStatusByIndex(SafeX509C X509ChainStatus chainStatus = ValidationErrorToChainStatus(error); Marshal.FreeHGlobal(error.Message); - if (!statusByIndex.ContainsKey(error.Index)) + if (!statusByIndex.TryGetValue(error.Index, out List? value)) { - statusByIndex.Add(error.Index, new List()); + value = new List(); + statusByIndex.Add(error.Index, value); } - statusByIndex[error.Index].Add(chainStatus); + value.Add(chainStatus); } return statusByIndex; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.cs index fc85db32b294ab..200c1c95ca176b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.cs @@ -17,8 +17,8 @@ internal static partial class X500NameEncoder private const string UseNewlineSeparators = "\r\n"; private const string DefaultSeparators = ",;"; - private static readonly IndexOfAnyValues s_needsQuotingChars = - IndexOfAnyValues.Create(",+=\"\n<>#;"); // \r is NOT in this list, because it isn't in Windows. + private static readonly SearchValues s_needsQuotingChars = + SearchValues.Create(",+=\"\n<>#;"); // \r is NOT in this list, because it isn't in Windows. internal static string X500DistinguishedNameDecode( byte[] encodedName, diff --git a/src/libraries/System.Security.Cryptography/tests/DESTests.cs b/src/libraries/System.Security.Cryptography/tests/DESTests.cs index edf123bfe78b0c..07d2d195123779 100644 --- a/src/libraries/System.Security.Cryptography/tests/DESTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/DESTests.cs @@ -19,6 +19,15 @@ public static void EnsureLegalSizesValuesIsolated() } } + [Fact] + public static void DesDerivedFeedbackSize() + { + using (DES des = new DESMinimal()) + { + Assert.Equal(64, des.FeedbackSize); + } + } + private class DESLegalSizesBreaker : DESMinimal { public DESLegalSizesBreaker() diff --git a/src/libraries/System.Text.Encoding.Extensions/ref/System.Text.Encoding.Extensions.cs b/src/libraries/System.Text.Encoding.Extensions/ref/System.Text.Encoding.Extensions.cs index a13aedd4f57333..0c9b8230911fe9 100644 --- a/src/libraries/System.Text.Encoding.Extensions/ref/System.Text.Encoding.Extensions.cs +++ b/src/libraries/System.Text.Encoding.Extensions/ref/System.Text.Encoding.Extensions.cs @@ -33,6 +33,8 @@ public ASCIIEncoding() { } public override int GetMaxByteCount(int charCount) { throw null; } public override int GetMaxCharCount(int byteCount) { throw null; } public override string GetString(byte[] bytes, int byteIndex, int byteCount) { throw null; } + public override bool TryGetBytes(System.ReadOnlySpan chars, System.Span bytes, out int bytesWritten) { throw null; } + public override bool TryGetChars(System.ReadOnlySpan bytes, System.Span chars, out int charsWritten) { throw null; } } public partial class UnicodeEncoding : System.Text.Encoding { @@ -153,5 +155,7 @@ public UTF8Encoding(bool encoderShouldEmitUTF8Identifier, bool throwOnInvalidByt public override int GetMaxCharCount(int byteCount) { throw null; } public override byte[] GetPreamble() { throw null; } public override string GetString(byte[] bytes, int index, int count) { throw null; } + public override bool TryGetBytes(System.ReadOnlySpan chars, System.Span bytes, out int bytesWritten) { throw null; } + public override bool TryGetChars(System.ReadOnlySpan bytes, System.Span chars, out int charsWritten) { throw null; } } } diff --git a/src/libraries/System.Text.Encoding/tests/Ascii/EqualsTests.cs b/src/libraries/System.Text.Encoding/tests/Ascii/EqualsTests.cs new file mode 100644 index 00000000000000..c2186defc5e129 --- /dev/null +++ b/src/libraries/System.Text.Encoding/tests/Ascii/EqualsTests.cs @@ -0,0 +1,204 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Intrinsics; +using Xunit; + +namespace System.Text.Tests +{ + public abstract class AsciiEqualityTests + { + protected abstract bool Equals(string left, string right); + protected abstract bool EqualsIgnoreCase(string left, string right); + protected abstract bool Equals(byte[] left, byte[] right); + protected abstract bool EqualsIgnoreCase(byte[] left, byte[] right); + + public static IEnumerable ValidAsciiInputs + { + get + { + yield return new object[] { "test" }; + + for (char textLength = (char)0; textLength <= 127; textLength++) + { + yield return new object[] { new string(textLength, textLength) }; + } + } + } + + [Theory] + [MemberData(nameof(ValidAsciiInputs))] + public void Equals_ExactlyTheSameInputs_ReturnsTrue(string input) + { + Assert.True(Equals(input, input)); // reference equality + Assert.True(Equals(input, new StringBuilder(input).ToString())); // content equality + } + + [Theory] + [MemberData(nameof(ValidAsciiInputs))] + public void EqualsIgnoreCase_ExactlyTheSameInputs_ReturnsTrue(string input) + { + Assert.True(EqualsIgnoreCase(input, input)); // reference equality + Assert.True(EqualsIgnoreCase(input, new StringBuilder(input).ToString())); // content equality + } + + public static IEnumerable DifferentInputs + { + get + { + yield return new object[] { "tak", "nie" }; + + for (char i = (char)1; i <= 127; i++) + { + if (i != '?') // ASCIIEncoding maps invalid ASCII to ? + { + yield return new object[] { new string(i, i), string.Create(i, i, (destination, iteration) => + { + destination.Fill(iteration); + destination[iteration / 2] = (char)128; + })}; + } + } + } + } + + [Theory] + [MemberData(nameof(DifferentInputs))] + public void Equals_DifferentInputs_ReturnsFalse(string left, string right) + { + Assert.False(Equals(left, right)); + Assert.False(Equals(right, left)); + } + + [Theory] + [MemberData(nameof(DifferentInputs))] + public void EqualsIgnoreCase_DifferentInputs_ReturnsFalse(string left, string right) + { + Assert.False(EqualsIgnoreCase(left, right)); + Assert.False(EqualsIgnoreCase(right, left)); + } + + public static IEnumerable EqualIgnoringCaseConsiderations + { + get + { + yield return new object[] { "aBc", "AbC" }; + + for (char i = (char)0; i <= 127; i++) + { + char left = i; + char right = char.IsAsciiLetterUpper(left) ? char.ToLower(left) : char.IsAsciiLetterLower(left) ? char.ToUpper(left) : left; + yield return new object[] { new string(left, i), new string(right, i) }; + } + } + } + + [Theory] + [MemberData(nameof(EqualIgnoringCaseConsiderations))] + public void EqualIgnoreCase_EqualIgnoringCaseConsiderations_ReturnsTrue(string left, string right) + { + Assert.True(EqualsIgnoreCase(left, right)); + Assert.True(EqualsIgnoreCase(right, left)); + } + + public static IEnumerable ContainingNonAsciiCharactersBuffers + { + get + { + foreach (int length in new[] { 1, Vector128.Count - 1, Vector128.Count, Vector256.Count + 1 }) + { + for (int index = 0; index < length; index++) + { + yield return new object[] { Create(length, index) }; + } + } + + static byte[] Create(int length, int invalidCharacterIndex) + { + byte[] buffer = Enumerable.Repeat(GetNextValidAsciiByte(), length).ToArray(); + buffer[invalidCharacterIndex] = GetNextInvalidAsciiByte(); + + Assert.False(Ascii.IsValid(buffer)); + + return buffer; + } + + static byte GetNextValidAsciiByte() => (byte)Random.Shared.Next(0, 127 + 1); + + static byte GetNextInvalidAsciiByte() => (byte)Random.Shared.Next(128, 255 + 1); + } + } + + [Theory] + [MemberData(nameof(ContainingNonAsciiCharactersBuffers))] + public void Equals_EqualValues_ButNonAscii_ReturnsFalse(byte[] input) + => Assert.False(Equals(input, input)); + + [Theory] + [MemberData(nameof(ContainingNonAsciiCharactersBuffers))] + public void EqualsIgnoreCase_EqualValues_ButNonAscii_ReturnsFalse(byte[] input) + => Assert.False(EqualsIgnoreCase(input, input)); + } + + public class AsciiEqualityTests_Byte_Byte : AsciiEqualityTests + { + protected override bool Equals(string left, string right) + => Ascii.Equals(Encoding.ASCII.GetBytes(left), Encoding.ASCII.GetBytes(right)); + + protected override bool EqualsIgnoreCase(string left, string right) + => Ascii.EqualsIgnoreCase(Encoding.ASCII.GetBytes(left), Encoding.ASCII.GetBytes(right)); + + protected override bool Equals(byte[] left, byte[] right) + => Ascii.Equals(left, right); + + protected override bool EqualsIgnoreCase(byte[] left, byte[] right) + => Ascii.EqualsIgnoreCase(left, right); + } + + public class AsciiEqualityTests_Byte_Char : AsciiEqualityTests + { + protected override bool Equals(string left, string right) + => Ascii.Equals(Encoding.ASCII.GetBytes(left), right); + + protected override bool EqualsIgnoreCase(string left, string right) + => Ascii.EqualsIgnoreCase(Encoding.ASCII.GetBytes(left), right); + + protected override bool Equals(byte[] left, byte[] right) + => Ascii.Equals(left, right.Select(b => (char)b).ToArray()); + + protected override bool EqualsIgnoreCase(byte[] left, byte[] right) + => Ascii.EqualsIgnoreCase(left, right.Select(b => (char)b).ToArray()); + } + + public class AsciiEqualityTests_Char_Byte : AsciiEqualityTests + { + protected override bool Equals(string left, string right) + => Ascii.Equals(left, Encoding.ASCII.GetBytes(right)); + + protected override bool EqualsIgnoreCase(string left, string right) + => Ascii.EqualsIgnoreCase(left, Encoding.ASCII.GetBytes(right)); + + protected override bool Equals(byte[] left, byte[] right) + => Ascii.Equals(left.Select(b => (char)b).ToArray(), right); + + protected override bool EqualsIgnoreCase(byte[] left, byte[] right) + => Ascii.EqualsIgnoreCase(left.Select(b => (char)b).ToArray(), right); + } + + public class AsciiEqualityTests_Char_Char : AsciiEqualityTests + { + protected override bool Equals(string left, string right) + => Ascii.Equals(left, right); + + protected override bool EqualsIgnoreCase(string left, string right) + => Ascii.EqualsIgnoreCase(left, right); + + protected override bool Equals(byte[] left, byte[] right) + => Ascii.Equals(left.Select(b => (char)b).ToArray(), right.Select(b => (char)b).ToArray()); + + protected override bool EqualsIgnoreCase(byte[] left, byte[] right) + => Ascii.EqualsIgnoreCase(left.Select(b => (char)b).ToArray(), right.Select(b => (char)b).ToArray()); + } +} diff --git a/src/libraries/System.Text.Encoding/tests/EncodingTestHelpers.cs b/src/libraries/System.Text.Encoding/tests/EncodingTestHelpers.cs index f049afdf196f31..9b9170cf5826bc 100644 --- a/src/libraries/System.Text.Encoding/tests/EncodingTestHelpers.cs +++ b/src/libraries/System.Text.Encoding/tests/EncodingTestHelpers.cs @@ -268,6 +268,12 @@ static void GetBytes_NetCoreApp(Encoding encoding, string chars, int index, int Assert.Equal(expected.Length, encoding.GetBytes(chars.AsSpan(index, count), (Span)stringResultAdvanced)); VerifyGetBytes(stringResultAdvanced, 0, stringResultAdvanced.Length, new byte[expected.Length], expected); + // Use TryGetBytes(ReadOnlySpan, Span, out int bytesWritten) + Array.Clear(stringResultAdvanced); + Assert.True(encoding.TryGetBytes(chars.AsSpan(index, count), (Span)stringResultAdvanced, out int bytesWritten)); + Assert.Equal(expected.Length, bytesWritten); + VerifyGetBytes(stringResultAdvanced, 0, stringResultAdvanced.Length, new byte[expected.Length], expected); + if (count == 0) Assert.Equal(expected.Length, encoding.GetBytes(ReadOnlySpan.Empty, (Span)stringResultAdvanced)); } @@ -289,6 +295,12 @@ static void VerifyGetChars_NetCoreApp(Encoding encoding, byte[] bytes, int byteI VerifyGetChars(byteChars, charIndex, charCount, (char[])chars.Clone(), expectedChars); Assert.Equal(expectedChars.Length, charCount); + // Use TryGetChars(ReadOnlySpan, Span, out int charsWritten) + byteChars = (char[])chars.Clone(); + Assert.True(encoding.TryGetChars(new ReadOnlySpan(bytes, byteIndex, byteCount), new Span(byteChars).Slice(charIndex), out charCount)); + VerifyGetChars(byteChars, charIndex, charCount, (char[])chars.Clone(), expectedChars); + Assert.Equal(expectedChars.Length, charCount); + if (byteCount == 0) { charCount = encoding.GetChars(ReadOnlySpan.Empty, new Span(byteChars).Slice(charIndex)); diff --git a/src/libraries/System.Text.Encoding/tests/NegativeEncodingTests.cs b/src/libraries/System.Text.Encoding/tests/NegativeEncodingTests.cs index 1754d8771ab44b..d0e1e5a51cfa6f 100644 --- a/src/libraries/System.Text.Encoding/tests/NegativeEncodingTests.cs +++ b/src/libraries/System.Text.Encoding/tests/NegativeEncodingTests.cs @@ -128,10 +128,22 @@ public static unsafe void GetBytes_Invalid(Encoding encoding) AssertExtensions.Throws("bytes", () => encoding.GetBytes("a", 0, 1, new byte[0], 0)); AssertExtensions.Throws("bytes", () => encoding.GetBytes("abc", 0, 3, new byte[1], 0)); AssertExtensions.Throws("bytes", () => encoding.GetBytes("\uD800\uDC00", 0, 2, new byte[1], 0)); + AssertExtensions.Throws("bytes", () => encoding.GetBytes(new char[1], 0, 1, new byte[0], 0)); AssertExtensions.Throws("bytes", () => encoding.GetBytes(new char[3], 0, 3, new byte[1], 0)); AssertExtensions.Throws("bytes", () => encoding.GetBytes("\uD800\uDC00".ToCharArray(), 0, 2, new byte[1], 0)); + AssertExtensions.Throws("bytes", () => encoding.GetBytes((ReadOnlySpan)new char[1], (Span)new byte[0])); + AssertExtensions.Throws("bytes", () => encoding.GetBytes((ReadOnlySpan)new char[3], (Span)new byte[1])); + AssertExtensions.Throws("bytes", () => encoding.GetBytes((ReadOnlySpan)"\uD800\uDC00".ToCharArray(), (Span)new byte[1])); + + Assert.False(encoding.TryGetBytes((ReadOnlySpan)new char[1], (Span)new byte[0], out int bytesWritten)); + Assert.Equal(0, bytesWritten); + Assert.False(encoding.TryGetBytes((ReadOnlySpan)new char[3], (Span)new byte[1], out bytesWritten)); + Assert.Equal(0, bytesWritten); + Assert.False(encoding.TryGetBytes((ReadOnlySpan)"\uD800\uDC00".ToCharArray(), (Span)new byte[1], out bytesWritten)); + Assert.Equal(0, bytesWritten); + char[] chars = new char[3]; byte[] bytes = new byte[3]; byte[] smallBytes = new byte[1]; @@ -223,6 +235,9 @@ public static unsafe void GetChars_Invalid(Encoding encoding) // Chars does not have enough capacity to accommodate result AssertExtensions.Throws("chars", () => encoding.GetChars(new byte[4], 0, 4, new char[1], 1)); + AssertExtensions.Throws("chars", () => encoding.GetChars((ReadOnlySpan)new byte[4], (new char[1]).AsSpan(1))); + Assert.False(encoding.TryGetChars((ReadOnlySpan)new byte[4], (new char[1]).AsSpan(1), out int charsWritten)); + Assert.Equal(0, charsWritten); byte[] bytes = new byte[encoding.GetMaxByteCount(2)]; char[] chars = new char[4]; diff --git a/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj b/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj index a0c5f7f8553677..697bc05b2da20b 100644 --- a/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj +++ b/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj @@ -10,6 +10,7 @@ + diff --git a/src/libraries/System.Text.Json/Common/JsonNumberHandling.cs b/src/libraries/System.Text.Json/Common/JsonNumberHandling.cs index 827bd7e25049ac..f637efe9ba2e0f 100644 --- a/src/libraries/System.Text.Json/Common/JsonNumberHandling.cs +++ b/src/libraries/System.Text.Json/Common/JsonNumberHandling.cs @@ -15,7 +15,7 @@ namespace System.Text.Json.Serialization #else public #endif - enum JsonNumberHandling + enum JsonNumberHandling { /// /// Numbers will only be read from tokens and will only be written as JSON numbers (without quotes). diff --git a/src/libraries/System.Text.Json/Common/JsonObjectCreationHandling.cs b/src/libraries/System.Text.Json/Common/JsonObjectCreationHandling.cs new file mode 100644 index 00000000000000..baa1bea93ef308 --- /dev/null +++ b/src/libraries/System.Text.Json/Common/JsonObjectCreationHandling.cs @@ -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. + +namespace System.Text.Json.Serialization +{ + + /// + /// Determines how deserialization will handle object creation for fields or properties. + /// +#if BUILDING_SOURCE_GENERATOR + internal +#else + public +#endif + enum JsonObjectCreationHandling + { + /// + /// A new instance will always be created when deserializing a field or property. + /// + Replace = 0, + + /// + /// Attempt to populate any instances already found on a deserialized field or property. + /// + Populate = 1, + } +} diff --git a/src/libraries/System.Text.Json/Common/JsonSeparatorNamingPolicy.cs b/src/libraries/System.Text.Json/Common/JsonSeparatorNamingPolicy.cs index 9e54127c65ad95..77eb1d8af32c31 100644 --- a/src/libraries/System.Text.Json/Common/JsonSeparatorNamingPolicy.cs +++ b/src/libraries/System.Text.Json/Common/JsonSeparatorNamingPolicy.cs @@ -16,6 +16,11 @@ internal JsonSeparatorNamingPolicy(bool lowercase, char separator) => public sealed override string ConvertName(string name) { + if (name is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(name)); + } + // Rented buffer 20% longer that the input. int rentedBufferLength = (12 * name.Length) / 10; char[]? rentedBuffer = rentedBufferLength > JsonConstants.StackallocCharThreshold diff --git a/src/libraries/System.Text.Json/Common/ThrowHelper.cs b/src/libraries/System.Text.Json/Common/ThrowHelper.cs new file mode 100644 index 00000000000000..3f381ce3be6818 --- /dev/null +++ b/src/libraries/System.Text.Json/Common/ThrowHelper.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; + +namespace System.Text.Json +{ + internal static partial class ThrowHelper + { + [DoesNotReturn] + public static void ThrowArgumentNullException(string parameterName) + { + throw new ArgumentNullException(parameterName); + } + } +} diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs index 8384e36c8a4822..846a04ffabc1f1 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs @@ -32,6 +32,7 @@ private sealed partial class Emitter internal const string JsonContextVarName = "jsonContext"; private const string NumberHandlingPropName = "NumberHandling"; private const string UnmappedMemberHandlingPropName = "UnmappedMemberHandling"; + private const string PreferredPropertyObjectCreationHandlingPropName = "PreferredPropertyObjectCreationHandling"; private const string ObjectCreatorPropName = "ObjectCreator"; private const string OptionsInstanceVariableName = "Options"; private const string JsonTypeInfoReturnValueLocalVariableName = "jsonTypeInfo"; @@ -65,6 +66,7 @@ private sealed partial class Emitter private const string JsonCollectionInfoValuesTypeRef = "global::System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues"; private const string JsonIgnoreConditionTypeRef = "global::System.Text.Json.Serialization.JsonIgnoreCondition"; private const string JsonNumberHandlingTypeRef = "global::System.Text.Json.Serialization.JsonNumberHandling"; + private const string JsonObjectCreationHandlingTypeRef = "global::System.Text.Json.Serialization.JsonObjectCreationHandling"; private const string JsonUnmappedMemberHandlingTypeRef = "global::System.Text.Json.Serialization.JsonUnmappedMemberHandling"; private const string JsonMetadataServicesTypeRef = "global::System.Text.Json.Serialization.Metadata.JsonMetadataServices"; private const string JsonObjectInfoValuesTypeRef = "global::System.Text.Json.Serialization.Metadata.JsonObjectInfoValues"; @@ -657,6 +659,14 @@ private string GenerateForObject(TypeGenerationSpec typeMetadata) """; } + if (typeMetadata.PreferredPropertyObjectCreationHandling != null) + { + objectInfoInitSource += $""" + + {JsonTypeInfoReturnValueLocalVariableName}.{PreferredPropertyObjectCreationHandlingPropName} = {GetObjectCreationHandlingAsStr(typeMetadata.PreferredPropertyObjectCreationHandling.Value)}; +"""; + } + string additionalSource = @$"{propMetadataInitFuncSource}{serializeFuncSource}{ctorParamMetadataInitFuncSource}"; return GenerateForType(typeMetadata, objectInfoInitSource, additionalSource); @@ -762,6 +772,12 @@ private static string GeneratePropMetadataInitFunc(TypeGenerationSpec typeGenera {propertyInfoVarName}.IsRequired = true;"); } + if (memberMetadata.ObjectCreationHandling != null) + { + sb.Append($@" + {propertyInfoVarName}.ObjectCreationHandling = {GetObjectCreationHandlingAsStr(memberMetadata.ObjectCreationHandling.Value)};"); + } + sb.Append($@" {PropVarName}[{i}] = {propertyInfoVarName}; "); @@ -1386,12 +1402,22 @@ private static string IndentSource(string source, int numIndentations) } private static string GetNumberHandlingAsStr(JsonNumberHandling? numberHandling) => - numberHandling.HasValue - ? $"({JsonNumberHandlingTypeRef}){(int)numberHandling.Value}" - : "default"; + numberHandling switch + { + null => "default", + >= 0 => $"({JsonNumberHandlingTypeRef}){(int)numberHandling.Value}", + < 0 => $"({JsonNumberHandlingTypeRef})({(int)numberHandling.Value})" + }; + + private static string GetObjectCreationHandlingAsStr(JsonObjectCreationHandling creationHandling) => + creationHandling >= 0 + ? $"({JsonObjectCreationHandlingTypeRef}){(int)creationHandling}" + : $"({JsonObjectCreationHandlingTypeRef})({(int)creationHandling})"; private static string GetUnmappedMemberHandlingAsStr(JsonUnmappedMemberHandling unmappedMemberHandling) => - $"({JsonUnmappedMemberHandlingTypeRef}){(int)unmappedMemberHandling}"; + unmappedMemberHandling >= 0 + ? $"({JsonUnmappedMemberHandlingTypeRef}){(int)unmappedMemberHandling}" + : $"({JsonUnmappedMemberHandlingTypeRef})({(int)unmappedMemberHandling})"; private static string GetCreateValueInfoMethodRef(string typeCompilableName) => $"{CreateValueInfoMethodName}<{typeCompilableName}>"; diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index d641c432cf6042..16d245e217d98c 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -38,6 +38,7 @@ private sealed class Parser private const string JsonIgnoreConditionFullName = "System.Text.Json.Serialization.JsonIgnoreCondition"; private const string JsonIncludeAttributeFullName = "System.Text.Json.Serialization.JsonIncludeAttribute"; private const string JsonNumberHandlingAttributeFullName = "System.Text.Json.Serialization.JsonNumberHandlingAttribute"; + private const string JsonObjectCreationHandlingAttributeFullName = "System.Text.Json.Serialization.JsonObjectCreationHandlingAttribute"; private const string JsonUnmappedMemberHandlingAttributeFullName = "System.Text.Json.Serialization.JsonUnmappedMemberHandlingAttribute"; private const string JsonPropertyNameAttributeFullName = "System.Text.Json.Serialization.JsonPropertyNameAttribute"; private const string JsonPropertyOrderAttributeFullName = "System.Text.Json.Serialization.JsonPropertyOrderAttribute"; @@ -708,6 +709,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener CollectionType collectionType = CollectionType.NotApplicable; JsonNumberHandling? numberHandling = null; JsonUnmappedMemberHandling? unmappedMemberHandling = null; + JsonObjectCreationHandling? preferredPropertyObjectCreationHandling = null; bool foundDesignTimeCustomConverter = false; string? converterInstatiationLogic = null; bool implementsIJsonOnSerialized = false; @@ -735,6 +737,12 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener unmappedMemberHandling = (JsonUnmappedMemberHandling)ctorArgs[0].Value!; continue; } + else if (attributeTypeFullName == JsonObjectCreationHandlingAttributeFullName) + { + IList ctorArgs = attributeData.ConstructorArguments; + preferredPropertyObjectCreationHandling = (JsonObjectCreationHandling)ctorArgs[0].Value!; + continue; + } else if (!foundDesignTimeCustomConverter && attributeType.GetCompatibleBaseClass(JsonConverterAttributeFullName) != null) { foundDesignTimeCustomConverter = true; @@ -1139,6 +1147,7 @@ void CacheMemberHelper(Location memberLocation) classType, numberHandling, unmappedMemberHandling, + preferredPropertyObjectCreationHandling, propGenSpecList, paramGenSpecArray, propertyInitializerSpecList, @@ -1238,6 +1247,7 @@ private PropertyGenerationSpec GetPropertyGenerationSpec( out string? jsonPropertyName, out JsonIgnoreCondition? ignoreCondition, out JsonNumberHandling? numberHandling, + out JsonObjectCreationHandling? objectCreationHandling, out string? converterInstantiationLogic, out int order, out bool hasFactoryConverter, @@ -1287,6 +1297,7 @@ private PropertyGenerationSpec GetPropertyGenerationSpec( SetterIsVirtual = setterIsVirtual, DefaultIgnoreCondition = ignoreCondition, NumberHandling = numberHandling, + ObjectCreationHandling = objectCreationHandling, Order = order, HasJsonInclude = hasJsonInclude, IsExtensionData = isExtensionData, @@ -1320,6 +1331,7 @@ private void ProcessMemberCustomAttributes( out string? jsonPropertyName, out JsonIgnoreCondition? ignoreCondition, out JsonNumberHandling? numberHandling, + out JsonObjectCreationHandling? objectCreationHandling, out string? converterInstantiationLogic, out int order, out bool hasFactoryConverter, @@ -1330,6 +1342,7 @@ private void ProcessMemberCustomAttributes( jsonPropertyName = null; ignoreCondition = default; numberHandling = default; + objectCreationHandling = default; converterInstantiationLogic = null; order = 0; isExtensionData = false; @@ -1382,6 +1395,12 @@ private void ProcessMemberCustomAttributes( numberHandling = (JsonNumberHandling)ctorArgs[0].Value!; } break; + case JsonObjectCreationHandlingAttributeFullName: + { + IList ctorArgs = attributeData.ConstructorArguments; + objectCreationHandling = (JsonObjectCreationHandling)ctorArgs[0].Value!; + } + break; case JsonPropertyNameAttributeFullName: { IList ctorArgs = attributeData.ConstructorArguments; diff --git a/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs b/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs index b6d006fd85ed3a..3605442288e371 100644 --- a/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs @@ -90,6 +90,11 @@ internal sealed class PropertyGenerationSpec /// public JsonNumberHandling? NumberHandling { get; init; } + /// + /// The for the property. + /// + public JsonObjectCreationHandling? ObjectCreationHandling { get; init; } + /// /// The serialization order of the property. /// diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets index 6c977db11d6bbe..be3c37a67fe24b 100644 --- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets +++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets @@ -35,6 +35,7 @@ + @@ -43,6 +44,7 @@ + diff --git a/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs b/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs index ce2fb3f84f8dbf..bff0553ade6b90 100644 --- a/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs @@ -63,6 +63,7 @@ public TypeGenerationSpec(Type type) public JsonNumberHandling? NumberHandling { get; private set; } public JsonUnmappedMemberHandling? UnmappedMemberHandling { get; private set; } + public JsonObjectCreationHandling? PreferredPropertyObjectCreationHandling { get; private set; } public List? PropertyGenSpecList { get; private set; } @@ -131,6 +132,7 @@ public void Initialize( ClassType classType, JsonNumberHandling? numberHandling, JsonUnmappedMemberHandling? unmappedMemberHandling, + JsonObjectCreationHandling? preferredPropertyObjectCreationHandling, List? propertyGenSpecList, ParameterGenerationSpec[]? ctorParamGenSpecArray, List? propertyInitializerSpecList, @@ -156,6 +158,7 @@ public void Initialize( IsPolymorphic = isPolymorphic; NumberHandling = numberHandling; UnmappedMemberHandling = unmappedMemberHandling; + PreferredPropertyObjectCreationHandling = preferredPropertyObjectCreationHandling; PropertyGenSpecList = propertyGenSpecList; PropertyInitializerSpecList = propertyInitializerSpecList; CtorParamGenSpecArray = ctorParamGenSpecArray; diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index f090117148d9a6..c7f0db84ffa5e5 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -244,10 +244,6 @@ public static partial class JsonSerializer [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] - public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -388,6 +384,7 @@ public JsonSerializerOptions(System.Text.Json.JsonSerializerOptions options) { } public bool IsReadOnly { get { throw null; } } public int MaxDepth { get { throw null; } set { } } public System.Text.Json.Serialization.JsonNumberHandling NumberHandling { get { throw null; } set { } } + public System.Text.Json.Serialization.JsonObjectCreationHandling PreferredObjectCreationHandling { get { throw null; } set { } } public bool PropertyNameCaseInsensitive { get { throw null; } set { } } public System.Text.Json.JsonNamingPolicy? PropertyNamingPolicy { get { throw null; } set { } } public System.Text.Json.JsonCommentHandling ReadCommentHandling { get { throw null; } set { } } @@ -973,6 +970,17 @@ public sealed partial class JsonNumberHandlingAttribute : System.Text.Json.Seria public JsonNumberHandlingAttribute(System.Text.Json.Serialization.JsonNumberHandling handling) { } public System.Text.Json.Serialization.JsonNumberHandling Handling { get { throw null; } } } + public enum JsonObjectCreationHandling + { + Replace = 0, + Populate = 1, + } + [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] + public sealed partial class JsonObjectCreationHandlingAttribute : System.Text.Json.Serialization.JsonAttribute + { + public JsonObjectCreationHandlingAttribute(System.Text.Json.Serialization.JsonObjectCreationHandling handling) { } + public System.Text.Json.Serialization.JsonObjectCreationHandling Handling { get { throw null; } } + } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple=false, Inherited=false)] public sealed partial class JsonPolymorphicAttribute : System.Text.Json.Serialization.JsonAttribute { @@ -1214,6 +1222,7 @@ public abstract partial class JsonPropertyInfo { internal JsonPropertyInfo() { } public System.Reflection.ICustomAttributeProvider? AttributeProvider { get { throw null; } set { } } + public System.Text.Json.Serialization.JsonObjectCreationHandling? ObjectCreationHandling { get { throw null; } set { } } public System.Text.Json.Serialization.JsonConverter? CustomConverter { get { throw null; } set { } } public System.Func? Get { get { throw null; } set { } } public bool IsExtensionData { get { throw null; } set { } } @@ -1253,6 +1262,7 @@ internal JsonTypeInfo() { } public bool IsReadOnly { get { throw null; } } public System.Text.Json.Serialization.Metadata.JsonTypeInfoKind Kind { get { throw null; } } public System.Text.Json.Serialization.JsonNumberHandling? NumberHandling { get { throw null; } set { } } + public System.Text.Json.Serialization.JsonObjectCreationHandling? PreferredPropertyObjectCreationHandling { get { throw null; } set { } } public System.Action? OnDeserialized { get { throw null; } set { } } public System.Action? OnDeserializing { get { throw null; } set { } } public System.Action? OnSerialized { get { throw null; } set { } } diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj index c988155fe2ba36..d70085f787ba6a 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -1,4 +1,5 @@ + $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true @@ -38,9 +39,13 @@ - + + + + + diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 93b1860f887505..279368734cbdcc 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -2,16 +2,12 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -48,9 +71,10 @@ - - - + + + + @@ -61,8 +85,6 @@ - - @@ -80,35 +102,23 @@ + - - - - + - - - - - - - - - - - + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.CustomConverters.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.CustomConverters.cs index 4de62e09b7ef53..18762d22bcee30 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.CustomConverters.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.CustomConverters.cs @@ -248,13 +248,13 @@ public struct StructWithCustomConverterProperty public class ClassWithCustomConverterFactoryProperty { [JsonConverter(typeof(JsonStringEnumConverter))] // This converter is a JsonConverterFactory - public Serialization.Tests.SampleEnum MyEnum { get; set; } + public SourceGenSampleEnum MyEnum { get; set; } } public struct StructWithCustomConverterFactoryProperty { [JsonConverter(typeof(JsonStringEnumConverter))] // This converter is a JsonConverterFactory - public Serialization.Tests.SampleEnum MyEnum { get; set; } + public SourceGenSampleEnum MyEnum { get; set; } } [JsonConverter(typeof(CustomConverter_StructWithCustomConverter))] // Invalid @@ -268,4 +268,11 @@ public struct StructWithBadCustomConverter { public int MyInt { get; set; } } + + public enum SourceGenSampleEnum + { + MinZero = 0, + One = 1, + Two = 2 + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs index 673bafa651506a..979defdc010ac5 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs @@ -361,6 +361,7 @@ public static void JsonSerializerOptions_EqualityComparer_ChangingAnySettingShou yield return (GetProp(nameof(JsonSerializerOptions.IgnoreNullValues)), true); yield return (GetProp(nameof(JsonSerializerOptions.DefaultIgnoreCondition)), JsonIgnoreCondition.WhenWritingDefault); yield return (GetProp(nameof(JsonSerializerOptions.NumberHandling)), JsonNumberHandling.AllowReadingFromString); + yield return (GetProp(nameof(JsonSerializerOptions.PreferredObjectCreationHandling)), JsonObjectCreationHandling.Populate); yield return (GetProp(nameof(JsonSerializerOptions.UnmappedMemberHandling)), JsonUnmappedMemberHandling.Disallow); yield return (GetProp(nameof(JsonSerializerOptions.IgnoreReadOnlyProperties)), true); yield return (GetProp(nameof(JsonSerializerOptions.IgnoreReadOnlyFields)), true); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs new file mode 100644 index 00000000000000..5a669bb5b2f901 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Text.Json.Serialization.Tests +{ + public sealed class JsonCreationHandlingTests_String : JsonCreationHandlingTests + { + public JsonCreationHandlingTests_String() : base(JsonSerializerWrapper.StringSerializer) { } + } + + public sealed class JsonCreationHandlingTests_AsyncStream : JsonCreationHandlingTests + { + public JsonCreationHandlingTests_AsyncStream() : base(JsonSerializerWrapper.AsyncStreamSerializer) { } + } + + public sealed class JsonCreationHandlingTests_AsyncStreamWithSmallBuffer : JsonCreationHandlingTests + { + public JsonCreationHandlingTests_AsyncStreamWithSmallBuffer() : base(JsonSerializerWrapper.AsyncStreamSerializerWithSmallBuffer) { } + } + + public sealed class JsonCreationHandlingTests_SyncStream : JsonCreationHandlingTests + { + public JsonCreationHandlingTests_SyncStream() : base(JsonSerializerWrapper.SyncStreamSerializer) { } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs index 84939076aa9bc8..417c0b3b03c9d1 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs @@ -1764,5 +1764,61 @@ public class UnsupportedType { public ReadOnlySpan Span => Array.Empty(); } + + [Fact] + public static void JsonCreationHandlingAttributeIsShownInMetadata() + { + bool typeResolved = false; + DefaultJsonTypeInfoResolver resolver = new() + { + Modifiers = + { + (ti) => + { + if (ti.Type == typeof(TestClassWithJsonCreationHandlingOnProperty)) + { + Assert.Equal(3, ti.Properties.Count); + Assert.Null(ti.Properties[0].ObjectCreationHandling); + Assert.Equal(JsonObjectCreationHandling.Replace, ti.Properties[1].ObjectCreationHandling); + Assert.Equal(JsonObjectCreationHandling.Populate, ti.Properties[2].ObjectCreationHandling); + typeResolved = true; + } + } + } + }; + + JsonSerializerOptions o = new() + { + TypeInfoResolver = resolver + }; + + var deserialized = JsonSerializer.Deserialize("{}", o); + Assert.True(typeResolved); + } + + [Theory] + [InlineData((JsonObjectCreationHandling)(-1))] + [InlineData((JsonObjectCreationHandling)2)] + [InlineData((JsonObjectCreationHandling)int.MaxValue)] + public static void ObjectCreationHandling_SetInvalidValue_ThrowsArgumentOutOfRangeException(JsonObjectCreationHandling handling) + { + JsonTypeInfo jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(typeof(Poco), new()); + JsonPropertyInfo propertyInfo = jsonTypeInfo.CreateJsonPropertyInfo(typeof(List), "List"); + Assert.Throws(() => propertyInfo.ObjectCreationHandling = handling); + } + + private class TestClassWithJsonCreationHandlingOnProperty + { + [JsonPropertyOrder(0)] + public Poco PropertyWitoutAttribute { get; set; } + + [JsonPropertyOrder(1)] + [JsonObjectCreationHandling(JsonObjectCreationHandling.Replace)] + public Poco PropertyWithReplace { get; set; } + + [JsonPropertyOrder(2)] + [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] + public Poco PropertyWithPopulate { get; set; } + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs index ed36a73e3ac80f..06fd59bae037e9 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs @@ -422,6 +422,7 @@ private static void TestTypeInfoImmutability(JsonTypeInfo typeInfo) Assert.Throws(() => typeInfo.Properties.Clear()); Assert.Throws(() => typeInfo.PolymorphismOptions = null); Assert.Throws(() => typeInfo.PolymorphismOptions = new()); + Assert.Throws(() => typeInfo.PreferredPropertyObjectCreationHandling = null); Assert.Throws(() => typeInfo.OriginatingResolver = new DefaultJsonTypeInfoResolver()); if (typeInfo.Properties.Count > 0) @@ -443,7 +444,7 @@ private static void TestTypeInfoImmutability(JsonTypeInfo typeInfo) Assert.Throws(() => jpo.DerivedTypes.Insert(0, default)); } - foreach (var property in typeInfo.Properties) + foreach (JsonPropertyInfo property in typeInfo.Properties) { Assert.NotNull(property.PropertyType); Assert.Null(property.CustomConverter); @@ -465,6 +466,14 @@ private static void TestTypeInfoImmutability(JsonTypeInfo typeInfo) Assert.NotNull(exception.InnerException); Assert.IsType(exception.InnerException); } + + Assert.Throws(() => property.Name = null); + Assert.Throws(() => property.ShouldSerialize = null); + Assert.Throws(() => property.Get = null); + Assert.Throws(() => property.Set = null); + Assert.Throws(() => property.ObjectCreationHandling = null); + Assert.Throws(() => property.IsExtensionData = true); + Assert.Throws(() => property.IsRequired = true); } } @@ -1422,6 +1431,35 @@ public static void UnmappedMemberHandling_SetInvalidValue_ThrowsArgumentOutOfRan Assert.Throws(() => jsonTypeInfo.UnmappedMemberHandling = handling); } + [Theory] + [InlineData(typeof(object))] + [InlineData(typeof(int))] + [InlineData(typeof(List))] + [InlineData(typeof(Dictionary))] + public static void PreferredPropertyObjectCreationHandling_NonObjectKind_ThrowsInvalidOperationException(Type type) + { + JsonTypeInfo jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(type, new()); + + // Invalid kinds default to null and can be set to null. + Assert.Null(jsonTypeInfo.PreferredPropertyObjectCreationHandling); + jsonTypeInfo.PreferredPropertyObjectCreationHandling = null; + Assert.Null(jsonTypeInfo.PreferredPropertyObjectCreationHandling); + + Assert.Throws(() => jsonTypeInfo.PreferredPropertyObjectCreationHandling = JsonObjectCreationHandling.Populate); + Assert.Throws(() => jsonTypeInfo.PreferredPropertyObjectCreationHandling = JsonObjectCreationHandling.Replace); + Assert.Null(jsonTypeInfo.PreferredPropertyObjectCreationHandling); + } + + [Theory] + [InlineData((JsonObjectCreationHandling)(-1))] + [InlineData((JsonObjectCreationHandling)2)] + [InlineData((JsonObjectCreationHandling)int.MaxValue)] + public static void PreferredPropertyObjectCreationHandling_SetInvalidValue_ThrowsArgumentOutOfRangeException(JsonObjectCreationHandling handling) + { + JsonTypeInfo jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(typeof(Poco), new()); + Assert.Throws(() => jsonTypeInfo.PreferredPropertyObjectCreationHandling = handling); + } + [Theory] [InlineData(typeof(int))] [InlineData(typeof(string))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PropertyNameTests.cs index 6da381d144dab7..09fb2c31287578 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PropertyNameTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; using System.Threading.Tasks; using Xunit; @@ -34,5 +35,34 @@ public async Task JsonNameConflictOnCaseInsensitiveFail() await Assert.ThrowsAsync(async () => await Serializer.SerializeWrapper(new IntPropertyNamesDifferentByCaseOnly_TestClass(), options)); } } + + [Fact] + public void CamelCasePolicyToleratesNullOrEmpty() + { + Assert.Null(JsonNamingPolicy.CamelCase.ConvertName(null)); + Assert.Equal(string.Empty, JsonNamingPolicy.CamelCase.ConvertName(string.Empty)); + } + + [Theory] + [MemberData(nameof(JsonSeparatorNamingPolicyInstances))] + public void InboxSeparatorNamingPolicies_ThrowsOnNullInput(JsonNamingPolicy policy) + { + Assert.Throws(() => policy.ConvertName(null)); + } + + [Theory] + [MemberData(nameof(JsonSeparatorNamingPolicyInstances))] + public void InboxSeparatorNamingPolicies_EmptyInput(JsonNamingPolicy policy) + { + Assert.Equal(string.Empty, policy.ConvertName(string.Empty)); + } + + public static IEnumerable JsonSeparatorNamingPolicyInstances() + { + yield return new object[] { JsonNamingPolicy.SnakeCaseLower }; + yield return new object[] { JsonNamingPolicy.SnakeCaseUpper }; + yield return new object[] { JsonNamingPolicy.KebabCaseLower }; + yield return new object[] { JsonNamingPolicy.KebabCaseUpper }; + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs index ec23f4f69e1b32..aa578a51e9c8ec 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.CompilerServices; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; @@ -78,9 +77,7 @@ public static async Task DeserializeAsyncEnumerable_ReadSourceAsync(IE [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(DeserializeAsyncEnumerableOverload overload) { string json = JsonSerializer.Serialize(Enumerable.Range(0, 100)); @@ -104,9 +101,7 @@ public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(Dese [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] public static async Task DeserializeAsyncEnumerable_ShouldTolerateCustomQueueConverters(DeserializeAsyncEnumerableOverload overload) { const int expectedCount = 20; @@ -160,11 +155,8 @@ private class DegenerateQueueConverter : JsonConverter> public static void DeserializeAsyncEnumerable_NullArgument_ThrowsArgumentNullException() { AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null)); - AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null, returnType: typeof(int))); AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null, jsonTypeInfo: ResolveJsonTypeInfo())); - AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null, jsonTypeInfo: ResolveJsonTypeInfo(typeof(int)))); AssertExtensions.Throws("jsonTypeInfo", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: new MemoryStream(), jsonTypeInfo: null)); - AssertExtensions.Throws("jsonTypeInfo", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: new MemoryStream(), jsonTypeInfo: null)); } [Theory] @@ -190,9 +182,7 @@ public static async Task DeserializeAsyncEnumerable_NotARootLevelJsonArray_Throw [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] public static async Task DeserializeAsyncEnumerable_CancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions @@ -216,9 +206,7 @@ await Assert.ThrowsAsync(async () => [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] public static async Task DeserializeAsyncEnumerable_EnumeratorWithCancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions @@ -243,41 +231,27 @@ await Assert.ThrowsAsync(async () => public static IEnumerable GetAsyncEnumerableSources() { yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); - yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions); yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.JsonTypeInfo); - yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo); yield return WrapArgs(Enumerable.Range(0, 20), 1, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); yield return WrapArgs(Enumerable.Range(0, 100), 20, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); yield return WrapArgs(Enumerable.Range(0, 100).Select(i => $"lorem ipsum dolor: {i}"), 500, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); yield return WrapArgs(Enumerable.Range(0, 100).Select(i => $"lorem ipsum dolor: {i}"), 500, DeserializeAsyncEnumerableOverload.JsonTypeInfo); yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); - yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions); yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.JsonTypeInfo); - yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo); yield return WrapArgs(Enumerable.Range(0, 100).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 500, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); static object[] WrapArgs(IEnumerable source, int bufferSize, DeserializeAsyncEnumerableOverload overload) => new object[] { source, bufferSize, overload }; } - public enum DeserializeAsyncEnumerableOverload { JsonSerializerOptions, UntypedJsonSerializerOptions, JsonTypeInfo, UntypedJsonTypeInfo }; + public enum DeserializeAsyncEnumerableOverload { JsonSerializerOptions, JsonTypeInfo }; private static IAsyncEnumerable DeserializeAsyncEnumerableWrapper(Stream stream, JsonSerializerOptions options = null, CancellationToken cancellationToken = default, DeserializeAsyncEnumerableOverload overload = DeserializeAsyncEnumerableOverload.JsonSerializerOptions) { return overload switch { DeserializeAsyncEnumerableOverload.JsonTypeInfo => JsonSerializer.DeserializeAsyncEnumerable(stream, ResolveJsonTypeInfo(options), cancellationToken), - DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo => Cast(JsonSerializer.DeserializeAsyncEnumerable(stream, ResolveJsonTypeInfo(typeof(T), options), cancellationToken)), - DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions => Cast(JsonSerializer.DeserializeAsyncEnumerable(stream, typeof(T), options, cancellationToken)), DeserializeAsyncEnumerableOverload.JsonSerializerOptions or _ => JsonSerializer.DeserializeAsyncEnumerable(stream, options, cancellationToken), }; - - static async IAsyncEnumerable Cast(IAsyncEnumerable source, [EnumeratorCancellation] CancellationToken token = default) - { - await foreach (object item in source.WithCancellation(token)) - { - yield return (T)item; - } - } } private static JsonTypeInfo ResolveJsonTypeInfo(JsonSerializerOptions? options = null) diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs index d1062f12febdf3..c3734c58f6927a 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs @@ -290,7 +290,7 @@ public async Task LargeJsonFile(int bufferSize) [InlineData(1000, false, false)] public async Task VeryLargeJsonFileTest(int payloadSize, bool ignoreNull, bool writeIndented) { - List list = JsonTestHelper.PopulateLargeObject(payloadSize); + List list = Order.PopulateLargeObject(payloadSize); JsonSerializerOptions options = new JsonSerializerOptions { @@ -338,10 +338,10 @@ public async Task DeepNestedJsonFileTest(int depthFactor, bool ignoreNull, bool int length = ListLength * depthFactor; List[] orders = new List[length]; - orders[0] = JsonTestHelper.PopulateLargeObject(1); + orders[0] = Order.PopulateLargeObject(1); for (int i = 1; i < length; i++ ) { - orders[i] = JsonTestHelper.PopulateLargeObject(1); + orders[i] = Order.PopulateLargeObject(1); orders[i - 1][0].RelatedOrder = orders[i]; } @@ -382,10 +382,10 @@ public async Task NestedJsonFileCircularDependencyTest(int depthFactor) int length = ListLength * depthFactor; List[] orders = new List[length]; - orders[0] = JsonTestHelper.PopulateLargeObject(1000); + orders[0] = Order.PopulateLargeObject(1000); for (int i = 1; i < length; i++) { - orders[i] = JsonTestHelper.PopulateLargeObject(1); + orders[i] = Order.PopulateLargeObject(1); orders[i - 1][0].RelatedOrder = orders[i]; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj index ac3753c325db00..8d0e4e67d83376 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj @@ -15,9 +15,13 @@ true true - 00:45:00 true + + --setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot + + 01:15:00 + @@ -49,6 +53,10 @@ + + + + @@ -153,6 +161,7 @@ + @@ -269,10 +278,10 @@ - + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs index a6689a0b01aa51..e625db93ab6742 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs @@ -12,6 +12,7 @@ using System.Text.Unicode; using System.Threading; using System.Threading.Tasks; +using Microsoft.DotNet.XUnitExtensions; using Newtonsoft.Json; using Xunit; @@ -3100,64 +3101,73 @@ public void WritingTooLargePropertyStandalone(bool formatted, bool skipValidatio [InlineData(false, false)] public void WritingTooLargeBase64Bytes(bool formatted, bool skipValidation) { - byte[] value; - try { - value = new byte[200_000_000]; - } - catch (OutOfMemoryException) - { - return; - } + byte[] value = new byte[200_000_000]; + value.AsSpan().Fill((byte)'a'); - value.AsSpan().Fill(255); + var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + var output = new ArrayBufferWriter(value.Length); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(1024); + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteBase64StringValue(value.AsSpan(0, 125_000_001)); + } + Assert.InRange(output.WrittenCount, 125_000_001, int.MaxValue); + output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - Assert.Throws(() => jsonUtf8.WriteBase64StringValue(value.AsSpan(0, 125_000_001))); - } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + Assert.Throws(() => jsonUtf8.WriteBase64String(value.AsSpan(0, 166_666_667), value.AsSpan(0, 1))); + } - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - Assert.Throws(() => jsonUtf8.WriteBase64String(value.AsSpan(0, 166_666_667), value.AsSpan(0, 1))); - } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + Assert.Throws(() => jsonUtf8.WriteBase64String(Encoding.UTF8.GetString(value).ToCharArray().AsSpan(0, 166_666_667), value.AsSpan(0, 1))); + } - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - Assert.Throws(() => jsonUtf8.WriteBase64String(Encoding.UTF8.GetString(value).ToCharArray().AsSpan(0, 166_666_667), value.AsSpan(0, 1))); - } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteBase64StringValue(value); + } + Assert.InRange(output.WrittenCount, Base64.GetMaxEncodedToUtf8Length(value.Length), int.MaxValue); + output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - Assert.Throws(() => jsonUtf8.WriteBase64StringValue(value)); - } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String("foo", value); + } + Assert.InRange(output.WrittenCount, Base64.GetMaxEncodedToUtf8Length(value.Length), int.MaxValue); + output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - jsonUtf8.WriteStartObject(); - Assert.Throws(() => jsonUtf8.WriteBase64String("foo", value)); - } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String("foo"u8, value); + } + Assert.InRange(output.WrittenCount, Base64.GetMaxEncodedToUtf8Length(value.Length), int.MaxValue); + output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - jsonUtf8.WriteStartObject(); - Assert.Throws(() => jsonUtf8.WriteBase64String("foo"u8, value)); - } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String("foo".AsSpan(), value); + } + Assert.InRange(output.WrittenCount, Base64.GetMaxEncodedToUtf8Length(value.Length), int.MaxValue); + output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - jsonUtf8.WriteStartObject(); - Assert.Throws(() => jsonUtf8.WriteBase64String("foo".AsSpan(), value)); + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String(JsonEncodedText.Encode("foo"), value); + } + Assert.InRange(output.WrittenCount, Base64.GetMaxEncodedToUtf8Length(value.Length), int.MaxValue); + output.Clear(); } - - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + catch (OutOfMemoryException) { - jsonUtf8.WriteStartObject(); - Assert.Throws(() => jsonUtf8.WriteBase64String(JsonEncodedText.Encode("foo"), value)); + throw new SkipTestException("Out of memory allocating large objects"); } } @@ -3172,59 +3182,57 @@ public void WritingTooLargeBase64Bytes(bool formatted, bool skipValidation) [InlineData(true, false)] [InlineData(false, true)] [InlineData(false, false)] - public void WritingLargestPossibleBase64Bytes(bool formatted, bool skipValidation) + public void WritingHugeBase64Bytes(bool formatted, bool skipValidation) { - byte[] value; - try { - value = new byte[125_000_000]; - } - catch (OutOfMemoryException) - { - return; - } + byte[] value = new byte[1_000_000_000]; - value.AsSpan().Fill(168); + value.AsSpan().Fill(168); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(1024); + var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + var output = new ArrayBufferWriter(1024); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - jsonUtf8.WriteBase64StringValue(value); - } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteBase64StringValue(value); + } - output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - jsonUtf8.WriteStartObject(); - jsonUtf8.WriteBase64String("foo", value); - jsonUtf8.WriteEndObject(); - } + output.Clear(); + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String("foo", value); + jsonUtf8.WriteEndObject(); + } - output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - jsonUtf8.WriteStartObject(); - jsonUtf8.WriteBase64String("foo"u8, value); - jsonUtf8.WriteEndObject(); - } + output.Clear(); + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String("foo"u8, value); + jsonUtf8.WriteEndObject(); + } - output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) - { - jsonUtf8.WriteStartObject(); - jsonUtf8.WriteBase64String("foo".AsSpan(), value); - jsonUtf8.WriteEndObject(); - } + output.Clear(); + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String("foo".AsSpan(), value); + jsonUtf8.WriteEndObject(); + } - output.Clear(); - using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + output.Clear(); + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteBase64String(JsonEncodedText.Encode("foo"), value); + jsonUtf8.WriteEndObject(); + } + } + catch (OutOfMemoryException) { - jsonUtf8.WriteStartObject(); - jsonUtf8.WriteBase64String(JsonEncodedText.Encode("foo"), value); - jsonUtf8.WriteEndObject(); + throw new SkipTestException("Out of memory allocating large objects"); } } diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs index 8cff7411be704a..870a3a00888851 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs @@ -378,20 +378,20 @@ private static void AddIsECMABoundaryHelper(Dictionary require } } - /// Adds an IndexOfAnyValues instance declaration to the required helpers collection if the chars are ASCII. - private static string EmitIndexOfAnyValuesOrLiteral(ReadOnlySpan chars, Dictionary requiredHelpers) + /// Adds a SearchValues instance declaration to the required helpers collection if the chars are ASCII. + private static string EmitSearchValuesOrLiteral(ReadOnlySpan chars, Dictionary requiredHelpers) { - // IndexOfAnyValues is faster than a regular IndexOfAny("abcd") for sets of 4/5 values iff they are ASCII. - // Only emit IndexOfAnyValues instances when we know they'll be faster to avoid increasing the startup cost too much. + // SearchValues is faster than a regular IndexOfAny("abcd") for sets of 4/5 values iff they are ASCII. + // Only emit SearchValues instances when we know they'll be faster to avoid increasing the startup cost too much. Debug.Assert(chars.Length is 4 or 5); return RegexCharClass.IsAscii(chars) - ? EmitIndexOfAnyValues(chars.ToArray(), requiredHelpers) + ? EmitSearchValues(chars.ToArray(), requiredHelpers) : Literal(chars.ToString()); } - /// Adds an IndexOfAnyValues instance declaration to the required helpers collection. - private static string EmitIndexOfAnyValues(char[] asciiChars, Dictionary requiredHelpers) + /// Adds a SearchValues instance declaration to the required helpers collection. + private static string EmitSearchValues(char[] asciiChars, Dictionary requiredHelpers) { Debug.Assert(RegexCharClass.IsAscii(asciiChars)); @@ -443,7 +443,7 @@ private static string EmitIndexOfAnyValues(char[] asciiChars, DictionarySupports searching for characters in or not in {EscapeXmlComment(setLiteral)}.", - $"internal static readonly IndexOfAnyValues {fieldName} = IndexOfAnyValues.Create({setLiteral});", + $"internal static readonly SearchValues {fieldName} = SearchValues.Create({setLiteral});", }); } @@ -452,7 +452,7 @@ private static string EmitIndexOfAnyValues(char[] asciiChars, Dictionary requiredHelpers, bool checkOverflow) { - // In order to optimize the search for ASCII characters, we use IndexOfAnyValues to vectorize a search + // In order to optimize the search for ASCII characters, we use SearchValues to vectorize a search // for those characters plus anything non-ASCII (if we find something non-ASCII, we'll fall back to // a sequential walk). In order to do that search, we actually build up a set for all of the ASCII // characters _not_ contained in the set, and then do a search for the inverse of that, which will be @@ -532,7 +532,7 @@ private static string EmitIndexOfAnyCustomHelper(string set, Dictionary= 0)")) { writer.WriteLine("base.runtextpos = pos + i;"); @@ -1056,9 +1063,9 @@ void EmitFixedSet_LeftToRight() 1 => $"{span}.IndexOf({Literal(primarySet.Chars[0])})", 2 => $"{span}.IndexOfAny({Literal(primarySet.Chars[0])}, {Literal(primarySet.Chars[1])})", 3 => $"{span}.IndexOfAny({Literal(primarySet.Chars[0])}, {Literal(primarySet.Chars[1])}, {Literal(primarySet.Chars[2])})", - _ => $"{span}.IndexOfAny({EmitIndexOfAnyValuesOrLiteral(primarySet.Chars, requiredHelpers)})", + _ => $"{span}.IndexOfAny({EmitSearchValuesOrLiteral(primarySet.Chars, requiredHelpers)})", } : - primarySet.AsciiSet is not null ? $"{span}.IndexOfAny({EmitIndexOfAnyValues(primarySet.AsciiSet, requiredHelpers)})" : + primarySet.AsciiSet is not null ? $"{span}.IndexOfAny({EmitSearchValues(primarySet.AsciiSet, requiredHelpers)})" : primarySet.Range is not null ? (primarySet.Range.Value.LowInclusive == primarySet.Range.Value.HighInclusive, primarySet.Negated) switch { (false, false) => $"{span}.IndexOfAnyInRange({Literal(primarySet.Range.Value.LowInclusive)}, {Literal(primarySet.Range.Value.HighInclusive)})", @@ -1227,7 +1234,7 @@ void EmitLiteralAfterAtomicLoop() { 2 => $"IndexOfAny({Literal(literalChars[0])}, {Literal(literalChars[1])});", 3 => $"IndexOfAny({Literal(literalChars[0])}, {Literal(literalChars[1])}, {Literal(literalChars[2])});", - _ => $"IndexOfAny({EmitIndexOfAnyValuesOrLiteral(literalChars, requiredHelpers)});", + _ => $"IndexOfAny({EmitSearchValuesOrLiteral(literalChars, requiredHelpers)});", }); FinishEmitBlock indexOfFoundBlock = default; @@ -3322,10 +3329,10 @@ literal.SetChars is not null || { (true, 2) => $"{startingPos} = {sliceSpan}.IndexOfAny({Literal(literal.SetChars[0])}, {Literal(literal.SetChars[1])});", (true, 3) => $"{startingPos} = {sliceSpan}.IndexOfAny({Literal(literal.SetChars[0])}, {Literal(literal.SetChars[1])}, {Literal(literal.SetChars[2])});", - (true, _) => $"{startingPos} = {sliceSpan}.IndexOfAny({EmitIndexOfAnyValuesOrLiteral(literal.SetChars.AsSpan(), requiredHelpers)});", + (true, _) => $"{startingPos} = {sliceSpan}.IndexOfAny({EmitSearchValuesOrLiteral(literal.SetChars.AsSpan(), requiredHelpers)});", (false, 2) => $"{startingPos} = {sliceSpan}.IndexOfAny({Literal(node.Ch)}, {Literal(literal.SetChars[0])}, {Literal(literal.SetChars[1])});", - (false, _) => $"{startingPos} = {sliceSpan}.IndexOfAny({EmitIndexOfAnyValuesOrLiteral($"{node.Ch}{literal.SetChars}".AsSpan(), requiredHelpers)});", + (false, _) => $"{startingPos} = {sliceSpan}.IndexOfAny({EmitSearchValuesOrLiteral($"{node.Ch}{literal.SetChars}".AsSpan(), requiredHelpers)});", }); } else if (literal.AsciiChars is not null) // set of only ASCII characters @@ -3338,7 +3345,7 @@ literal.SetChars is not null || Array.Resize(ref asciiChars, asciiChars.Length + 1); asciiChars[asciiChars.Length - 1] = node.Ch; } - writer.WriteLine($"{startingPos} = {sliceSpan}.IndexOfAny({EmitIndexOfAnyValues(asciiChars, requiredHelpers)});"); + writer.WriteLine($"{startingPos} = {sliceSpan}.IndexOfAny({EmitSearchValues(asciiChars, requiredHelpers)});"); } else if (literal.Range.LowInclusive == literal.Range.HighInclusive) // single char from a RegexNode.One { @@ -4633,7 +4640,7 @@ private static bool TryEmitIndexOf( 1 => $"{last}{indexOfName}({Literal(setChars[0])})", 2 => $"{last}{indexOfAnyName}({Literal(setChars[0])}, {Literal(setChars[1])})", 3 => $"{last}{indexOfAnyName}({Literal(setChars[0])}, {Literal(setChars[1])}, {Literal(setChars[2])})", - _ => $"{last}{indexOfAnyName}({EmitIndexOfAnyValuesOrLiteral(setChars, requiredHelpers)})", + _ => $"{last}{indexOfAnyName}({EmitSearchValuesOrLiteral(setChars, requiredHelpers)})", }; literalLength = 1; @@ -4646,7 +4653,7 @@ private static bool TryEmitIndexOf( "IndexOfAny" : "IndexOfAnyExcept"; - indexOfExpr = $"{last}{indexOfAnyName}({EmitIndexOfAnyValues(asciiChars, requiredHelpers)})"; + indexOfExpr = $"{last}{indexOfAnyName}({EmitSearchValues(asciiChars, requiredHelpers)})"; literalLength = 1; return true; diff --git a/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj b/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj index 8f2a65c0b3f6d5..1b900f0552c678 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj +++ b/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj @@ -7,8 +7,8 @@ + - diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunner.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunner.cs index 11ad1fc3c21c87..b58f584662ed9a 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunner.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunner.cs @@ -10,7 +10,7 @@ internal sealed class CompiledRegexRunner : RegexRunner { private readonly ScanDelegate _scanMethod; - private readonly IndexOfAnyValues[]? _indexOfAnyValues; + private readonly SearchValues[]? _searchValues; /// This field will only be set if the pattern contains backreferences and has RegexOptions.IgnoreCase private readonly CultureInfo? _culture; @@ -21,10 +21,10 @@ internal sealed class CompiledRegexRunner : RegexRunner internal delegate void ScanDelegate(RegexRunner runner, ReadOnlySpan text); - public CompiledRegexRunner(ScanDelegate scan, IndexOfAnyValues[]? indexOfAnyValues, CultureInfo? culture) + public CompiledRegexRunner(ScanDelegate scan, SearchValues[]? searchValues, CultureInfo? culture) { _scanMethod = scan; - _indexOfAnyValues = indexOfAnyValues; + _searchValues = searchValues; _culture = culture; } diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs index 5d21799b339fe9..6784f068d1c559 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs @@ -10,22 +10,22 @@ namespace System.Text.RegularExpressions internal sealed class CompiledRegexRunnerFactory : RegexRunnerFactory { private readonly DynamicMethod _scanMethod; - private readonly IndexOfAnyValues[]? _indexOfAnyValues; + private readonly SearchValues[]? _searchValues; /// This field will only be set if the pattern has backreferences and uses RegexOptions.IgnoreCase private readonly CultureInfo? _culture; // Delegate is lazily created to avoid forcing JIT'ing until the regex is actually executed. private CompiledRegexRunner.ScanDelegate? _scan; - public CompiledRegexRunnerFactory(DynamicMethod scanMethod, IndexOfAnyValues[]? indexOfAnyValues, CultureInfo? culture) + public CompiledRegexRunnerFactory(DynamicMethod scanMethod, SearchValues[]? searchValues, CultureInfo? culture) { _scanMethod = scanMethod; - _indexOfAnyValues = indexOfAnyValues; + _searchValues = searchValues; _culture = culture; } protected internal override RegexRunner CreateInstance() => new CompiledRegexRunner( - _scan ??= _scanMethod.CreateDelegate(), _indexOfAnyValues, _culture); + _scan ??= _scanMethod.CreateDelegate(), _searchValues, _culture); } } diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Match.cs index 5a4e65eebec6fc..6421f93d2c5101 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Match.cs @@ -125,9 +125,9 @@ public virtual string Result(string replacement) // Gets the weakly cached replacement helper or creates one if there isn't one already. RegexReplacement repl = RegexReplacement.GetOrCreate(regex.RegexReplacementWeakReference, replacement, regex.caps!, regex.capsize, regex.capnames!, regex.roptions); - SegmentStringBuilder segments = SegmentStringBuilder.Create(); + var segments = new StructListBuilder>(); repl.ReplacementImpl(ref segments, this); - return segments.ToString(); + return Regex.SegmentsToStringAndDispose(ref segments); } internal ReadOnlyMemory GroupToStringImpl(int groupnum) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Replace.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Replace.cs index 161ce09f0bd930..5cbd1008cdb002 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Replace.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Replace.cs @@ -3,6 +3,8 @@ using System.Diagnostics.CodeAnalysis; +#pragma warning disable CS8500 // takes address of managed type + namespace System.Text.RegularExpressions { // Callback class @@ -172,11 +174,11 @@ private static string Replace(MatchEvaluator evaluator, Regex regex, string inpu return input; } - var state = (segments: SegmentStringBuilder.Create(), evaluator, prevat: 0, input, count); + var state = (segments: new StructListBuilder>(), evaluator, prevat: 0, input, count); if (!regex.RightToLeft) { - regex.RunAllMatchesWithCallback(input, startat, ref state, static (ref (SegmentStringBuilder segments, MatchEvaluator evaluator, int prevat, string input, int count) state, Match match) => + regex.RunAllMatchesWithCallback(input, startat, ref state, static (ref (StructListBuilder> segments, MatchEvaluator evaluator, int prevat, string input, int count) state, Match match) => { state.segments.Add(state.input.AsMemory(state.prevat, match.Index - state.prevat)); state.prevat = match.Index + match.Length; @@ -195,7 +197,7 @@ private static string Replace(MatchEvaluator evaluator, Regex regex, string inpu { state.prevat = input.Length; - regex.RunAllMatchesWithCallback(input, startat, ref state, static (ref (SegmentStringBuilder segments, MatchEvaluator evaluator, int prevat, string input, int count) state, Match match) => + regex.RunAllMatchesWithCallback(input, startat, ref state, static (ref (StructListBuilder> segments, MatchEvaluator evaluator, int prevat, string input, int count) state, Match match) => { state.segments.Add(state.input.AsMemory(match.Index + match.Length, state.prevat - match.Index - match.Length)); state.prevat = match.Index; @@ -212,7 +214,35 @@ private static string Replace(MatchEvaluator evaluator, Regex regex, string inpu state.segments.AsSpan().Reverse(); } - return state.segments.ToString(); + return SegmentsToStringAndDispose(ref state.segments); + } + + /// Creates a string from all the segments in the builder and then disposes of the builder. + internal static unsafe string SegmentsToStringAndDispose(ref StructListBuilder> segments) + { + Span> span = segments.AsSpan(); + + int length = 0; + for (int i = 0; i < span.Length; i++) + { + length += span[i].Length; + } + + ReadOnlySpan> tmpSpan = span; // avoid address exposing the span and impacting the other code in the method that uses it + string result = string.Create(length, (IntPtr)(&tmpSpan), static (dest, spanPtr) => + { + Span> span = *(Span>*)spanPtr; + for (int i = 0; i < span.Length; i++) + { + ReadOnlySpan segment = span[i].Span; + segment.CopyTo(dest); + dest = dest.Slice(segment.Length); + } + }); + + segments.Dispose(); + + return result; } } } diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs index f9be28acceeeb2..51a1a4cd23cde1 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs @@ -26,7 +26,7 @@ internal abstract class RegexCompiler private static readonly FieldInfo s_runstackField = RegexRunnerField("runstack"); private static readonly FieldInfo s_cultureField = typeof(CompiledRegexRunner).GetField("_culture", BindingFlags.Instance | BindingFlags.NonPublic)!; private static readonly FieldInfo s_caseBehaviorField = typeof(CompiledRegexRunner).GetField("_caseBehavior", BindingFlags.Instance | BindingFlags.NonPublic)!; - private static readonly FieldInfo s_indexOfAnyValuesArrayField = typeof(CompiledRegexRunner).GetField("_indexOfAnyValues", BindingFlags.Instance | BindingFlags.NonPublic)!; + private static readonly FieldInfo s_searchValuesArrayField = typeof(CompiledRegexRunner).GetField("_searchValues", BindingFlags.Instance | BindingFlags.NonPublic)!; private static readonly MethodInfo s_captureMethod = RegexRunnerMethod("Capture"); private static readonly MethodInfo s_transferCaptureMethod = RegexRunnerMethod("TransferCapture"); @@ -66,28 +66,29 @@ internal abstract class RegexCompiler private static readonly MethodInfo s_spanGetLengthMethod = typeof(ReadOnlySpan).GetMethod("get_Length")!; private static readonly MethodInfo s_spanIndexOfChar = typeof(MemoryExtensions).GetMethod("IndexOf", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfSpan = typeof(MemoryExtensions).GetMethod("IndexOf", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); + private static readonly MethodInfo s_spanIndexOfSpanStringComparison = typeof(MemoryExtensions).GetMethod("IndexOf", new Type[] { typeof(ReadOnlySpan), typeof(ReadOnlySpan), typeof(StringComparison) })!; private static readonly MethodInfo s_spanIndexOfAnyCharChar = typeof(MemoryExtensions).GetMethod("IndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnyCharCharChar = typeof(MemoryExtensions).GetMethod("IndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnySpan = typeof(MemoryExtensions).GetMethod("IndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); - private static readonly MethodInfo s_spanIndexOfAnyIndexOfAnyValues = typeof(MemoryExtensions).GetMethod("IndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(IndexOfAnyValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); + private static readonly MethodInfo s_spanIndexOfAnySearchValues = typeof(MemoryExtensions).GetMethod("IndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(SearchValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnyExceptChar = typeof(MemoryExtensions).GetMethod("IndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnyExceptCharChar = typeof(MemoryExtensions).GetMethod("IndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnyExceptCharCharChar = typeof(MemoryExtensions).GetMethod("IndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnyExceptSpan = typeof(MemoryExtensions).GetMethod("IndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); - private static readonly MethodInfo s_spanIndexOfAnyExceptIndexOfAnyValues = typeof(MemoryExtensions).GetMethod("IndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(IndexOfAnyValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); + private static readonly MethodInfo s_spanIndexOfAnyExceptSearchValues = typeof(MemoryExtensions).GetMethod("IndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(SearchValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnyInRange = typeof(MemoryExtensions).GetMethod("IndexOfAnyInRange", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanIndexOfAnyExceptInRange = typeof(MemoryExtensions).GetMethod("IndexOfAnyExceptInRange", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfChar = typeof(MemoryExtensions).GetMethod("LastIndexOf", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyCharChar = typeof(MemoryExtensions).GetMethod("LastIndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyCharCharChar = typeof(MemoryExtensions).GetMethod("LastIndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnySpan = typeof(MemoryExtensions).GetMethod("LastIndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); - private static readonly MethodInfo s_spanLastIndexOfAnyIndexOfAnyValues = typeof(MemoryExtensions).GetMethod("LastIndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(IndexOfAnyValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); + private static readonly MethodInfo s_spanLastIndexOfAnySearchValues = typeof(MemoryExtensions).GetMethod("LastIndexOfAny", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(SearchValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfSpan = typeof(MemoryExtensions).GetMethod("LastIndexOf", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyExceptChar = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyExceptCharChar = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyExceptCharCharChar = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyExceptSpan = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); - private static readonly MethodInfo s_spanLastIndexOfAnyExceptIndexOfAnyValues = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(IndexOfAnyValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); + private static readonly MethodInfo s_spanLastIndexOfAnyExceptSearchValues = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyExcept", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(SearchValues<>).MakeGenericType(Type.MakeGenericMethodParameter(0)) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyInRange = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyInRange", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanLastIndexOfAnyExceptInRange = typeof(MemoryExtensions).GetMethod("LastIndexOfAnyExceptInRange", new Type[] { typeof(ReadOnlySpan<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(0) })!.MakeGenericMethod(typeof(char)); private static readonly MethodInfo s_spanSliceIntMethod = typeof(ReadOnlySpan).GetMethod("Slice", new Type[] { typeof(int) })!; @@ -98,7 +99,7 @@ internal abstract class RegexCompiler private static readonly MethodInfo s_stringGetCharsMethod = typeof(string).GetMethod("get_Chars", new Type[] { typeof(int) })!; private static readonly MethodInfo s_arrayResize = typeof(Array).GetMethod("Resize")!.MakeGenericMethod(typeof(int)); private static readonly MethodInfo s_mathMinIntInt = typeof(Math).GetMethod("Min", new Type[] { typeof(int), typeof(int) })!; - private static readonly MethodInfo s_memoryMarshalGetArrayDataReferenceIndexOfAnyValues = typeof(MemoryMarshal).GetMethod("GetArrayDataReference", new Type[] { Type.MakeGenericMethodParameter(0).MakeArrayType() })!.MakeGenericMethod(typeof(IndexOfAnyValues))!; + private static readonly MethodInfo s_memoryMarshalGetArrayDataReferenceSearchValues = typeof(MemoryMarshal).GetMethod("GetArrayDataReference", new Type[] { Type.MakeGenericMethodParameter(0).MakeArrayType() })!.MakeGenericMethod(typeof(SearchValues))!; // Note: // Single-range helpers like IsAsciiLetterLower, IsAsciiLetterUpper, IsAsciiDigit, and IsBetween aren't used here, as the IL generated for those // single-range checks is as cheap as the method call, and there's no readability issue as with the source generator. @@ -112,8 +113,8 @@ internal abstract class RegexCompiler /// Whether this expression has a non-infinite timeout. protected bool _hasTimeout; - /// instances used by the expression. For now these are only ASCII sets. - protected List>? _indexOfAnyValues; + /// instances used by the expression. For now these are only ASCII sets. + protected List>? _searchValues; /// Pool of Int32 LocalBuilders. private Stack? _int32LocalsPool; @@ -456,6 +457,7 @@ protected void EmitTryFindNextPossibleStartingPosition() switch (_regexTree.FindOptimizations.FindMode) { case FindNextStartingPositionMode.LeadingString_LeftToRight: + case FindNextStartingPositionMode.LeadingString_OrdinalIgnoreCase_LeftToRight: case FindNextStartingPositionMode.FixedDistanceString_LeftToRight: EmitIndexOf_LeftToRight(); break; @@ -745,25 +747,33 @@ bool EmitAnchors() void EmitIndexOf_LeftToRight() { RegexFindOptimizations opts = _regexTree.FindOptimizations; - Debug.Assert(opts.FindMode is FindNextStartingPositionMode.LeadingString_LeftToRight or FindNextStartingPositionMode.FixedDistanceString_LeftToRight); + Debug.Assert(opts.FindMode is FindNextStartingPositionMode.LeadingString_LeftToRight or FindNextStartingPositionMode.LeadingString_OrdinalIgnoreCase_LeftToRight or FindNextStartingPositionMode.FixedDistanceString_LeftToRight); using RentedLocalBuilder i = RentInt32Local(); // int i = inputSpan.Slice(pos).IndexOf(prefix); Ldloca(inputSpan); Ldloc(pos); - if (opts.FindMode == FindNextStartingPositionMode.FixedDistanceString_LeftToRight && + if (opts.FindMode is FindNextStartingPositionMode.FixedDistanceString_LeftToRight && opts.FixedDistanceLiteral is { Distance: > 0 } literal) { Ldc(literal.Distance); Add(); } Call(s_spanSliceIntMethod); - Ldstr(opts.FindMode == FindNextStartingPositionMode.LeadingString_LeftToRight ? + Ldstr(opts.FindMode is FindNextStartingPositionMode.LeadingString_LeftToRight or FindNextStartingPositionMode.LeadingString_OrdinalIgnoreCase_LeftToRight ? opts.LeadingPrefix : opts.FixedDistanceLiteral.String!); Call(s_stringAsSpanMethod); - Call(s_spanIndexOfSpan); + if (opts.FindMode is FindNextStartingPositionMode.LeadingString_OrdinalIgnoreCase_LeftToRight) + { + Ldc((int)StringComparison.OrdinalIgnoreCase); + Call(s_spanIndexOfSpanStringComparison); + } + else + { + Call(s_spanIndexOfSpan); + } Stloc(i); // if (i < 0) goto ReturnFalse; @@ -927,8 +937,8 @@ void EmitFixedSet_LeftToRight() else if (primarySet.AsciiSet is not null) { Debug.Assert(!primarySet.Negated); - LoadIndexOfAnyValues(primarySet.AsciiSet); - Call(s_spanIndexOfAnyIndexOfAnyValues); + LoadSearchValues(primarySet.AsciiSet); + Call(s_spanIndexOfAnySearchValues); } else if (primarySet.Range is not null) { @@ -948,7 +958,7 @@ void EmitFixedSet_LeftToRight() } else { - // In order to optimize the search for ASCII characters, we use IndexOfAnyValues to vectorize a search + // In order to optimize the search for ASCII characters, we use SearchValues to vectorize a search // for those characters plus anything non-ASCII (if we find something non-ASCII, we'll fall back to // a sequential walk). In order to do that search, we actually build up a set for all of the ASCII // characters _not_ contained in the set, and then do a search for the inverse of that, which will be @@ -979,9 +989,9 @@ void EmitFixedSet_LeftToRight() } else { - // IndexOfAnyExcept(indexOfAnyValuesArray[...]); - LoadIndexOfAnyValues(CollectionsMarshal.AsSpan(asciiChars)); - Call(s_spanIndexOfAnyExceptIndexOfAnyValues); + // IndexOfAnyExcept(searchValuesArray[...]); + LoadSearchValues(CollectionsMarshal.AsSpan(asciiChars)); + Call(s_spanIndexOfAnyExceptSearchValues); } Stloc(i); @@ -3575,8 +3585,8 @@ literal.SetChars is not null || Array.Resize(ref asciiChars, asciiChars.Length + 1); asciiChars[^1] = node.Ch; } - LoadIndexOfAnyValues(asciiChars); - Call(s_spanIndexOfAnyIndexOfAnyValues); + LoadSearchValues(asciiChars); + Call(s_spanIndexOfAnySearchValues); } else if (literal.Range.LowInclusive == literal.Range.HighInclusive) // single char from a RegexNode.One { @@ -5190,16 +5200,16 @@ void EmitIndexOf(RegexNode node, bool useLast, bool negate) } } - // IndexOfAny{Except}(IndexOfAnyValues) + // IndexOfAny{Except}(SearchValues) if (RegexCharClass.TryGetAsciiSetChars(node.Str, out char[]? asciiChars)) { - LoadIndexOfAnyValues(asciiChars); + LoadSearchValues(asciiChars); Call((useLast, negated) switch { - (false, false) => s_spanIndexOfAnyIndexOfAnyValues, - (false, true) => s_spanIndexOfAnyExceptIndexOfAnyValues, - (true, false) => s_spanLastIndexOfAnyIndexOfAnyValues, - (true, true) => s_spanLastIndexOfAnyExceptIndexOfAnyValues, + (false, false) => s_spanIndexOfAnySearchValues, + (false, true) => s_spanIndexOfAnyExceptSearchValues, + (true, false) => s_spanLastIndexOfAnySearchValues, + (true, true) => s_spanLastIndexOfAnyExceptSearchValues, }); return; } @@ -6096,21 +6106,21 @@ private void EmitTimeoutCheckIfNeeded() } /// - /// Adds an entry in for the given and emits a load of that initialized value. + /// Adds an entry in for the given and emits a load of that initialized value. /// - private void LoadIndexOfAnyValues(ReadOnlySpan chars) + private void LoadSearchValues(ReadOnlySpan chars) { - List> list = _indexOfAnyValues ??= new(); + List> list = _searchValues ??= new(); int index = list.Count; - list.Add(IndexOfAnyValues.Create(chars)); + list.Add(SearchValues.Create(chars)); - // Logically do _indexOfAnyValues[index], but avoid the bounds check on accessing the array, + // Logically do _searchValues[index], but avoid the bounds check on accessing the array, // and cast to the known derived sealed type to enable devirtualization. - // DerivedIndexOfAnyValues d = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(this._indexOfAnyValues), index); + // DerivedSearchValues d = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(this._searchValues), index); // ... = d; - Ldthisfld(s_indexOfAnyValuesArrayField); - Call(s_memoryMarshalGetArrayDataReferenceIndexOfAnyValues); + Ldthisfld(s_searchValuesArrayField); + Call(s_memoryMarshalGetArrayDataReferenceSearchValues); Ldc(index * IntPtr.Size); Add(); _ilg!.Emit(OpCodes.Ldind_Ref); diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexFindOptimizations.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexFindOptimizations.cs index d02c74a70c7b6e..113c0749f5af47 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexFindOptimizations.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexFindOptimizations.cs @@ -66,7 +66,7 @@ public RegexFindOptimizations(RegexNode root, RegexOptions options) } // If there's a leading substring, just use IndexOf and inherit all of its optimizations. - string prefix = RegexPrefixAnalyzer.FindPrefix(root); + string? prefix = RegexPrefixAnalyzer.FindPrefix(root); if (prefix.Length > 1) { LeadingPrefix = prefix; @@ -126,6 +126,16 @@ public RegexFindOptimizations(RegexNode root, RegexOptions options) return; } + // We're now left-to-right only. + + prefix = RegexPrefixAnalyzer.FindPrefixOrdinalCaseInsensitive(root); + if (prefix is { Length: > 1 }) + { + LeadingPrefix = prefix; + FindMode = FindNextStartingPositionMode.LeadingString_OrdinalIgnoreCase_LeftToRight; + return; + } + // We're now left-to-right only and looking for sets. // Build up a list of all of the sets that are a fixed distance from the start of the expression. @@ -547,6 +557,21 @@ public bool TryFindNextStartingPositionLeftToRight(ReadOnlySpan textSpan, return false; } + // There's a case-insensitive prefix. Search for it with ordinal case-insensitive IndexOf. + + case FindNextStartingPositionMode.LeadingString_OrdinalIgnoreCase_LeftToRight: + { + int i = textSpan.Slice(pos).IndexOf(LeadingPrefix.AsSpan(), StringComparison.OrdinalIgnoreCase); + if (i >= 0) + { + pos += i; + return true; + } + + pos = textSpan.Length; + return false; + } + // There's a set at the beginning of the pattern. Search for it. case FindNextStartingPositionMode.LeadingSet_LeftToRight: @@ -776,6 +801,8 @@ internal enum FindNextStartingPositionMode LeadingString_LeftToRight, /// A multi-character substring at the beginning of the right-to-left pattern. LeadingString_RightToLeft, + /// A multi-character ordinal case-insensitive substring at the beginning of the pattern. + LeadingString_OrdinalIgnoreCase_LeftToRight, /// A set starting the pattern. LeadingSet_LeftToRight, diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs index edeb6976c5312c..858a7349705cb3 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs @@ -63,7 +63,7 @@ internal sealed class RegexLWCGCompiler : RegexCompiler DynamicMethod scanMethod = DefineDynamicMethod($"Regex{regexNum}_Scan{description}", null, typeof(CompiledRegexRunner), new[] { typeof(RegexRunner), typeof(ReadOnlySpan) }); EmitScan(options, tryfindNextPossibleStartPositionMethod, tryMatchAtCurrentPositionMethod); - return new CompiledRegexRunnerFactory(scanMethod, _indexOfAnyValues?.ToArray(), regexTree.Culture); + return new CompiledRegexRunnerFactory(scanMethod, _searchValues?.ToArray(), regexTree.Culture); } /// Begins the definition of a new method (no args) with a specified return value. diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs index 7634cda0a377b3..16e96ea2d69a0f 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs @@ -2077,8 +2077,8 @@ internal static int MapCaptureNumber(int capnum, Hashtable? caps) => 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Q, S, 0, 0, 0}; #if NET8_0_OR_GREATER - private static readonly IndexOfAnyValues s_metachars = - IndexOfAnyValues.Create("\t\n\f\r #$()*+.?[\\^{|"); + private static readonly SearchValues s_metachars = + SearchValues.Create("\t\n\f\r #$()*+.?[\\^{|"); private static int IndexOfMetachar(ReadOnlySpan input) => input.IndexOfAny(s_metachars); diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs index ccf33f6fe1987b..88553b3b7d1130 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs @@ -155,6 +155,31 @@ static bool Process(RegexNode node, ref ValueStringBuilder vsb) } } + /// Computes the leading ordinal case-insensitive substring in . + public static string? FindPrefixOrdinalCaseInsensitive(RegexNode node) + { + while (true) + { + // Search down the left side of the tree looking for a concatenation. If we find one, + // ask it for any ordinal case-insensitive prefix it has. + switch (node.Kind) + { + case RegexNodeKind.Atomic: + case RegexNodeKind.Capture: + case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when node.M > 0: + node = node.Child(0); + continue; + + case RegexNodeKind.Concatenate: + node.TryGetOrdinalCaseInsensitiveString(0, node.ChildCount(), out _, out string? caseInsensitiveString); + return caseInsensitiveString; + + default: + return null; + } + } + } + /// Finds sets at fixed-offsets from the beginning of the pattern/ /// The RegexNode tree root. /// true to spend more time finding sets (e.g. through alternations); false to do a faster analysis that's potentially more incomplete. diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs index 45ade777de8662..3b6259307fb9f5 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs @@ -6,6 +6,8 @@ using System.Diagnostics; using System.Runtime.InteropServices; +#pragma warning disable CS8500 // takes address of managed type + namespace System.Text.RegularExpressions { /// @@ -126,7 +128,7 @@ public static RegexReplacement GetOrCreate(WeakReference repl /// Given a Match, emits into the StringBuilder the evaluated /// substitution pattern. /// - public void ReplacementImpl(ref SegmentStringBuilder segments, Match match) + public void ReplacementImpl(ref StructListBuilder> segments, Match match) { foreach (int rule in _rules) { @@ -157,7 +159,7 @@ public void ReplacementImpl(ref SegmentStringBuilder segments, Match match) /// Given a Match, emits into the builder the evaluated /// Right-to-Left substitution pattern. /// - public void ReplacementImplRTL(ref SegmentStringBuilder segments, Match match) + public void ReplacementImplRTL(ref StructListBuilder> segments, Match match) { for (int i = _rules.Length - 1; i >= 0; i--) { @@ -210,11 +212,99 @@ public string Replace(Regex regex, string input, int count, int startat) return input; } - var state = (replacement: this, segments: SegmentStringBuilder.Create(), inputMemory: input.AsMemory(), prevat: 0, count); + // Handle the common case of a left-to-right pattern with no backreferences in the replacement pattern such that the replacement is just a string of text. + if (!regex.RightToLeft && !_hasBackreferences) + { + // With no backreferences, there should either be no rules (in the case of an empty replacement) + // or one rule (in the case of a single text string). + Debug.Assert(_rules.Length <= 1); + Debug.Assert(_rules.Length == 0 || (_rules[0] == 0 && _strings.Length == 1)); + + return ReplaceSimpleText(regex, input, _rules.Length != 0 ? _strings[0] : "", count, startat); + } + else + { + return ReplaceNonSimpleText(regex, input, count, startat); + } + } + + private static unsafe string ReplaceSimpleText(Regex regex, string input, string replacement, int count, int startat) + { + // As the replacement text is the same for every match, for every match we can simply store the offset/count for the match. + // As we only split the input when there's a replacement, we know that there's then replacement text to be inserted between + // every offset/count pair in the list. + + var state = (input, replacement, offsetAndCounts: new StructListBuilder(), inputMemory: input.AsMemory(), prevat: 0, count); + string result = input; + + regex.RunAllMatchesWithCallback(input, startat, ref state, (ref (string input, string replacement, StructListBuilder segments, ReadOnlyMemory inputMemory, int prevat, int count) state, Match match) => + { + // Store the offset/count pair for the match. + state.segments.Add(state.prevat); + state.segments.Add(match.Index - state.prevat); + + // Update the previous offset to be the end of the match. + state.prevat = match.Index + match.Length; + + // Update the number of matches and return whether to continue. + return --state.count != 0; + }, RegexRunnerMode.BoundsRequired, reuseMatchObject: true); + + // If the list is empty, there were no matches and we can just return the input string. + // If the list isn't empty, we need to compose the result string. + if (state.offsetAndCounts.Count != 0) + { + // Add the final offset/count pair for the text after the last match. + state.offsetAndCounts.Add(state.prevat); + state.offsetAndCounts.Add(input.Length - state.prevat); + + // There should now be an even number of items in the list, as each offset and count is its + // own entry and they're added in pairs. And there should be at least four entries, one for + // the first segment and one for the last. + Debug.Assert(state.offsetAndCounts.Count % 2 == 0, $"{state.offsetAndCounts.Count}"); + Debug.Assert(state.offsetAndCounts.Count >= 4, $"{state.offsetAndCounts.Count}"); + + Span span = state.offsetAndCounts.AsSpan(); + + // Determine the final string length. + int length = ((span.Length / 2) - 1) * replacement.Length; + for (int i = 1; i < span.Length; i += 2) // the count of each pair is the second item + { + length += span[i]; + } + + ReadOnlySpan tmpSpan = span; // avoid address exposing the span and impacting the other code in the method that uses it + result = string.Create(length, ((IntPtr)(&tmpSpan), input, replacement), static (dest, state) => + { + Span span = *(Span*)state.Item1; + for (int i = 0; i < span.Length; i += 2) + { + if (i != 0) + { + state.replacement.CopyTo(dest); + dest = dest.Slice(state.replacement.Length); + } + + (int offset, int count) = (span[i], span[i + 1]); + state.input.AsSpan(offset, count).CopyTo(dest); + dest = dest.Slice(count); + } + }); + } + + state.offsetAndCounts.Dispose(); + + return result; + } + + /// Handles cases other than left-to-right with a simple replacement string. + private string ReplaceNonSimpleText(Regex regex, string input, int count, int startat) + { + var state = (replacement: this, segments: new StructListBuilder>(), inputMemory: input.AsMemory(), prevat: 0, count); if (!regex.RightToLeft) { - regex.RunAllMatchesWithCallback(input, startat, ref state, (ref (RegexReplacement thisRef, SegmentStringBuilder segments, ReadOnlyMemory inputMemory, int prevat, int count) state, Match match) => + regex.RunAllMatchesWithCallback(input, startat, ref state, (ref (RegexReplacement thisRef, StructListBuilder> segments, ReadOnlyMemory inputMemory, int prevat, int count) state, Match match) => { state.segments.Add(state.inputMemory.Slice(state.prevat, match.Index - state.prevat)); state.prevat = match.Index + match.Length; @@ -227,13 +317,14 @@ public string Replace(Regex regex, string input, int count, int startat) return input; } + // Final segment of the input string after the last match. state.segments.Add(state.inputMemory.Slice(state.prevat)); } else { state.prevat = input.Length; - regex.RunAllMatchesWithCallback(input, startat, ref state, (ref (RegexReplacement thisRef, SegmentStringBuilder segments, ReadOnlyMemory inputMemory, int prevat, int count) state, Match match) => + regex.RunAllMatchesWithCallback(input, startat, ref state, (ref (RegexReplacement thisRef, StructListBuilder> segments, ReadOnlyMemory inputMemory, int prevat, int count) state, Match match) => { state.segments.Add(state.inputMemory.Slice(match.Index + match.Length, state.prevat - match.Index - match.Length)); state.prevat = match.Index; @@ -246,11 +337,15 @@ public string Replace(Regex regex, string input, int count, int startat) return input; } + // Final segment of the input string after the last match. state.segments.Add(state.inputMemory.Slice(0, state.prevat)); + + // Reverse the segments as we're dealing with right-to-left handling. state.segments.AsSpan().Reverse(); } - return state.segments.ToString(); + // Compose the final string from the built up segments. + return Regex.SegmentsToStringAndDispose(ref state.segments); } } } diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/SegmentStringBuilder.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/SegmentStringBuilder.cs deleted file mode 100644 index 2c603815cd1577..00000000000000 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/SegmentStringBuilder.cs +++ /dev/null @@ -1,98 +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.Buffers; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace System.Text -{ - /// Provides a value type string builder composed of individual segments represented as instances. - [DebuggerDisplay("Count = {_count}")] - internal struct SegmentStringBuilder - { - /// The array backing the builder, obtained from . - private ReadOnlyMemory[] _array; - /// The number of items in , and thus also the next position in the array to be filled. - private int _count; - - /// Creates a new builder. - /// Should be used instead of default struct initialization. - public static SegmentStringBuilder Create() => new SegmentStringBuilder() { _array = Array.Empty>() }; - - /// Gets the number of segments added to the builder. - public int Count => _count; - - /// Adds a segment to the builder. - /// The segment. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(ReadOnlyMemory segment) - { - ReadOnlyMemory[] array = _array; - int pos = _count; - if ((uint)pos < (uint)array.Length) - { - array[pos] = segment; - _count = pos + 1; - } - else - { - GrowAndAdd(segment); - } - } - - /// Grows the builder to accommodate another segment. - /// - [MethodImpl(MethodImplOptions.NoInlining)] - private void GrowAndAdd(ReadOnlyMemory segment) - { - ReadOnlyMemory[] array = _array; - Debug.Assert(array.Length == _count); - - const int DefaultArraySize = 256; - int newSize = array.Length == 0 ? DefaultArraySize : array.Length * 2; - - ReadOnlyMemory[] newArray = _array = ArrayPool>.Shared.Rent(newSize); - Array.Copy(array, newArray, _count); - ArrayPool>.Shared.Return(array, clearArray: true); - newArray[_count++] = segment; - } - - /// Gets a span of all segments in the builder. - /// - public Span> AsSpan() => new Span>(_array, 0, _count); - - /// Creates a string from all the segments in the builder and then disposes of the builder. - public override unsafe string ToString() - { - ReadOnlyMemory[] array = _array; - var span = new Span>(array, 0, _count); - - int length = 0; - for (int i = 0; i < span.Length; i++) - { - length += span[i].Length; - } - -#pragma warning disable CS8500 // takes address of managed type - ReadOnlySpan> tmpSpan = span; // avoid address exposing the span and impacting the other code in the method that uses it - string result = string.Create(length, (IntPtr)(&tmpSpan), static (dest, spanPtr) => - { - Span> span = *(Span>*)spanPtr; - for (int i = 0; i < span.Length; i++) - { - ReadOnlySpan segment = span[i].Span; - segment.CopyTo(dest); - dest = dest.Slice(segment.Length); - } - }); -#pragma warning restore CS8500 - - span.Clear(); - this = default; - ArrayPool>.Shared.Return(array); - - return result; - } - } -} diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/StructListBuilder.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/StructListBuilder.cs new file mode 100644 index 00000000000000..b23c20b2a7300c --- /dev/null +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/StructListBuilder.cs @@ -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. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Text +{ + /// Provides a struct-based list builder. + [DebuggerDisplay("Count = {_count}")] + internal struct StructListBuilder + { + /// The array backing the builder, obtained from . + private T[] _array = Array.Empty(); + /// The number of items in , and thus also the next position in the array to be filled. + private int _count; + + /// Creates a new builder. + /// Should be used instead of default struct initialization. + public StructListBuilder() { } + + /// Gets the number of items in the builder. + public int Count => _count; + + /// Gets a span of the items in the builder. + public Span AsSpan() => _array.AsSpan(0, _count); + + /// Adds an item to the builder. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(T item) + { + T[] array = _array; + int pos = _count; + if ((uint)pos < (uint)array.Length) + { + array[pos] = item; + _count = pos + 1; + } + else + { + GrowAndAdd(item); + } + } + + /// Disposes the builder, returning any array it's storing to the pool. + public void Dispose() + { + if (_array != null) + { + ArrayPool.Shared.Return(_array, clearArray: RuntimeHelpers.IsReferenceOrContainsReferences()); + _array = null!; + } + } + + /// Grows the builder to accommodate another item. + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowAndAdd(T item) + { + T[] array = _array; + Debug.Assert(array.Length == _count); + + const int DefaultArraySize = 256; + int newSize = array.Length == 0 ? DefaultArraySize : array.Length * 2; + + T[] newArray = _array = ArrayPool.Shared.Rent(newSize); + Array.Copy(array, newArray, _count); + ArrayPool.Shared.Return(array, clearArray: RuntimeHelpers.IsReferenceOrContainsReferences()); + newArray[_count++] = item; + } + } +} diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs index 72eb2e52cdddb2..2a48aa50097c17 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs @@ -865,7 +865,7 @@ file static class Utilities internal static readonly bool s_hasTimeout = s_defaultTimeout != Regex.InfiniteMatchTimeout; /// Supports searching for characters in or not in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz". - internal static readonly IndexOfAnyValues s_asciiLetters = IndexOfAnyValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + internal static readonly SearchValues s_asciiLetters = SearchValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); } } """ diff --git a/src/libraries/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.cs b/src/libraries/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.cs index 41be9b17b088cc..abe73d4db72e22 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.cs +++ b/src/libraries/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.cs @@ -4,6 +4,8 @@ // Changes to this file must follow the https://aka.ms/api-review process. // ------------------------------------------------------------------------------ +using System.Numerics; + namespace System.Threading.Tasks { public static partial class Parallel @@ -16,6 +18,9 @@ public static partial class Parallel public static System.Threading.Tasks.ParallelLoopResult For(long fromInclusive, long toExclusive, System.Action body) { throw null; } public static System.Threading.Tasks.ParallelLoopResult For(long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action body) { throw null; } public static System.Threading.Tasks.ParallelLoopResult For(long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action body) { throw null; } + public static System.Threading.Tasks.Task ForAsync(T fromInclusive, T toExclusive, System.Func body) where T : notnull, System.Numerics.IBinaryInteger { throw null; } + public static System.Threading.Tasks.Task ForAsync(T fromInclusive, T toExclusive, System.Threading.CancellationToken cancellationToken, System.Func body) where T : notnull, System.Numerics.IBinaryInteger { throw null; } + public static System.Threading.Tasks.Task ForAsync(T fromInclusive, T toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func body) where T : notnull, System.Numerics.IBinaryInteger { throw null; } public static System.Threading.Tasks.ParallelLoopResult ForEach(System.Collections.Concurrent.OrderablePartitioner source, System.Action body) { throw null; } public static System.Threading.Tasks.ParallelLoopResult ForEach(System.Collections.Concurrent.OrderablePartitioner source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action body) { throw null; } public static System.Threading.Tasks.ParallelLoopResult ForEach(System.Collections.Concurrent.Partitioner source, System.Action body) { throw null; } diff --git a/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.ForEachAsync.cs b/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.ForEachAsync.cs index 7862243c1ae4f0..b3c6d50cafe2e7 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.ForEachAsync.cs +++ b/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.ForEachAsync.cs @@ -3,16 +3,214 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; namespace System.Threading.Tasks { public static partial class Parallel { - /// Executes a for each operation on an in which iterations may run in parallel. + /// Executes a for loop in which iterations may run in parallel. + /// The start index, inclusive. + /// The end index, exclusive. + /// An asynchronous delegate that is invoked once per element in the data source. + /// The argument is . + /// A task that represents the entire for each operation. + /// The operation will execute at most operations in parallel. + public static Task ForAsync(T fromInclusive, T toExclusive, Func body) + where T : notnull, IBinaryInteger + { + if (fromInclusive is null) throw new ArgumentNullException(nameof(fromInclusive)); + if (toExclusive is null) throw new ArgumentNullException(nameof(toExclusive)); + ArgumentNullException.ThrowIfNull(body); + + return ForAsync(fromInclusive, toExclusive, DefaultDegreeOfParallelism, TaskScheduler.Default, default, body); + } + + /// Executes a for loop in which iterations may run in parallel. + /// The start index, inclusive. + /// The end index, exclusive. + /// A cancellation token that may be used to cancel the for each operation. + /// An asynchronous delegate that is invoked once per element in the data source. + /// The argument is . + /// A task that represents the entire for each operation. + /// The operation will execute at most operations in parallel. + public static Task ForAsync(T fromInclusive, T toExclusive, CancellationToken cancellationToken, Func body) + where T : notnull, IBinaryInteger + { + if (fromInclusive is null) throw new ArgumentNullException(nameof(fromInclusive)); + if (toExclusive is null) throw new ArgumentNullException(nameof(toExclusive)); + ArgumentNullException.ThrowIfNull(body); + + return ForAsync(fromInclusive, toExclusive, DefaultDegreeOfParallelism, TaskScheduler.Default, cancellationToken, body); + } + + /// Executes a for loop in which iterations may run in parallel. + /// The start index, inclusive. + /// The end index, exclusive. + /// An object that configures the behavior of this operation. + /// An asynchronous delegate that is invoked once per element in the data source. + /// The argument is . + /// A task that represents the entire for each operation. + /// The operation will execute at most operations in parallel. + public static Task ForAsync(T fromInclusive, T toExclusive, ParallelOptions parallelOptions, Func body) + where T : notnull, IBinaryInteger + { + if (fromInclusive is null) throw new ArgumentNullException(nameof(fromInclusive)); + if (toExclusive is null) throw new ArgumentNullException(nameof(toExclusive)); + ArgumentNullException.ThrowIfNull(parallelOptions); + ArgumentNullException.ThrowIfNull(body); + + return ForAsync(fromInclusive, toExclusive, parallelOptions.EffectiveMaxConcurrencyLevel, parallelOptions.EffectiveTaskScheduler, parallelOptions.CancellationToken, body); + } + + /// Executes a for each operation on an in which iterations may run in parallel. + /// The type of the data in the source. + /// The start index, inclusive. + /// The end index, exclusive. + /// The degree of parallelism, or the number of operations to allow to run in parallel. + /// The task scheduler on which all code should execute. + /// A cancellation token that may be used to cancel the for each operation. + /// An asynchronous delegate that is invoked once per element in the data source. + /// The argument is . + /// A task that represents the entire for each operation. + private static Task ForAsync(T fromInclusive, T toExclusive, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, Func body) + where T : notnull, IBinaryInteger + { + Debug.Assert(fromInclusive != null); + Debug.Assert(toExclusive != null); + Debug.Assert(scheduler != null); + Debug.Assert(body != null); + + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + if (fromInclusive >= toExclusive) + { + return Task.CompletedTask; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool Interlockable() => + typeof(T) == typeof(int) || + typeof(T) == typeof(uint) || + typeof(T) == typeof(long) || + typeof(T) == typeof(ulong) || + typeof(T) == typeof(nint) || + typeof(T) == typeof(nuint); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool CompareExchange(ref T location, T value, T comparand) => + typeof(T) == typeof(int) ? Interlocked.CompareExchange(ref Unsafe.As(ref location), Unsafe.As(ref value), Unsafe.As(ref comparand)) == Unsafe.As(ref comparand) : + typeof(T) == typeof(uint) ? Interlocked.CompareExchange(ref Unsafe.As(ref location), Unsafe.As(ref value), Unsafe.As(ref comparand)) == Unsafe.As(ref comparand) : + typeof(T) == typeof(long) ? Interlocked.CompareExchange(ref Unsafe.As(ref location), Unsafe.As(ref value), Unsafe.As(ref comparand)) == Unsafe.As(ref comparand) : + typeof(T) == typeof(ulong) ? Interlocked.CompareExchange(ref Unsafe.As(ref location), Unsafe.As(ref value), Unsafe.As(ref comparand)) == Unsafe.As(ref comparand) : + typeof(T) == typeof(nint) ? Interlocked.CompareExchange(ref Unsafe.As(ref location), Unsafe.As(ref value), Unsafe.As(ref comparand)) == Unsafe.As(ref comparand) : + typeof(T) == typeof(nuint) ? Interlocked.CompareExchange(ref Unsafe.As(ref location), Unsafe.As(ref value), Unsafe.As(ref comparand)) == Unsafe.As(ref comparand) : + throw new UnreachableException(); + + // The worker body. Each worker will execute this same body. + Func taskBody = static async o => + { + var state = (ForEachState)o; + bool launchedNext = false; + +#pragma warning disable CA2007 // Explicitly don't use ConfigureAwait, as we want to perform all work on the specified scheduler that's now current + try + { + // Continue to loop while there are more elements to be processed. + while (!state.Cancellation.IsCancellationRequested) + { + // Get the next element from the enumerator. For some types, we can get the next element with just + // interlocked operations, avoiding the need to take a lock. For other types, we need to take a lock. + T element; + if (Interlockable()) + { + TryAgain: + element = state.NextAvailable; + if (element >= state.ToExclusive) + { + break; + } + + if (!CompareExchange(ref state.NextAvailable, element + T.One, element)) + { + goto TryAgain; + } + } + else + { + await state.AcquireLock(); + try + { + if (state.Cancellation.IsCancellationRequested || // check now that the lock has been acquired + state.NextAvailable >= state.ToExclusive) + { + break; + } + + element = state.NextAvailable; + state.NextAvailable++; + } + finally + { + state.ReleaseLock(); + } + } + + // If the remaining dop allows it and we've not yet queued the next worker, do so now. We wait + // until after we've grabbed an item from the enumerator to a) avoid unnecessary contention on the + // serialized resource, and b) avoid queueing another work if there aren't any more items. Each worker + // is responsible only for creating the next worker, which in turn means there can't be any contention + // on creating workers (though it's possible one worker could be executing while we're creating the next). + if (!launchedNext) + { + launchedNext = true; + state.QueueWorkerIfDopAvailable(); + } + + // Process the loop body. + await state.LoopBody(element, state.Cancellation.Token); + } + } + catch (Exception e) + { + // Record the failure and then don't let the exception propagate. The last worker to complete + // will propagate exceptions as is appropriate to the top-level task. + state.RecordException(e); + } + finally + { + // If we're the last worker to complete, complete the operation. + if (state.SignalWorkerCompletedIterating()) + { + state.Complete(); + } + } +#pragma warning restore CA2007 + }; + + try + { + // Construct a state object that encapsulates all state to be passed and shared between + // the workers, and queues the first worker. + var state = new ForEachState(fromInclusive, toExclusive, taskBody, !Interlockable(), dop, scheduler, cancellationToken, body); + state.QueueWorkerIfDopAvailable(); + return state.Task; + } + catch (Exception e) + { + return Task.FromException(e); + } + } + + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An enumerable data source. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. /// The operation will execute at most operations in parallel. public static Task ForEachAsync(IEnumerable source, Func body) @@ -23,12 +221,12 @@ public static Task ForEachAsync(IEnumerable source, FuncExecutes a for each operation on an in which iterations may run in parallel. + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An enumerable data source. /// A cancellation token that may be used to cancel the for each operation. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. /// The operation will execute at most operations in parallel. public static Task ForEachAsync(IEnumerable source, CancellationToken cancellationToken, Func body) @@ -39,12 +237,12 @@ public static Task ForEachAsync(IEnumerable source, Cancellati return ForEachAsync(source, DefaultDegreeOfParallelism, TaskScheduler.Default, cancellationToken, body); } - /// Executes a for each operation on an in which iterations may run in parallel. + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An enumerable data source. /// An object that configures the behavior of this operation. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. public static Task ForEachAsync(IEnumerable source, ParallelOptions parallelOptions, Func body) { @@ -55,14 +253,14 @@ public static Task ForEachAsync(IEnumerable source, ParallelOp return ForEachAsync(source, parallelOptions.EffectiveMaxConcurrencyLevel, parallelOptions.EffectiveTaskScheduler, parallelOptions.CancellationToken, body); } - /// Executes a for each operation on an in which iterations may run in parallel. + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An enumerable data source. /// A integer indicating how many operations to allow to run in parallel. /// The task scheduler on which all code should execute. /// A cancellation token that may be used to cancel the for each operation. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. private static Task ForEachAsync(IEnumerable source, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, Func body) { @@ -76,11 +274,6 @@ private static Task ForEachAsync(IEnumerable source, int dop, return Task.FromCanceled(cancellationToken); } - if (dop < 0) - { - dop = DefaultDegreeOfParallelism; - } - // The worker body. Each worker will execute this same body. Func taskBody = static async o => { @@ -168,11 +361,11 @@ private static Task ForEachAsync(IEnumerable source, int dop, } } - /// Executes a for each operation on an in which iterations may run in parallel. + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An asynchronous enumerable data source. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. /// The operation will execute at most operations in parallel. public static Task ForEachAsync(IAsyncEnumerable source, Func body) @@ -183,12 +376,12 @@ public static Task ForEachAsync(IAsyncEnumerable source, Func< return ForEachAsync(source, DefaultDegreeOfParallelism, TaskScheduler.Default, default(CancellationToken), body); } - /// Executes a for each operation on an in which iterations may run in parallel. + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An asynchronous enumerable data source. /// A cancellation token that may be used to cancel the for each operation. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. /// The operation will execute at most operations in parallel. public static Task ForEachAsync(IAsyncEnumerable source, CancellationToken cancellationToken, Func body) @@ -199,12 +392,12 @@ public static Task ForEachAsync(IAsyncEnumerable source, Cance return ForEachAsync(source, DefaultDegreeOfParallelism, TaskScheduler.Default, cancellationToken, body); } - /// Executes a for each operation on an in which iterations may run in parallel. + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An asynchronous enumerable data source. /// An object that configures the behavior of this operation. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. public static Task ForEachAsync(IAsyncEnumerable source, ParallelOptions parallelOptions, Func body) { @@ -215,14 +408,14 @@ public static Task ForEachAsync(IAsyncEnumerable source, Paral return ForEachAsync(source, parallelOptions.EffectiveMaxConcurrencyLevel, parallelOptions.EffectiveTaskScheduler, parallelOptions.CancellationToken, body); } - /// Executes a for each operation on an in which iterations may run in parallel. + /// Executes a for each operation on an in which iterations may run in parallel. /// The type of the data in the source. /// An asynchronous enumerable data source. /// A integer indicating how many operations to allow to run in parallel. /// The task scheduler on which all code should execute. /// A cancellation token that may be used to cancel the for each operation. /// An asynchronous delegate that is invoked once per element in the data source. - /// The exception that is thrown when the argument or argument is null. + /// The argument or argument is . /// A task that represents the entire for each operation. private static Task ForEachAsync(IAsyncEnumerable source, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, Func body) { @@ -236,11 +429,6 @@ private static Task ForEachAsync(IAsyncEnumerable source, int return Task.FromCanceled(cancellationToken); } - if (dop < 0) - { - dop = DefaultDegreeOfParallelism; - } - // The worker body. Each worker will execute this same body. Func taskBody = static async o => { @@ -352,7 +540,7 @@ private abstract class ForEachAsyncState : TaskCompletionSource, IThrea /// The present at the time of the ForEachAsync invocation. This is only used if on the default scheduler. private readonly ExecutionContext? _executionContext; /// Semaphore used to provide exclusive access to the enumerator. - private readonly SemaphoreSlim _lock = new SemaphoreSlim(initialCount: 1, maxCount: 1); + private readonly SemaphoreSlim? _lock; /// The number of outstanding workers. When this hits 0, the operation has completed. private int _completionRefCount; @@ -367,10 +555,11 @@ private abstract class ForEachAsyncState : TaskCompletionSource, IThrea public readonly CancellationTokenSource Cancellation = new CancellationTokenSource(); /// Initializes the state object. - protected ForEachAsyncState(Func taskBody, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, Func body) + protected ForEachAsyncState(Func taskBody, bool needsLock, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, Func body) { _taskBody = taskBody; - _remainingDop = dop; + _lock = needsLock ? new SemaphoreSlim(initialCount: 1, maxCount: 1) : null; + _remainingDop = dop < 0 ? DefaultDegreeOfParallelism : dop; LoopBody = body; _scheduler = scheduler; if (scheduler == TaskScheduler.Default) @@ -417,7 +606,8 @@ public void QueueWorkerIfDopAvailable() public bool SignalWorkerCompletedIterating() => Interlocked.Decrement(ref _completionRefCount) == 0; /// Asynchronously acquires exclusive access to the enumerator. - public Task AcquireLock() => + public Task AcquireLock() + { // We explicitly don't pass this.Cancellation to WaitAsync. Doing so adds overhead, and it isn't actually // necessary. All of the operations that monitor the lock are part of the same ForEachAsync operation, and the Task // returned from ForEachAsync can't complete until all of the constituent operations have completed, including whoever @@ -426,10 +616,16 @@ public Task AcquireLock() => // the face of cancellation, in exchange for making it a bit slower / more overhead in the common case of cancellation // not being requested. We want to optimize for the latter. This also then avoids an exception throw / catch when // cancellation is requested. - _lock.WaitAsync(CancellationToken.None); + Debug.Assert(_lock is not null, "Should only be invoked when _lock is non-null"); + return _lock.WaitAsync(CancellationToken.None); + } /// Relinquishes exclusive access to the enumerator. - public void ReleaseLock() => _lock.Release(); + public void ReleaseLock() + { + Debug.Assert(_lock is not null, "Should only be invoked when _lock is non-null"); + _lock.Release(); + } /// Stores an exception and triggers cancellation in order to alert all workers to stop as soon as possible. /// The exception. @@ -513,7 +709,7 @@ public SyncForEachAsyncState( IEnumerable source, Func taskBody, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, Func body) : - base(taskBody, dop, scheduler, cancellationToken, body) + base(taskBody, needsLock: true, dop, scheduler, cancellationToken, body) { Enumerator = source.GetEnumerator() ?? throw new InvalidOperationException(SR.Parallel_ForEach_NullEnumerator); } @@ -535,7 +731,7 @@ public AsyncForEachAsyncState( IAsyncEnumerable source, Func taskBody, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, Func body) : - base(taskBody, dop, scheduler, cancellationToken, body) + base(taskBody, needsLock: true, dop, scheduler, cancellationToken, body) { Enumerator = source.GetAsyncEnumerator(Cancellation.Token) ?? throw new InvalidOperationException(SR.Parallel_ForEach_NullEnumerator); } @@ -546,5 +742,23 @@ public ValueTask DisposeAsync() return Enumerator.DisposeAsync(); } } + + /// Stores the state associated with an IAsyncEnumerable ForEachAsync operation, shared between all its workers. + /// Specifies the type of data being enumerated. + private sealed class ForEachState : ForEachAsyncState + { + public T NextAvailable; + public readonly T ToExclusive; + + public ForEachState( + T fromExclusive, T toExclusive, Func taskBody, + bool needsLock, int dop, TaskScheduler scheduler, CancellationToken cancellationToken, + Func body) : + base(taskBody, needsLock, dop, scheduler, cancellationToken, body) + { + NextAvailable = fromExclusive; + ToExclusive = toExclusive; + } + } } } diff --git a/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs b/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs index b68b3d2c7b26bb..5708643c1d28f0 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs +++ b/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Numerics; using System.Runtime.CompilerServices; using Xunit; @@ -23,9 +24,14 @@ public void InvalidArguments_ThrowsException() AssertExtensions.Throws("source", () => { Parallel.ForEachAsync((IAsyncEnumerable)null, CancellationToken.None, (item, cancellationToken) => default); }); AssertExtensions.Throws("source", () => { Parallel.ForEachAsync((IAsyncEnumerable)null, new ParallelOptions(), (item, cancellationToken) => default); }); + AssertExtensions.Throws("parallelOptions", () => { Parallel.ForAsync(1, 10, null, (item, cancellationToken) => default); }); AssertExtensions.Throws("parallelOptions", () => { Parallel.ForEachAsync(Enumerable.Range(1, 10), null, (item, cancellationToken) => default); }); AssertExtensions.Throws("parallelOptions", () => { Parallel.ForEachAsync(EnumerableRangeAsync(1, 10), null, (item, cancellationToken) => default); }); + AssertExtensions.Throws("body", () => { Parallel.ForAsync(1, 10, null); }); + AssertExtensions.Throws("body", () => { Parallel.ForAsync(1, 10, CancellationToken.None, null); }); + AssertExtensions.Throws("body", () => { Parallel.ForAsync(1, 10, new ParallelOptions(), null); }); + AssertExtensions.Throws("body", () => { Parallel.ForEachAsync(Enumerable.Range(1, 10), null); }); AssertExtensions.Throws("body", () => { Parallel.ForEachAsync(Enumerable.Range(1, 10), CancellationToken.None, null); }); AssertExtensions.Throws("body", () => { Parallel.ForEachAsync(Enumerable.Range(1, 10), new ParallelOptions(), null); }); @@ -54,9 +60,11 @@ void AssertCanceled(Task t) return default; }; + AssertCanceled(Parallel.ForAsync(1, 10, cts.Token, body)); AssertCanceled(Parallel.ForEachAsync(MarkStart(box), cts.Token, body)); AssertCanceled(Parallel.ForEachAsync(MarkStartAsync(box), cts.Token, body)); + AssertCanceled(Parallel.ForAsync(1, 10, new ParallelOptions { CancellationToken = cts.Token }, body)); AssertCanceled(Parallel.ForEachAsync(MarkStart(box), new ParallelOptions { CancellationToken = cts.Token }, body)); AssertCanceled(Parallel.ForEachAsync(MarkStartAsync(box), new ParallelOptions { CancellationToken = cts.Token }, body)); @@ -79,6 +87,39 @@ static async IAsyncEnumerable MarkStartAsync(StrongBox box) } } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(-1)] + [InlineData(1)] + [InlineData(2)] + [InlineData(4)] + [InlineData(128)] + public async Task Dop_WorkersCreatedRespectingLimit_For(int dop) + { + bool exit = false; + + int activeWorkers = 0; + var block = new TaskCompletionSource(); + + Task t = Parallel.ForAsync(long.MinValue, long.MaxValue, new ParallelOptions { MaxDegreeOfParallelism = dop }, async (item, cancellationToken) => + { + Interlocked.Increment(ref activeWorkers); + await block.Task; + if (Volatile.Read(ref exit)) + { + throw new FormatException(); + } + }); + Assert.False(t.IsCompleted); + + await Task.Delay(20); // give the loop some time to run + + Volatile.Write(ref exit, true); + block.SetResult(); + await Assert.ThrowsAsync(() => t); + + Assert.InRange(activeWorkers, 0, dop == -1 ? Environment.ProcessorCount : dop); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(-1)] [InlineData(1)] @@ -117,6 +158,40 @@ static IEnumerable IterateUntilSet(StrongBox box) Assert.InRange(activeWorkers, 0, dop == -1 ? Environment.ProcessorCount : dop); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(-1)] + [InlineData(1)] + [InlineData(2)] + [InlineData(4)] + [InlineData(128)] + public async Task Dop_WorkersCreatedRespectingLimitAndTaskScheduler_For(int dop) + { + bool exit = false; + int activeWorkers = 0; + var block = new TaskCompletionSource(); + + int MaxSchedulerLimit = Math.Min(2, Environment.ProcessorCount); + + Task t = Parallel.ForAsync(long.MinValue, long.MaxValue, new ParallelOptions { MaxDegreeOfParallelism = dop, TaskScheduler = new MaxConcurrencyLevelPassthroughTaskScheduler(MaxSchedulerLimit) }, async (item, cancellationToken) => + { + Interlocked.Increment(ref activeWorkers); + await block.Task; + if (Volatile.Read(ref exit)) + { + throw new FormatException(); + } + }); + Assert.False(t.IsCompleted); + + await Task.Delay(20); // give the loop some time to run + + Volatile.Write(ref exit, true); + block.SetResult(); + await Assert.ThrowsAsync(() => t); + + Assert.InRange(activeWorkers, 0, Math.Min(MaxSchedulerLimit, dop == -1 ? Environment.ProcessorCount : dop)); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(-1)] [InlineData(1)] @@ -157,6 +232,33 @@ static IEnumerable IterateUntilSet(StrongBox box) Assert.InRange(activeWorkers, 0, Math.Min(MaxSchedulerLimit, dop == -1 ? Environment.ProcessorCount : dop)); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task Dop_NegativeTaskSchedulerLimitTreatedAsDefault_For() + { + bool exit = false; + int activeWorkers = 0; + var block = new TaskCompletionSource(); + + Task t = Parallel.ForAsync(long.MinValue, long.MaxValue, new ParallelOptions { TaskScheduler = new MaxConcurrencyLevelPassthroughTaskScheduler(-42) }, async (item, cancellationToken) => + { + Interlocked.Increment(ref activeWorkers); + await block.Task; + if (Volatile.Read(ref exit)) + { + throw new FormatException(); + } + }); + Assert.False(t.IsCompleted); + + await Task.Delay(20); // give the loop some time to run + + Volatile.Write(ref exit, true); + block.SetResult(); + await Assert.ThrowsAsync(() => t); + + Assert.InRange(activeWorkers, 0, Environment.ProcessorCount); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task Dop_NegativeTaskSchedulerLimitTreatedAsDefault_Sync() { @@ -224,6 +326,19 @@ static async IAsyncEnumerable IterateUntilSet(StrongBox box) Assert.InRange(activeWorkers, 0, Environment.ProcessorCount); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task RunsAsynchronously_For() + { + var cts = new CancellationTokenSource(); + + Task t = Parallel.ForAsync(long.MinValue, long.MaxValue, cts.Token, (item, cancellationToken) => default); + Assert.False(t.IsCompleted); + + cts.Cancel(); + + await Assert.ThrowsAnyAsync(() => t); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task RunsAsynchronously_EvenForEntirelySynchronousWork_Sync() { @@ -301,6 +416,20 @@ static async IAsyncEnumerable IterateUntilSetAsync(StrongBox box) Assert.InRange(activeWorkers, 0, dop == -1 ? Environment.ProcessorCount : dop); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void EmptyRange_For() + { + int counter = 0; + Task t = Parallel.ForAsync(10, 10, (item, cancellationToken) => + { + Interlocked.Increment(ref counter); + return default; + }); + Assert.True(t.IsCompletedSuccessfully); + + Assert.Equal(0, counter); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task EmptySource_Sync() { @@ -327,6 +456,51 @@ await Parallel.ForEachAsync(EnumerableRangeAsync(0, 0), (item, cancellationToken Assert.Equal(0, counter); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(false)] + [InlineData(true)] + public async Task AllItemsEnumeratedOnce_For(bool yield) + { + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + await Test(yield); + + async Task Test(bool yield) where T : IBinaryInteger + { + const int Start = 10, Count = 10_000; + + var set = new HashSet(); + + await Parallel.ForAsync(T.CreateTruncating(Start), T.CreateTruncating(Start + Count), async (item, cancellationToken) => + { + lock (set) + { + Assert.True(set.Add(item)); + } + + if (yield) + { + await Task.Yield(); + } + }); + + Assert.False(set.Contains(T.CreateTruncating(Start - 1))); + for (int i = Start; i < Start + Count; i++) + { + Assert.True(set.Contains(T.CreateTruncating(i))); + } + Assert.False(set.Contains(T.CreateTruncating(Start + Count + 1))); + } + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(false)] [InlineData(true)] @@ -349,10 +523,12 @@ await Parallel.ForEachAsync(Enumerable.Range(Start, Count), async (item, cancell } }); + Assert.False(set.Contains(Start - 1)); for (int i = Start; i < Start + Count; i++) { Assert.True(set.Contains(i)); } + Assert.False(set.Contains(Start + Count + 1)); } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -377,10 +553,40 @@ await Parallel.ForEachAsync(EnumerableRangeAsync(Start, Count, yield), async (it } }); + Assert.False(set.Contains(Start - 1)); for (int i = Start; i < Start + Count; i++) { Assert.True(set.Contains(i)); } + Assert.False(set.Contains(Start + Count + 1)); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(false)] + [InlineData(true)] + public async Task TaskScheduler_AllCodeExecutedOnCorrectScheduler_For(bool defaultScheduler) + { + TaskScheduler scheduler = defaultScheduler ? + TaskScheduler.Default : + new ConcurrentExclusiveSchedulerPair().ConcurrentScheduler; + + TaskScheduler otherScheduler = new ConcurrentExclusiveSchedulerPair().ConcurrentScheduler; + + var cq = new ConcurrentQueue(); + + await Parallel.ForAsync(1, 101, new ParallelOptions { TaskScheduler = scheduler }, async (item, cancellationToken) => + { + Assert.Same(scheduler, TaskScheduler.Current); + await Task.Yield(); + cq.Enqueue(item); + + if (item % 10 == 0) + { + await new SwitchTo(otherScheduler); + } + }); + + Assert.Equal(Enumerable.Range(1, 100), cq.OrderBy(i => i)); } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -460,6 +666,17 @@ async IAsyncEnumerable Iterate() Assert.Equal(Enumerable.Range(1, 100), cq.OrderBy(i => i)); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task Cancellation_CancelsIterationAndReturnsCanceledTask_For() + { + using var cts = new CancellationTokenSource(10); + OperationCanceledException oce = await Assert.ThrowsAnyAsync(() => Parallel.ForAsync(long.MinValue, long.MaxValue, cts.Token, async (item, cancellationToken) => + { + await Task.Yield(); + })); + Assert.Equal(cts.Token, oce.CancellationToken); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task Cancellation_CancelsIterationAndReturnsCanceledTask_Sync() { @@ -518,6 +735,21 @@ await Parallel.ForEachAsync(YieldTokenAsync(default), (item, cancellationToken) }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task Cancellation_SameTokenPassedToEveryInvocation_For() + { + var cq = new ConcurrentQueue(); + + await Parallel.ForAsync(1, 101, async (item, cancellationToken) => + { + cq.Enqueue(cancellationToken); + await Task.Yield(); + }); + + Assert.Equal(100, cq.Count); + Assert.Equal(1, cq.Distinct().Count()); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task Cancellation_SameTokenPassedToEveryInvocation_Sync() { @@ -548,6 +780,32 @@ await Parallel.ForEachAsync(EnumerableRangeAsync(1, 100), async (item, cancellat Assert.Equal(1, cq.Distinct().Count()); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task Cancellation_HasPriorityOverExceptions_For() + { + var tcs = new TaskCompletionSource(); + var cts = new CancellationTokenSource(); + + Task t = Parallel.ForAsync(0, long.MaxValue, new ParallelOptions { CancellationToken = cts.Token, MaxDegreeOfParallelism = 2 }, async (item, cancellationToken) => + { + if (item == 0) + { + await tcs.Task; + cts.Cancel(); + throw new FormatException(); + } + else + { + tcs.TrySetResult(); + await Task.Yield(); + } + }); + + OperationCanceledException oce = await Assert.ThrowsAnyAsync(() => t); + Assert.Equal(cts.Token, oce.CancellationToken); + Assert.True(t.IsCanceled); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task Cancellation_HasPriorityOverExceptions_Sync() { @@ -616,6 +874,22 @@ static async IAsyncEnumerable Iterate() Assert.True(t.IsCanceled); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(false)] + [InlineData(true)] + public async Task Cancellation_FaultsForOceForNonCancellation_For(bool internalToken) + { + var cts = new CancellationTokenSource(); + + Task t = Parallel.ForAsync(long.MinValue, long.MaxValue, new ParallelOptions { CancellationToken = cts.Token }, (item, cancellationToken) => + { + throw new OperationCanceledException(internalToken ? cancellationToken : cts.Token); + }); + + await Assert.ThrowsAnyAsync(() => t); + Assert.True(t.IsFaulted); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(false)] [InlineData(true)] @@ -642,6 +916,38 @@ static async IAsyncEnumerable Iterate() Assert.True(t.IsFaulted); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(0, 4)] + [InlineData(1, 4)] + [InlineData(2, 4)] + [InlineData(3, 4)] + [InlineData(4, 4)] + public async Task Cancellation_InternalCancellationExceptionsArentFilteredOut_For(int numThrowingNonCanceledOce, int total) + { + var cts = new CancellationTokenSource(); + + var barrier = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + int remainingCount = total; + + Task t = Parallel.ForAsync(0, total, new ParallelOptions { CancellationToken = cts.Token, MaxDegreeOfParallelism = total }, async (item, cancellationToken) => + { + // Wait for all operations to be started + if (Interlocked.Decrement(ref remainingCount) == 0) + { + barrier.SetResult(); + } + await barrier.Task; + + throw item < numThrowingNonCanceledOce ? + new OperationCanceledException(cancellationToken) : + throw new FormatException(); + }); + + await Assert.ThrowsAnyAsync(() => t); + Assert.Equal(total, t.Exception.InnerExceptions.Count); + Assert.Equal(numThrowingNonCanceledOce, t.Exception.InnerExceptions.Count(e => e is OperationCanceledException)); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(0, 4)] [InlineData(1, 4)] @@ -751,6 +1057,27 @@ static async IAsyncEnumerable Iterate() Assert.True(t.IsFaulted); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task Exception_FromLoopBody_For() + { + var barrier = new Barrier(2); + Task t = Parallel.ForAsync(1, 3, new ParallelOptions { MaxDegreeOfParallelism = barrier.ParticipantCount }, (item, cancellationToken) => + { + barrier.SignalAndWait(); + throw item switch + { + 1 => new FormatException(), + 2 => new InvalidTimeZoneException(), + _ => new Exception() + }; + }); + await Assert.ThrowsAnyAsync(() => t); + Assert.True(t.IsFaulted); + Assert.Equal(2, t.Exception.InnerExceptions.Count); + Assert.Contains(t.Exception.InnerExceptions, e => e is FormatException); + Assert.Contains(t.Exception.InnerExceptions, e => e is InvalidTimeZoneException); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task Exception_FromLoopBody_Sync() { @@ -853,6 +1180,34 @@ public async Task Exception_FromDisposeAndCancellationCallback_Async() Assert.Contains(t.Exception.InnerExceptions, e => e is InvalidTimeZoneException); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task Exception_ImplicitlyCancelsOtherWorkers_For() + { + await Assert.ThrowsAsync(() => Parallel.ForAsync(0, long.MaxValue, async (item, cancellationToken) => + { + await Task.Yield(); + if (item == 1000) + { + throw new Exception(); + } + })); + + await Assert.ThrowsAsync(() => Parallel.ForAsync(0, long.MaxValue, new ParallelOptions { MaxDegreeOfParallelism = 2 }, async (item, cancellationToken) => + { + if (item == 0) + { + throw new FormatException(); + } + else + { + Assert.Equal(1, item); + var tcs = new TaskCompletionSource(); + cancellationToken.Register(() => tcs.SetResult()); + await tcs.Task; + } + })); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task Exception_ImplicitlyCancelsOtherWorkers_Sync() { @@ -958,6 +1313,24 @@ static async IAsyncEnumerable Iterate(Task signal) Assert.IsType(ae.InnerException); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(false)] + [InlineData(true)] + public async Task ExecutionContext_FlowsToWorkerBodies_For(bool defaultScheduler) + { + TaskScheduler scheduler = defaultScheduler ? + TaskScheduler.Default : + new ConcurrentExclusiveSchedulerPair().ConcurrentScheduler; + + var al = new AsyncLocal(); + al.Value = 42; + await Parallel.ForAsync(0, 100, async (item, cancellationToken) => + { + await Task.Yield(); + Assert.Equal(42, al.Value); + }); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(false)] [InlineData(true)] diff --git a/src/libraries/System.Web.HttpUtility/ref/System.Web.HttpUtility.cs b/src/libraries/System.Web.HttpUtility/ref/System.Web.HttpUtility.cs index 20861705d61fb8..f319c25a30e7a6 100644 --- a/src/libraries/System.Web.HttpUtility/ref/System.Web.HttpUtility.cs +++ b/src/libraries/System.Web.HttpUtility/ref/System.Web.HttpUtility.cs @@ -65,4 +65,8 @@ public static void HtmlEncode(string? s, System.IO.TextWriter output) { } [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("str")] public static string? UrlPathEncode(string? str) { throw null; } } + public partial interface IHtmlString + { + string ToHtmlString(); + } } diff --git a/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj b/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj index 0af2959103a0d5..df97d2ad041a05 100644 --- a/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj +++ b/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj @@ -4,6 +4,7 @@ $(NetCoreAppCurrent) + diff --git a/src/libraries/System.Web.HttpUtility/src/System/Web/HttpUtility.cs b/src/libraries/System.Web.HttpUtility/src/System/Web/HttpUtility.cs index 57964af42641ca..5d0d503f526b11 100644 --- a/src/libraries/System.Web.HttpUtility/src/System/Web/HttpUtility.cs +++ b/src/libraries/System.Web.HttpUtility/src/System/Web/HttpUtility.cs @@ -143,7 +143,12 @@ public static NameValueCollection ParseQueryString(string query, Encoding encodi [return: NotNullIfNotNull(nameof(value))] public static string? HtmlEncode(object? value) => - value == null ? null : HtmlEncode(Convert.ToString(value, CultureInfo.CurrentCulture) ?? string.Empty); + value switch + { + null => null, + IHtmlString ihs => ihs.ToHtmlString() ?? string.Empty, + _ => HtmlEncode(Convert.ToString(value, CultureInfo.CurrentCulture) ?? string.Empty), + }; public static void HtmlEncode(string? s, TextWriter output) => HttpEncoder.HtmlEncode(s, output); diff --git a/src/libraries/System.Web.HttpUtility/src/System/Web/IHtmlString.cs b/src/libraries/System.Web.HttpUtility/src/System/Web/IHtmlString.cs new file mode 100644 index 00000000000000..da6f3ce48bd3b7 --- /dev/null +++ b/src/libraries/System.Web.HttpUtility/src/System/Web/IHtmlString.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Web +{ + /// Represents an HTML-encoded string that should not be encoded again. + public interface IHtmlString + { + /// Returns an HTML-encoded string. + /// An HTML-encoded string. + string ToHtmlString(); + } +} diff --git a/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs b/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs index 416d3215b1754a..82268b3b326b4c 100644 --- a/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs +++ b/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs @@ -284,6 +284,20 @@ public void HtmlEncode_TextWriter_null() }); } + [Fact] + public void HtmlEncode_IHtmlString_UseToHtmlString() + { + Assert.Equal(string.Empty, HttpUtility.HtmlEncode(new ActionHtmlString(() => null))); + Assert.Equal(string.Empty, HttpUtility.HtmlEncode(new ActionHtmlString(() => string.Empty))); + Assert.Equal("<", HttpUtility.HtmlEncode(new ActionHtmlString(() => "<"))); + Assert.Throws(() => HttpUtility.HtmlEncode(new ActionHtmlString(() => throw new FormatException()))); + } + + private sealed class ActionHtmlString(Func toHtmlString) : IHtmlString + { + public string ToHtmlString() => toHtmlString(); + } + #endregion HtmlEncode #region JavaScriptStringEncode diff --git a/src/libraries/native-binplace.proj b/src/libraries/native-binplace.proj index 867fadd3c4637e..b6d10ef00c6d98 100644 --- a/src/libraries/native-binplace.proj +++ b/src/libraries/native-binplace.proj @@ -24,6 +24,7 @@ + diff --git a/src/libraries/oob-all.proj b/src/libraries/oob-all.proj index 1754c8b3d8a70c..8233bcac0bd86d 100644 --- a/src/libraries/oob-all.proj +++ b/src/libraries/oob-all.proj @@ -13,6 +13,14 @@ $(MSBuildThisFileDirectory)*\src\**\*.shproj; shims\src\*.csproj" /> + + + - - - diff --git a/src/libraries/oob-src.proj b/src/libraries/oob-src.proj index 5eb6a2f74e41b9..a285e8a83cf240 100644 --- a/src/libraries/oob-src.proj +++ b/src/libraries/oob-src.proj @@ -15,10 +15,17 @@ @(NetCoreAppLibrary->'%(Identity)\src\%(Identity).csproj'); Microsoft.VisualBasic.Core\src\Microsoft.VisualBasic.Core.vbproj" /> - - + diff --git a/src/libraries/oob.proj b/src/libraries/oob.proj index 074f952826da4a..8eec5f78284906 100644 --- a/src/libraries/oob.proj +++ b/src/libraries/oob.proj @@ -56,7 +56,7 @@ DependsOnTargets="GetTrimOOBAssembliesInputs;PrepareForAssembliesTrim" Inputs="$(ILLinkTasksAssembly);@(OOBAssemblyToTrim);@(OOBAssemblyReference);@(OOBLibrarySuppressionsXml)" Outputs="$(OOBAssembliesTrimMarkerFile)"> - + $(ILLinkArgs) diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index 6118eb1120e6a2..3bee7105912e7f 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -71,10 +71,10 @@ Outputs="$(MicrosoftNetCoreAppRuntimePackDir)data\PlatformManifest.txt" Condition="'$(BuildTargetFramework)' == '$(NetCoreAppCurrent)' or '$(BuildTargetFramework)' == ''"> @@ -103,16 +103,16 @@ + TargetRuntimeIdentifier="$(OutputRID)" /> - runtimes/$(OutputRid)/lib/$(NetCoreAppCurrent) + runtimes/$(OutputRID)/lib/$(NetCoreAppCurrent) - runtimes/$(OutputRid)/native + runtimes/$(OutputRID)/native true diff --git a/src/libraries/sendtohelix-wasm.targets b/src/libraries/sendtohelix-wasm.targets index e6be4a9df2f3ef..7a73b732b94e24 100644 --- a/src/libraries/sendtohelix-wasm.targets +++ b/src/libraries/sendtohelix-wasm.targets @@ -231,6 +231,14 @@ %(Identity) $(HelixCommand) $(_workItemTimeout) + + 01:20:00 + 01:20:00 + 01:20:00 + 01:20:00 @@ -253,7 +261,13 @@ %(Identity) $(HelixCommand) $(_workItemTimeout) + + 01:20:00 + 01:20:00 + 01:20:00 + 01:20:00 + diff --git a/src/libraries/sfx.proj b/src/libraries/sfx.proj index d5a37e1959d30e..f23bfea607ea37 100644 --- a/src/libraries/sfx.proj +++ b/src/libraries/sfx.proj @@ -43,7 +43,7 @@ Condition="'$(RefOnly)' != 'true'" Inputs="@(SharedFrameworkAssembly);@(SharedFrameworkSuppressionsXml);$(ILLinkTasksAssembly)" Outputs="$(SharedFrameworkAssembliesTrimMarkerFile)"> - + $(ILLinkArgs) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 29886d166cd762..ec83814b18d8ef 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -453,10 +453,6 @@ - - - diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 77b4d14346decf..92a0ac8ea82a51 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -41,9 +41,11 @@ set(CMAKE_MODULE_PATH ) set(CMAKE_INSTALL_MESSAGE LAZY) -find_program(CCACHE_PROGRAM ccache) -if(CCACHE_PROGRAM) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") +if(USE_CCACHE) + find_program(CCACHE_PROGRAM ccache) + if(CCACHE_PROGRAM) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") + endif() endif() function(append value) diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 709f018ad2d47d..b8e53f4ed0feab 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -227,7 +227,6 @@ - @@ -236,6 +235,7 @@ + @@ -272,7 +272,7 @@ CommonSystem\Collections\Generic\ArrayBuilder.cs - + @@ -280,6 +280,10 @@ + + + + diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs index 494a2bc3b86f6f..28cbe9e7cb2a84 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs @@ -77,13 +77,12 @@ internal object Invoke() return result; } - internal CustomAttributeBuilder(ConstructorInfo con, byte[] binaryAttribute) + internal CustomAttributeBuilder(ConstructorInfo con, ReadOnlySpan binaryAttribute) { ArgumentNullException.ThrowIfNull(con); - ArgumentNullException.ThrowIfNull(binaryAttribute); ctor = con; - data = (byte[])binaryAttribute.Clone(); + data = binaryAttribute.ToArray(); /* should we check that the user supplied data is correct? */ } @@ -268,7 +267,7 @@ private void Initialize(ConstructorInfo con, object?[] constructorArgs, } /* helper methods */ - internal static int decode_len(byte[] data, int pos, out int rpos) + internal static int decode_len(ReadOnlySpan data, int pos, out int rpos) { int len; if ((data[pos] & 0x80) == 0) @@ -289,9 +288,9 @@ internal static int decode_len(byte[] data, int pos, out int rpos) return len; } - internal static string string_from_bytes(byte[] data, int pos, int len) + internal static string string_from_bytes(ReadOnlySpan data, int pos, int len) { - return Text.Encoding.UTF8.GetString(data, pos, len); + return Text.Encoding.UTF8.GetString(data.Slice(pos, len)); } internal static string? decode_string(byte[] data, int pos, out int rpos) @@ -454,7 +453,7 @@ private static Type elementTypeToType(int elementType) => _ => throw new Exception(SR.Format(SR.ArgumentException_InvalidTypeArgument, elementType)), }; - private static object? decode_cattr_value(Type t, byte[] data, int pos, out int rpos) + private static object? decode_cattr_value(Type t, ReadOnlySpan data, int pos, out int rpos) { switch (Type.GetTypeCode(t)) { @@ -494,14 +493,19 @@ internal struct CustomAttributeInfo public object?[] namedParamValues; } + internal static CustomAttributeInfo decode_cattr(CustomAttributeBuilder customBuilder) + { + byte[] data = customBuilder.Data; + ConstructorInfo ctor = customBuilder.Ctor; + return decode_cattr(ctor, data); + } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2057:UnrecognizedReflectionPattern", Justification = "Types referenced from custom attributes are preserved")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", Justification = "Types referenced from custom attributes are preserved")] - internal static CustomAttributeInfo decode_cattr(CustomAttributeBuilder customBuilder) + internal static CustomAttributeInfo decode_cattr(ConstructorInfo ctor, ReadOnlySpan data) { - byte[] data = customBuilder.Data; - ConstructorInfo ctor = customBuilder.Ctor; int pos; CustomAttributeInfo info = default; diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.Mono.cs index a5bfdaabee1f33..929b9c1ec1f594 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeAssemblyBuilder.Mono.cs @@ -256,6 +256,8 @@ internal RuntimeAssemblyBuilder(AssemblyName n, AssemblyBuilderAccess access) // Netcore only allows one module per assembly manifest_module = new RuntimeModuleBuilder(this, "RefEmit_InMemoryManifestModule"); modules = new RuntimeModuleBuilder[] { manifest_module }; + + AssemblyLoadContext.InvokeAssemblyLoadEvent (this); } public override bool ReflectionOnly @@ -297,8 +299,9 @@ internal static AssemblyBuilder InternalDefineDynamicAssembly( public override bool IsCollectible => access == (uint)AssemblyBuilderAccess.RunAndCollect; - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -315,11 +318,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil UpdateNativeCustomAttributes(this); } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - /*Warning, @typeArguments must be a mscorlib internal array. So make a copy before passing it in*/ internal static Type MakeGenericType(Type gtd, Type[] typeArguments) => new TypeBuilderInstantiation(gtd, typeArguments); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.Mono.cs index f9939d27b3183b..ecfae6b04ab4bf 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.Mono.cs @@ -37,6 +37,7 @@ using System.Globalization; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using System.Buffers.Binary; namespace System.Reflection.Emit { @@ -221,7 +222,7 @@ protected override ParameterBuilder DefineParameterCore(int iSequence, Parameter if (type.is_created) throw not_after_created(); - ParameterBuilder pb = new ParameterBuilder(this, iSequence, attributes, strParamName); + ParameterBuilder pb = new RuntimeParameterBuilder(this, iSequence, attributes, strParamName); pinfo ??= new ParameterBuilder[parameters!.Length + 1]; pinfo[iSequence] = pb; return pb; @@ -254,20 +255,16 @@ protected override ILGenerator GetILGeneratorCore(int streamSize) return ilgen; } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - ArgumentNullException.ThrowIfNull(customBuilder); - - string? attrname = customBuilder.Ctor.ReflectedType!.FullName; + string? attrname = con.ReflectedType!.FullName; if (attrname == "System.Runtime.CompilerServices.MethodImplAttribute") { - byte[] data = customBuilder.Data; - int impla; // the (stupid) ctor takes a short or an int ... - impla = (int)data[2]; - impla |= ((int)data[3]) << 8; + int impla = BinaryPrimitives.ReadUInt16LittleEndian(binaryAttribute.Slice(2)); SetImplementationFlags((MethodImplAttributes)impla); return; } + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -282,14 +279,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil } } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - ArgumentNullException.ThrowIfNull(con); - ArgumentNullException.ThrowIfNull(binaryAttribute); - - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - protected override void SetImplementationFlagsCore(MethodImplAttributes attributes) { if (type.is_created) diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.Mono.cs index ab54737e986dcb..b417c32f06abae 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEnumBuilder.Mono.cs @@ -447,14 +447,9 @@ public override Type MakePointerType() return SymbolType.FormCompoundType("*", this, 0)!; } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - _tb.SetCustomAttribute(customBuilder); - } - - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); + _tb.SetCustomAttribute(con, binaryAttribute); } internal override bool IsUserType diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.Mono.cs index 8ff4a3df89eac5..5cbfea669f365d 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeEventBuilder.Mono.cs @@ -106,15 +106,16 @@ protected override void SetRemoveOnMethodCore(MethodBuilder mdBuilder) remove_method = mdBuilder; } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { RejectIfCreated(); - string? attrname = customBuilder.Ctor.ReflectedType!.FullName; + string? attrname = con.ReflectedType!.FullName; if (attrname == "System.Runtime.CompilerServices.SpecialNameAttribute") { attrs |= EventAttributes.SpecialName; return; } + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -129,11 +130,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil } } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - private void RejectIfCreated() { if (typeb.is_created) diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.Mono.cs index db8d805de1646b..68f4c7b2bbf74b 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeFieldBuilder.Mono.cs @@ -37,6 +37,7 @@ using System.Globalization; using System.Runtime.InteropServices; using System.Diagnostics.CodeAnalysis; +using System.Buffers.Binary; namespace System.Reflection.Emit { @@ -174,18 +175,14 @@ protected override void SetConstantCore(object? defaultValue) def_value = defaultValue; } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { RejectIfCreated(); - - string? attrname = customBuilder.Ctor.ReflectedType!.FullName; + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); + string? attrname = con.ReflectedType!.FullName; if (attrname == "System.Runtime.InteropServices.FieldOffsetAttribute") { - byte[] data = customBuilder.Data; - offset = (int)data[2]; - offset |= ((int)data[3]) << 8; - offset |= ((int)data[4]) << 16; - offset |= ((int)data[5]) << 24; + offset = BinaryPrimitives.ReadInt32LittleEndian(binaryAttribute.Slice(2)); return; } #pragma warning disable SYSLIB0050 // FieldAttributes.NotSerialized is obsolete @@ -221,12 +218,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil } } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - RejectIfCreated(); - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - protected override void SetOffsetCore(int iOffset) { RejectIfCreated(); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs index a1f176127f97f8..27e0d2e9975561 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeGenericTypeParameterBuilder.cs @@ -424,8 +424,9 @@ public override MethodBase? DeclaringMethod get { return mbuilder; } } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -440,12 +441,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil } } - // FIXME: "unverified implementation" - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - private static NotSupportedException not_supported() { return new NotSupportedException(); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs index 80e8352d04b40e..88996e06647a30 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs @@ -34,6 +34,7 @@ // #if MONO_FEATURE_SRE +using System.Buffers.Binary; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; @@ -334,7 +335,7 @@ protected override ParameterBuilder DefineParameterCore(int position, ParameterA if ((position < 0) || parameters == null || (position > parameters.Length)) throw new ArgumentOutOfRangeException(nameof(position)); - ParameterBuilder pb = new ParameterBuilder(this, position, attributes, strParamName); + ParameterBuilder pb = new RuntimeParameterBuilder(this, position, attributes, strParamName); pinfo ??= new ParameterBuilder[parameters.Length + 1]; pinfo[position] = pb; return pb; @@ -381,20 +382,17 @@ internal void ResolveUserTypes() } } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - switch (customBuilder.Ctor.ReflectedType!.FullName) + switch (con.ReflectedType!.FullName) { case "System.Runtime.CompilerServices.MethodImplAttribute": - byte[] data = customBuilder.Data; - int impla; // the (stupid) ctor takes a short or an int ... - impla = (int)data[2]; - impla |= ((int)data[3]) << 8; + int impla = BinaryPrimitives.ReadUInt16LittleEndian(binaryAttribute.Slice(2)); iattrs |= (MethodImplAttributes)impla; return; case "System.Runtime.InteropServices.DllImportAttribute": - CustomAttributeBuilder.CustomAttributeInfo attr = CustomAttributeBuilder.decode_cattr(customBuilder); + CustomAttributeBuilder.CustomAttributeInfo attr = CustomAttributeBuilder.decode_cattr(con, binaryAttribute); bool preserveSig = true; /* @@ -453,6 +451,7 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil break; } + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -467,11 +466,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil } } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - protected override void SetImplementationFlagsCore(MethodImplAttributes attributes) { RejectIfCreated(); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.Mono.cs index a6ab47cae28d3e..85e98ea5b84a4c 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.Mono.cs @@ -426,8 +426,9 @@ internal int get_next_table_index(int table, int count) return index; } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -441,11 +442,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil cattrs[0] = customBuilder; } } - - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } /* internal ISymbolDocumentWriter? DefineDocument (string url, Guid language, Guid languageVendor, Guid documentType) { diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeParameterBuilder.Mono.cs similarity index 82% rename from src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.Mono.cs rename to src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeParameterBuilder.Mono.cs index d634f330a21bb3..2f682a29d674aa 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ParameterBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeParameterBuilder.Mono.cs @@ -41,7 +41,7 @@ namespace System.Reflection.Emit { [StructLayout(LayoutKind.Sequential)] - public partial class ParameterBuilder + internal sealed class RuntimeParameterBuilder : ParameterBuilder { #region Sync with MonoReflectionParamBuilder in object-internals.h private MethodBase methodb; /* MethodBuilder, ConstructorBuilder or DynamicMethod */ @@ -55,7 +55,7 @@ public partial class ParameterBuilder #endregion [DynamicDependency(nameof(def_value))] // Automatically keeps all previous fields too due to StructLayout - internal ParameterBuilder(MethodBase mb, int pos, ParameterAttributes attributes, string? strParamName) + internal RuntimeParameterBuilder(MethodBase mb, int pos, ParameterAttributes attributes, string? strParamName) { name = strParamName; position = pos; @@ -67,32 +67,20 @@ internal ParameterBuilder(MethodBase mb, int pos, ParameterAttributes attributes table_idx = mb.get_next_table_index(0x08, 1); } - public virtual int Attributes + public override int Attributes { get { return (int)attrs; } } - public bool IsIn - { - get { return ((int)attrs & (int)ParameterAttributes.In) != 0; } - } - public bool IsOut - { - get { return ((int)attrs & (int)ParameterAttributes.Out) != 0; } - } - public bool IsOptional - { - get { return ((int)attrs & (int)ParameterAttributes.Optional) != 0; } - } - public virtual string? Name + public override string? Name { get { return name; } } - public virtual int Position + public override int Position { get { return position; } } - public virtual void SetConstant(object? defaultValue) + public override void SetConstant(object? defaultValue) { if (position > 0) { @@ -104,9 +92,10 @@ public virtual void SetConstant(object? defaultValue) attrs |= ParameterAttributes.HasDefault; } - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - string? attrname = customBuilder.Ctor.ReflectedType!.FullName; + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); + string? attrname = con.ReflectedType!.FullName; if (attrname == "System.Runtime.InteropServices.InAttribute") { attrs |= ParameterAttributes.In; @@ -151,11 +140,6 @@ public void SetCustomAttribute(CustomAttributeBuilder customBuilder) cattrs[0] = customBuilder; } } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } } } diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.Mono.cs index 80c8d942ccd68f..25dbb485d23c3e 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.Mono.cs @@ -159,16 +159,18 @@ protected override void SetConstantCore(object? defaultValue) def_value = defaultValue; } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { typeb.check_not_created(); - string? attrname = customBuilder.Ctor.ReflectedType!.FullName; + string? attrname = con.ReflectedType!.FullName; if (attrname == "System.Runtime.CompilerServices.SpecialNameAttribute") { attrs |= PropertyAttributes.SpecialName; return; } + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); + if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -183,11 +185,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil } } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - protected override void SetGetMethodCore(MethodBuilder mdBuilder) { typeb.check_not_created(); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs index 98670c99f16313..469f9efebb744b 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs @@ -34,6 +34,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -1411,15 +1412,19 @@ public override RuntimeTypeHandle TypeHandle } } - protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) + internal void SetCustomAttribute(ConstructorInfo con, ReadOnlySpan binaryAttribute) { - string? attrname = customBuilder.Ctor.ReflectedType!.FullName; + SetCustomAttributeCore(con, binaryAttribute); + } + + protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) + { + string? attrname = con.ReflectedType!.FullName; if (attrname == "System.Runtime.InteropServices.StructLayoutAttribute") { - byte[] data = customBuilder.Data; int layout_kind; /* the (stupid) ctor takes a short or an int ... */ - layout_kind = (int)data[2]; - layout_kind |= ((int)data[3]) << 8; + layout_kind = (int)binaryAttribute[2]; + layout_kind |= ((int)binaryAttribute[3]) << 8; attrs &= ~TypeAttributes.LayoutMask; attrs |= ((LayoutKind)layout_kind) switch { @@ -1429,38 +1434,36 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil _ => throw new Exception(SR.Argument_InvalidKindOfTypeForCA), // we should ignore it since it can be any value anyway... }; - Type ctor_type = customBuilder.Ctor is RuntimeConstructorBuilder builder ? builder.parameters![0] : customBuilder.Ctor.GetParametersInternal()[0].ParameterType; + Type ctor_type = con is RuntimeConstructorBuilder builder ? builder.parameters![0] : con.GetParametersInternal()[0].ParameterType; int pos = 6; if (ctor_type.FullName == "System.Int16") pos = 4; - int nnamed = (int)data[pos++]; - nnamed |= ((int)data[pos++]) << 8; + int nnamed = BinaryPrimitives.ReadUInt16LittleEndian(binaryAttribute.Slice(pos++)); + pos++; for (int i = 0; i < nnamed; ++i) { //byte named_type = data [pos++]; pos++; - byte type = data[pos++]; + byte type = binaryAttribute[pos++]; int len; string named_name; if (type == 0x55) { - len = CustomAttributeBuilder.decode_len(data, pos, out pos); + len = CustomAttributeBuilder.decode_len(binaryAttribute, pos, out pos); //string named_typename = - CustomAttributeBuilder.string_from_bytes(data, pos, len); + CustomAttributeBuilder.string_from_bytes(binaryAttribute, pos, len); pos += len; // FIXME: Check that 'named_type' and 'named_typename' match, etc. // See related code/FIXME in mono/mono/metadata/reflection.c } - len = CustomAttributeBuilder.decode_len(data, pos, out pos); - named_name = CustomAttributeBuilder.string_from_bytes(data, pos, len); + len = CustomAttributeBuilder.decode_len(binaryAttribute, pos, out pos); + named_name = CustomAttributeBuilder.string_from_bytes(binaryAttribute, pos, len); pos += len; /* all the fields are integers in StructLayout */ - int value = (int)data[pos++]; - value |= ((int)data[pos++]) << 8; - value |= ((int)data[pos++]) << 16; - value |= ((int)data[pos++]) << 24; + int value = BinaryPrimitives.ReadInt32LittleEndian(binaryAttribute.Slice(pos++)); + pos += 3; switch (named_name) { case "CharSet": @@ -1520,6 +1523,8 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil is_byreflike_set = 1; } + CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(con, binaryAttribute); + if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder[cattrs.Length + 1]; @@ -1534,11 +1539,6 @@ protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuil } } - protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttributeCore(new CustomAttributeBuilder(con, binaryAttribute)); - } - protected override EventBuilder DefineEventCore(string name, EventAttributes attributes, Type eventtype) { check_name(nameof(name), name); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/MethodInvoker.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/MethodInvoker.Mono.cs index 99df70de828fbb..b6a2a83b5514a3 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/MethodInvoker.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/MethodInvoker.Mono.cs @@ -18,7 +18,7 @@ public MethodInvoker(MethodBase method) } else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke) { - // Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing. + // Always use emit invoke (if IsDynamicCodeSupported == true); useful for testing. _invoked = true; } } diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoAsyncWaitSemaphore.Browser.Threads.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoAsyncWaitSemaphore.Browser.Threads.Mono.cs new file mode 100644 index 00000000000000..0bb2d90bba2d4f --- /dev/null +++ b/src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoAsyncWaitSemaphore.Browser.Threads.Mono.cs @@ -0,0 +1,223 @@ +// 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.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Threading; + +// +// This class provides a way for browser threads to asynchronously wait for a semaphore +// from JS, without using the threadpool. It is used to implement threadpool workers. +// +internal sealed partial class LowLevelLifoAsyncWaitSemaphore : LowLevelLifoSemaphoreBase, IDisposable +{ + private IntPtr lifo_semaphore; + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern IntPtr InitInternal(); + + public LowLevelLifoAsyncWaitSemaphore(int initialSignalCount, int maximumSignalCount, int spinCount, Action onWait) + : base (initialSignalCount, maximumSignalCount, spinCount, onWait) + { + CreateAsyncWait(maximumSignalCount); + } + +#pragma warning disable IDE0060 + private void CreateAsyncWait(int maximumSignalCount) +#pragma warning restore IDE0060 + { + lifo_semaphore = InitInternal(); + } + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void DeleteInternal(IntPtr semaphore); + + public void Dispose() + { + DeleteInternal(lifo_semaphore); + lifo_semaphore = IntPtr.Zero; + } + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void ReleaseInternal(IntPtr semaphore, int count); + + protected override void ReleaseCore(int count) + { + ReleaseInternal(lifo_semaphore, count); + } + + private sealed record WaitEntry (LowLevelLifoAsyncWaitSemaphore Semaphore, Action OnSuccess, Action OnTimeout, object? State) + { + public int TimeoutMs {get; internal set;} + public int StartWaitTicks {get; internal set; } + } + + public void PrepareAsyncWait(int timeoutMs, Action onSuccess, Action onTimeout, object? state) + { + Debug.Assert(timeoutMs >= -1); + + // Try to acquire the semaphore or + // a) register as a waiter and timeoutMs > 0 + // b) bail out if timeoutMs == 0 and return false + Counts counts = _separated._counts; + while (true) + { + Debug.Assert(counts.SignalCount <= _maximumSignalCount); + Counts newCounts = counts; + if (counts.SignalCount != 0) + { + newCounts.DecrementSignalCount(); + } + else if (timeoutMs != 0) + { + // Maximum number of spinners reached, register as a waiter instead + newCounts.IncrementWaiterCount(); + } + + Counts countsBeforeUpdate = _separated._counts.InterlockedCompareExchange(newCounts, counts); + if (countsBeforeUpdate == counts) + { + if (counts.SignalCount != 0) + { + onSuccess (this, state); + return; + } + if (newCounts.WaiterCount != counts.WaiterCount) + { + PrepareAsyncWaitForSignal(timeoutMs, onSuccess, onTimeout, state); + return; + } + if (timeoutMs == 0) + { + onTimeout (this, state); + return; + } + break; + } + + counts = countsBeforeUpdate; + } + + Debug.Fail("unreachable"); + } + + private void PrepareAsyncWaitForSignal(int timeoutMs, Action onSuccess, Action onTimeout, object? state) + { + Debug.Assert(timeoutMs > 0 || timeoutMs == -1); + + _onWait(); + + WaitEntry we = new WaitEntry(this, onSuccess, onTimeout, state) + { + TimeoutMs = timeoutMs, + StartWaitTicks = timeoutMs != -1 ? Environment.TickCount : 0, + }; + PrepareAsyncWaitCore(we); + // on success calls InternalAsyncWaitSuccess, on timeout calls InternalAsyncWaitTimeout + } + + private static void InternalAsyncWaitTimeout(LowLevelLifoAsyncWaitSemaphore self, WaitEntry internalWaitEntry) + { + WaitEntry we = internalWaitEntry!; + // Unregister the waiter. The wait subsystem used above guarantees that a thread that wakes due to a timeout does + // not observe a signal to the object being waited upon. + self._separated._counts.InterlockedDecrementWaiterCount(); + we.OnTimeout(self, we.State); + } + + private static void InternalAsyncWaitSuccess(LowLevelLifoAsyncWaitSemaphore self, WaitEntry internalWaitEntry) + { + WaitEntry we = internalWaitEntry!; + int endWaitTicks = we.TimeoutMs != -1 ? Environment.TickCount : 0; + // Unregister the waiter if this thread will not be waiting anymore, and try to acquire the semaphore + Counts counts = self._separated._counts; + while (true) + { + Debug.Assert(counts.WaiterCount != 0); + Counts newCounts = counts; + if (counts.SignalCount != 0) + { + newCounts.DecrementSignalCount(); + newCounts.DecrementWaiterCount(); + } + + // This waiter has woken up and this needs to be reflected in the count of waiters signaled to wake + if (counts.CountOfWaitersSignaledToWake != 0) + { + newCounts.DecrementCountOfWaitersSignaledToWake(); + } + + Counts countsBeforeUpdate = self._separated._counts.InterlockedCompareExchange(newCounts, counts); + if (countsBeforeUpdate == counts) + { + if (counts.SignalCount != 0) + { + we.OnSuccess(self, we.State); + return; + } + break; + } + + counts = countsBeforeUpdate; + } + // if we get here, we need to keep waiting because the SignalCount above was 0 after we did + // the CompareExchange - someone took the signal before us. + + if (we.TimeoutMs != -1) { + int waitMs = endWaitTicks - we.StartWaitTicks; + if (waitMs >= 0 && waitMs < we.TimeoutMs) + we.TimeoutMs -= waitMs; + else + we.TimeoutMs = 0; + we.StartWaitTicks = endWaitTicks; + } + PrepareAsyncWaitCore (we); + // on success calls InternalAsyncWaitSuccess, on timeout calls InternalAsyncWaitTimeout + } + + private static void PrepareAsyncWaitCore(WaitEntry internalWaitEntry) + { + int timeoutMs = internalWaitEntry.TimeoutMs; + LowLevelLifoAsyncWaitSemaphore semaphore = internalWaitEntry.Semaphore; + if (timeoutMs == 0) { + internalWaitEntry.OnTimeout (semaphore, internalWaitEntry.State); + return; + } + GCHandle gchandle = GCHandle.Alloc (internalWaitEntry); + unsafe { + delegate* unmanaged successCallback = &SuccessCallback; + delegate* unmanaged timeoutCallback = &TimeoutCallback; + PrepareAsyncWaitInternal (semaphore.lifo_semaphore, timeoutMs, successCallback, timeoutCallback, GCHandle.ToIntPtr(gchandle)); + } + } + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern unsafe void PrepareAsyncWaitInternal(IntPtr semaphore, + int timeoutMs, + /*delegate* unmanaged successCallback*/ void* successCallback, + /*delegate* unmanaged timeoutCallback*/ void* timeoutCallback, + IntPtr userData); + + [UnmanagedCallersOnly] + private static void SuccessCallback(IntPtr lifoSemaphore, IntPtr userData) + { + GCHandle gchandle = GCHandle.FromIntPtr(userData); + WaitEntry internalWaitEntry = (WaitEntry)gchandle.Target!; + gchandle.Free(); + InternalAsyncWaitSuccess(internalWaitEntry.Semaphore, internalWaitEntry); + } + + [UnmanagedCallersOnly] + private static void TimeoutCallback(IntPtr lifoSemaphore, IntPtr userData) + { + GCHandle gchandle = GCHandle.FromIntPtr(userData); + WaitEntry internalWaitEntry = (WaitEntry)gchandle.Target!; + gchandle.Free(); + InternalAsyncWaitTimeout(internalWaitEntry.Semaphore, internalWaitEntry); + } + +} diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.Mono.cs index 180f802ed84ca0..82365c61b8bb67 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.Mono.cs @@ -5,7 +5,7 @@ namespace System.Threading { - internal sealed unsafe partial class LowLevelLifoSemaphore : IDisposable + internal sealed unsafe partial class LowLevelLifoSemaphore : LowLevelLifoSemaphoreBase, IDisposable { private IntPtr lifo_semaphore; @@ -14,10 +14,10 @@ internal sealed unsafe partial class LowLevelLifoSemaphore : IDisposable #pragma warning disable IDE0060 private void Create(int maximumSignalCount) +#pragma warning restore IDE0060 { lifo_semaphore = InitInternal(); } -#pragma warning restore IDE0060 [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void DeleteInternal(IntPtr semaphore); @@ -39,7 +39,7 @@ private bool WaitCore(int timeoutMs) [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void ReleaseInternal(IntPtr semaphore, int count); - private void ReleaseCore(int count) + protected override void ReleaseCore(int count) { ReleaseInternal(lifo_semaphore, count); } diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.Mono.cs new file mode 100644 index 00000000000000..632b0c934ee4c0 --- /dev/null +++ b/src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.Mono.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Threading; + +internal sealed partial class PortableThreadPool +{ + private static partial class WorkerThread + { + private static bool IsIOPending => WebWorkerEventLoop.HasJavaScriptInteropDependents; + } + + private struct CpuUtilizationReader + { +#pragma warning disable CA1822 + public double CurrentUtilization => 0.0; // FIXME: can we do better +#pragma warning restore CA1822 + } +} diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.Browser.Threads.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.Browser.Threads.Mono.cs new file mode 100644 index 00000000000000..b45dee7fa2fd6f --- /dev/null +++ b/src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.Browser.Threads.Mono.cs @@ -0,0 +1,122 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Tracing; +using System.Runtime.CompilerServices; + +namespace System.Threading +{ + internal sealed partial class PortableThreadPool + { + /// + /// The worker thread infastructure for the CLR thread pool. + /// + private static partial class WorkerThread + { + /// + /// Semaphore for controlling how many threads are currently working. + /// + private static readonly LowLevelLifoAsyncWaitSemaphore s_semaphore = + new LowLevelLifoAsyncWaitSemaphore( + 0, + MaxPossibleThreadCount, + AppContextConfigHelper.GetInt32Config( + "System.Threading.ThreadPool.UnfairSemaphoreSpinLimit", + SemaphoreSpinCountDefault, + false), + onWait: () => + { + if (NativeRuntimeEventSource.Log.IsEnabled()) + { + NativeRuntimeEventSource.Log.ThreadPoolWorkerThreadWait( + (uint)ThreadPoolInstance._separated.counts.VolatileRead().NumExistingThreads); + } + }); + + private static readonly ThreadStart s_workerThreadStart = WorkerThreadStart; + + private sealed record SemaphoreWaitState(PortableThreadPool ThreadPoolInstance, LowLevelLock ThreadAdjustmentLock, WebWorkerEventLoop.KeepaliveToken KeepaliveToken) + { + public bool SpinWait = true; + + public void ResetIteration() { + SpinWait = true; + } + } + + private static void WorkerThreadStart() + { + Thread.CurrentThread.SetThreadPoolWorkerThreadName(); + + PortableThreadPool threadPoolInstance = ThreadPoolInstance; + + if (NativeRuntimeEventSource.Log.IsEnabled()) + { + NativeRuntimeEventSource.Log.ThreadPoolWorkerThreadStart( + (uint)threadPoolInstance._separated.counts.VolatileRead().NumExistingThreads); + } + + LowLevelLock threadAdjustmentLock = threadPoolInstance._threadAdjustmentLock; + var keepaliveToken = WebWorkerEventLoop.KeepalivePush(); + SemaphoreWaitState state = new(threadPoolInstance, threadAdjustmentLock, keepaliveToken) { SpinWait = true }; + // set up the callbacks for semaphore waits, tell + // emscripten to keep the thread alive, and return to + // the JS event loop. + WaitForWorkLoop(s_semaphore, state); + // return from thread start with keepalive - the thread will stay alive in the JS event loop + } + + private static readonly Action s_WorkLoopSemaphoreSuccess = new(WorkLoopSemaphoreSuccess); + private static readonly Action s_WorkLoopSemaphoreTimedOut = new(WorkLoopSemaphoreTimedOut); + + private static void WaitForWorkLoop(LowLevelLifoAsyncWaitSemaphore semaphore, SemaphoreWaitState state) + { + semaphore.PrepareAsyncWait(ThreadPoolThreadTimeoutMs, s_WorkLoopSemaphoreSuccess, s_WorkLoopSemaphoreTimedOut, state); + // thread should still be kept alive + Debug.Assert(state.KeepaliveToken.Valid); + } + + private static void WorkLoopSemaphoreSuccess(LowLevelLifoAsyncWaitSemaphore semaphore, object? stateObject) + { + SemaphoreWaitState state = (SemaphoreWaitState)stateObject!; + WorkerDoWork(state.ThreadPoolInstance, ref state.SpinWait); + // Go around the loop one more time, keeping existing mutated state + WaitForWorkLoop(semaphore, state); + } + + private static void WorkLoopSemaphoreTimedOut(LowLevelLifoAsyncWaitSemaphore semaphore, object? stateObject) + { + SemaphoreWaitState state = (SemaphoreWaitState)stateObject!; + if (ShouldExitWorker(state.ThreadPoolInstance, state.ThreadAdjustmentLock)) { + // we're done, kill the thread. + + // we're wrapped in an emscripten eventloop handler which will consult the + // keepalive count, destroy the thread and run the TLS dtor which will + // unregister the thread from Mono + state.KeepaliveToken.Pop(); + return; + } else { + // more work showed up while we were shutting down, go around one more time + state.ResetIteration(); + WaitForWorkLoop(semaphore, state); + } + } + + private static void CreateWorkerThread() + { + // Thread pool threads must start in the default execution context without transferring the context, so + // using captureContext: false. + Thread workerThread = new Thread(s_workerThreadStart); + workerThread.IsThreadPoolThread = true; + workerThread.IsBackground = true; + // thread name will be set in thread proc + + // This thread will return to the JS event loop - tell the runtime not to cleanup + // after the start function returns, if the Emscripten keepalive is non-zero. + WebWorkerEventLoop.StartExitable(workerThread, captureContext: false); + } + } + } +} diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs index 31bc824008607c..d5b1918608b77f 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs @@ -37,6 +37,7 @@ public partial class Thread private int interruption_requested; private IntPtr longlived; internal bool threadpool_thread; + internal bool external_eventloop; // browser-wasm: thread will return to the JS eventloop /* These are used from managed code */ internal byte apartment_state; internal int managed_id; @@ -352,5 +353,17 @@ private static void SpinWait_nop() private static extern void SetPriority(Thread thread, int priority); internal int GetSmallId() => small_id; + + internal bool HasExternalEventLoop + { + get + { + return external_eventloop; + } + set + { + external_eventloop = value; + } + } } } diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.Mono.cs new file mode 100644 index 00000000000000..7933e49db422b9 --- /dev/null +++ b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.Mono.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Threading +{ + public static partial class ThreadPool + { + // Indicates that the threadpool should yield the thread from the dispatch loop to the + // runtime periodically. We use this to return back to the JS event loop so that the JS + // event queue can be drained + internal static bool YieldFromDispatchLoop => true; + } +} diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs index 580df53de2a8df..ba5e678e874277 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs @@ -65,7 +65,7 @@ private bool SetTimer(uint actualDuration) // shortest time of all TimerQueues private static void ReplaceNextSetTimeout(long shortestDueTimeMs, long currentTimeMs) { - if (shortestDueTimeMs == int.MaxValue) + if (shortestDueTimeMs == long.MaxValue) { return; } @@ -85,7 +85,7 @@ private static long ShortestDueTime() { if (s_scheduledTimers == null) { - return int.MaxValue; + return long.MaxValue; } long shortestDueTimeMs = long.MaxValue; @@ -112,7 +112,7 @@ private static long PumpTimerQueue(long currentTimeMs) List timersToFire = s_scheduledTimersToFire!; List timers; timers = s_scheduledTimers!; - long shortestDueTimeMs = int.MaxValue; + long shortestDueTimeMs = long.MaxValue; for (int i = timers.Count - 1; i >= 0; --i) { TimerQueue timer = timers[i]; diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/WebWorkerEventLoop.Browser.Threads.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/WebWorkerEventLoop.Browser.Threads.Mono.cs index 5a49c076271d1c..73c2959293d525 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/WebWorkerEventLoop.Browser.Threads.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/WebWorkerEventLoop.Browser.Threads.Mono.cs @@ -67,10 +67,10 @@ internal static void StartExitable(Thread thread, bool captureContext) // not needed by PortableThreadPool.WorkerThread if (captureContext) throw new InvalidOperationException(); - // hack: threadpool threads are exitable, and nothing else is. - // see create_thread() in mono/metadata/threads.c + // for now, threadpool threads are exitable, and nothing else is. if (!thread.IsThreadPoolThread) throw new InvalidOperationException(); + thread.HasExternalEventLoop = true; thread.UnsafeStart(); } diff --git a/src/mono/mono.proj b/src/mono/mono.proj index f0a7d7e6ab82c1..8765984d989d34 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -360,7 +360,6 @@ <_MonoCMakeArgs Include="-DCMAKE_TOOLCHAIN_FILE=$(CrossToolchainFile)" /> <_MonoBuildEnv Include="TARGET_BUILD_ARCH=arm64" /> - <_MonoBuildEnv Include="PKG_CONFIG_PATH=$(MonoCrossDir)usr/local/libdata/pkgconfig" /> @@ -738,7 +737,6 @@ $(MonoLLVMDir)/$(BuildArchitecture)/lib/libclang.dylib $(MonoLLVMDir)/$(BuildArchitecture)/lib/libclang.so $([MSBuild]::NormalizePath('$(MonoLLVMDir)', '$(BuildArchitecture)', 'bin', 'libclang.dll')) - setlocal EnableDelayedExpansion && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && !EMSDK_PYTHON! <_ForceRelease Condition="$([MSBuild]::IsOSPlatform('Windows')) and '$(TargetArchitecture)' == 'wasm' and '$(Configuration)' == 'Debug'">true @@ -917,7 +915,6 @@ <_MonoRuntimeFilePath>$(MonoObjDir)out\lib\$(MonoFileName) <_MonoRuntimeStaticFilePath Condition="'$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">$(MonoObjDir)out\lib\$(MonoStaticLibFileName) <_MonoIncludeInterpStaticFiles Condition="'$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true'">true - <_MonoIncludeIcuFiles Condition="'$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsMacCatalyst)' == 'true'">true <_MonoAotCrossFilePath>$(MonoObjCrossDir)out\bin\$(MonoAotCrossFileName) @@ -954,10 +951,10 @@ $(RuntimeBinDir)%(_MonoRuntimeComponentsSharedFilePath.Filename)%(_MonoRuntimeComponentsSharedFilePath.Extension) <_MonoRuntimeArtifacts Include="$(_MonoAotCrossFilePath)"> - $(RuntimeBinDir)cross\$(OutputRid)\$(MonoAotCrossFileName) + $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossFileName) <_MonoRuntimeArtifacts Include="$(_MonoAotCrossPdbFilePath)" Condition="Exists('$(_MonoAotCrossPdbFilePath)')"> - $(RuntimeBinDir)cross\$(OutputRid)\$(MonoAotCrossPdbFileName) + $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossPdbFileName) <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\bin\llc$(ExeSuffix)"> $(RuntimeBinDir)\llc$(ExeSuffix) @@ -966,10 +963,10 @@ $(RuntimeBinDir)\opt$(ExeSuffix) <_MonoRuntimeArtifacts Condition="'$(MonoAOTBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\bin\llc$(ExeSuffix)"> - $(RuntimeBinDir)cross\$(OutputRid)\llc$(ExeSuffix) + $(RuntimeBinDir)cross\$(OutputRID)\llc$(ExeSuffix) <_MonoRuntimeArtifacts Condition="'$(MonoAOTBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\bin\opt$(ExeSuffix)"> - $(RuntimeBinDir)cross\$(OutputRid)\opt$(ExeSuffix) + $(RuntimeBinDir)cross\$(OutputRID)\opt$(ExeSuffix) <_MonoIncludeArtifacts Include="$(MonoObjDir)out\include\**" /> <_MonoRuntimeArtifacts Condition="'$(MonoComponentsStatic)' != 'true' and Exists('$(MonoObjDir)out\lib\Mono.release.framework')" Include="@(_MonoRuntimeComponentsSharedFilePath)"> @@ -1040,19 +1037,8 @@ <_MonoICorDebugArtifacts Condition="'$(MonoMsCorDbi)' == 'true'" Include="$(MonoObjDir)out\lib\$(LibPrefix)mscordbi$(LibSuffix)"> $(RuntimeBinDir)$(LibPrefix)mscordbi$(LibSuffix) - - <_IcuArtifacts Condition="'$(_MonoIncludeIcuFiles)' == 'true'" - Include="$(_IcuLibdir)\libicuuc.a; - $(_IcuLibdir)\libicui18n.a; - $(_IcuLibdir)\libicudata.a; - $(_IcuLibdir)\*.dat" /> - - 0) + { + struct timeval timeout; + timeout.tv_sec = 5; + timeout.tv_usec = 0; + setsockopt(sfd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); + } + res = connect (sfd, &sockaddr.addr, sock_len); if (res != SOCKET_ERROR) @@ -4716,10 +4724,11 @@ mono_ss_create_init_args (SingleStepReq *ss_req, SingleStepArgs *args) frame = tls->frames [0]; } - if (ss_req->size == STEP_SIZE_LINE) { + if (ss_req->size == STEP_SIZE_LINE_COLUMN) { if (frame) { ss_req->last_method = frame->de.method; ss_req->last_line = -1; + ss_req->last_column = -1; minfo = mono_debug_lookup_method (frame->de.method); if (minfo && frame->il_offset != -1) { @@ -4727,6 +4736,7 @@ mono_ss_create_init_args (SingleStepReq *ss_req, SingleStepArgs *args) if (loc) { ss_req->last_line = loc->row; + ss_req->last_column = loc->column; g_free (loc); } } @@ -5137,27 +5147,6 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, return; } - if (CHECK_ICORDBG (TRUE)) { - switch (t->type) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_R4: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_R8: - case MONO_TYPE_PTR: - buffer_add_byte (buf, t->type); - buffer_add_long (buf, (gssize) addr); - return; - } - } - switch (t->type) { case MONO_TYPE_VOID: buffer_add_byte (buf, t->type); @@ -5228,7 +5217,7 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, } buffer_add_objid (buf, obj); if (CHECK_ICORDBG (TRUE)) - buffer_add_long (buf, (gssize) addr); + buffer_add_long (buf, (gssize) obj); } break; handle_vtype: @@ -5268,6 +5257,8 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, if (CHECK_PROTOCOL_VERSION(2, 61)) buffer_add_byte(buf, !!boxed_vtype); + if (CHECK_ICORDBG (TRUE)) + buffer_add_long (buf, (gssize) addr); buffer_add_typeid (buf, domain, klass); nfields = 0; @@ -5287,7 +5278,8 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, continue; if (mono_field_is_deleted (f)) continue; - + if (CHECK_ICORDBG (TRUE)) + buffer_add_int (buf, mono_class_get_field_token (f)); if (mono_vtype_get_field_addr (addr, f) == addr && mono_class_from_mono_type_internal (t) == mono_class_from_mono_type_internal (f->type) && !boxed_vtype) //to avoid infinite recursion { gssize val = *(gssize*)addr; @@ -6343,6 +6335,17 @@ mono_do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, gu } } } else { + if (!strcmp (m->name, "ToString")) //can be calling in a nullable with null value, not sure how to deal with it correctly + { + MonoObject *str = (MonoObject*)mono_string_new_checked (" ", error); + buffer_add_byte (buf, 1); + buffer_add_byte (buf, MONO_TYPE_STRING); + buffer_add_objid (buf, str); + if (CHECK_ICORDBG (TRUE)) + buffer_add_long (buf, (gssize) str); + *endp = p; + return ERR_NONE; + } return ERR_INVALID_ARGUMENT; } } @@ -6906,6 +6909,44 @@ static void add_error_string (Buffer *buf, const char *str) buffer_add_string (buf, str); } +static void +create_file_to_check_memory_address (void) +{ + if (file_check_valid_memory != -1) + return; + char *file_name = g_strdup_printf ("debugger_check_valid_memory.%d", mono_process_current_pid ()); + filename_check_valid_memory = g_build_filename (g_get_tmp_dir (), file_name, (const char*)NULL); + file_check_valid_memory = open(filename_check_valid_memory, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR); + g_free (file_name); +} + +static gboolean +valid_memory_address (gpointer addr, gint size) +{ +#ifndef _MSC_VER + gboolean ret = TRUE; + create_file_to_check_memory_address (); + if(file_check_valid_memory < 0) { + return TRUE; + } + write (file_check_valid_memory, (gpointer)addr, 1); + if (errno == EFAULT) { + ret = FALSE; + } +#else + int i = 0; + gboolean ret = FALSE; + __try { + for (i = 0; i < size; i++) + *((volatile char*)addr+i); + ret = TRUE; + } __except(1) { + return ret; + } +#endif + return ret; +} + static ErrorCode vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) { @@ -7251,10 +7292,17 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) case MDBGPROT_CMD_VM_READ_MEMORY: { guint8* memory = (guint8*)GINT_TO_POINTER (decode_long (p, &p, end)); int size = decode_int (p, &p, end); - PRINT_DEBUG_MSG(1, "MDBGPROT_CMD_VM_READ_MEMORY - [%p] - size - %d\n", memory, size); + if (!valid_memory_address(memory, size)) + return ERR_INVALID_ARGUMENT; + PRINT_DEBUG_MSG (1, "MDBGPROT_CMD_VM_READ_MEMORY - [%p] - size - %d\n", memory, size); buffer_add_byte_array (buf, memory, size); break; } + case MDBGPROT_CMD_VM_GET_OBJECT_ID_BY_ADDRESS: { + MonoObject* obj = (MonoObject*)GINT_TO_POINTER (decode_long (p, &p, end)); + buffer_add_objid (buf, obj); + break; + } case MDBGPROT_CMD_GET_ASSEMBLY_BY_NAME: { char* assembly_name = decode_string (p, &p, end); //we get 'foo.dll' but mono_assembly_load expects 'foo' so we strip the last dot @@ -7326,6 +7374,52 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) buffer_add_string (buf, mono_enc_capabilities ()); break; } + case MDBGPROT_CMD_GET_INTERNAL_TYPE_CLASS: { + int internal_type = decode_int (p, &p, end); + switch (internal_type) { + case MONO_TYPE_BOOLEAN: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_boolean_class ()); + break; + case MONO_TYPE_I1: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_sbyte_class ()); + break; + case MONO_TYPE_U1: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_byte_class ()); + break; + case MONO_TYPE_CHAR: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_char_class ()); + break; + case MONO_TYPE_I2: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_int16_class ()); + break; + case MONO_TYPE_U2: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_uint16_class ()); + break; + case MONO_TYPE_I4: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_int32_class ()); + break; + case MONO_TYPE_U4: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_uint32_class ()); + break; + case MONO_TYPE_R4: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_single_class ()); + break; + case MONO_TYPE_I8: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_int64_class ()); + break; + case MONO_TYPE_U8: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_uint64_class ()); + break; + case MONO_TYPE_R8: + buffer_add_typeid (buf, mono_get_root_domain (), mono_get_double_class ()); + break; + default: { + buffer_add_int (buf, -1); + break; + } + } + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -7665,11 +7759,6 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf) return ERR_INVALID_OBJECT; } - if (CHECK_PROTOCOL_VERSION(3, 0)) { - buffer_add_byte(buf, 1); - buffer_add_byte(buf, MONO_TYPE_STRING); - } - buffer_add_objid (buf, (MonoObject*)o); break; } @@ -8193,6 +8282,9 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint guint8 b; int nnested; ErrorCode err; + int i = 0; + int len = 0; + MonoClassField *f = NULL; switch (command) { case CMD_TYPE_GET_INFO: { @@ -8258,16 +8350,16 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint guint count = inst->type_argc; buffer_add_int (buf, count); - for (guint i = 0; i < count; i++) - buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (inst->type_argv [i])); + for (guint k = 0; k < count; k++) + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (inst->type_argv [k])); } else if (mono_class_is_gtd (klass)) { MonoGenericContainer *container = mono_class_get_generic_container (klass); MonoClass *pklass; int count = container->type_argc; buffer_add_int (buf, count); - for (int i = 0; i < count; i++) { - pklass = mono_class_create_generic_parameter (mono_generic_container_get_param (container, i)); + for (int k = 0; k < count; k++) { + pklass = mono_class_create_generic_parameter (mono_generic_container_get_param (container, k)); buffer_add_typeid (buf, domain, pklass); } } else { @@ -8278,7 +8370,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint } case CMD_TYPE_GET_METHODS: { int nmethods; - int i = 0; + i = 0; gpointer iter = NULL; MonoMethod *m; @@ -8299,9 +8391,8 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint } case CMD_TYPE_GET_FIELDS: { int nfields; - int i = 0; + i = 0; gpointer iter = NULL; - MonoClassField *f; nfields = mono_class_num_fields (klass); @@ -8321,7 +8412,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint } case CMD_TYPE_GET_PROPERTIES: { int nprops; - int i = 0; + i = 0; gpointer iter = NULL; MonoProperty *prop; @@ -8406,13 +8497,28 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint goto exit; break; } - case MDBGPROT_CMD_TYPE_GET_VALUES_ICORDBG: { - MonoClass *dummy_class; + case MDBGPROT_CMD_TYPE_GET_VALUES_BY_FIELD_TOKEN: { + MonoThread *thread_obj; + MonoInternalThread *thread = NULL; int field_token = decode_int (p, &p, end); - MonoClassField *f = mono_field_from_token_checked (m_class_get_image (klass), field_token, &dummy_class, NULL, error); + int objid = decode_objid (p, &p, end); + if (objid != -1) + { + err = get_object (objid, (MonoObject**)&thread_obj); + if (err != ERR_NONE) + thread = THREAD_TO_INTERNAL (thread_obj); + } + + f = NULL; + gpointer iter = NULL; + + while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (mono_class_get_field_token (f) == field_token) + break; + } PRINT_DEBUG_MSG (1, "Getting value of field %s\n", f->name); if (f) { - if (get_static_field_value(f, klass, domain, NULL, buf) == -1) + if (get_static_field_value(f, klass, domain, thread, buf) == -1) goto invalid_fieldid; } else @@ -8421,8 +8527,6 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint } case CMD_TYPE_GET_VALUES: case CMD_TYPE_GET_VALUES_2: { - MonoClassField *f; - int len; MonoThread *thread_obj; MonoInternalThread *thread = NULL; @@ -8437,7 +8541,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint } len = decode_int (p, &p, end); - for (int i = 0; i < len; ++i) { + for (i = 0; i < len; ++i) { f = decode_fieldid (p, &p, end, NULL, &err); if (err != ERR_NONE) goto exit; @@ -8446,16 +8550,33 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint } break; } + case MDBGPROT_CMD_TYPE_SET_VALUES_BY_FIELD_TOKEN: { + len = 0; + gpointer iter = NULL; + len = decode_int (p, &p, end); + int field_token = decode_int (p, &p, end); + while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (mono_class_get_field_token (f) == field_token) + break; + } + if (f) { + if (get_static_field_value(f, klass, domain, NULL, buf) == -1) + goto invalid_fieldid; + } + else + goto invalid_fieldid; + goto set_value; + break; + } case CMD_TYPE_SET_VALUES: { guint8 *val; - MonoClassField *f; MonoVTable *vtable; MonoClass *k; - int len; + len = 0; gboolean found; len = decode_int (p, &p, end); - for (int i = 0; i < len; ++i) { + for (i = 0; i < len; ++i) { f = decode_fieldid (p, &p, end, NULL, &err); if (err != ERR_NONE) goto exit; @@ -8478,7 +8599,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint goto invalid_fieldid; // FIXME: Check for literal/const - +set_value: vtable = mono_class_vtable_checked (m_field_get_parent (f), error); if (!is_ok (error)) { mono_error_cleanup (error); @@ -8506,6 +8627,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint goto invalid_object; } buffer_add_objid (buf, o); + if (CHECK_ICORDBG (TRUE)) + { + MonoType *object_type = m_class_get_byval_arg (m_class_get_element_class (klass)); + buffer_add_value (buf, object_type, o, domain); + } break; } case CMD_TYPE_GET_SOURCE_FILES: @@ -8516,8 +8642,8 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint files = get_source_files_for_type (klass); buffer_add_int (buf, files->len); - for (guint i = 0; i < files->len; ++i) { - source_file = (char *)g_ptr_array_index (files, i); + for (guint k = 0; k < files->len; ++k) { + source_file = (char *)g_ptr_array_index (files, k); if (command == CMD_TYPE_GET_SOURCE_FILES_2) { buffer_add_string (buf, source_file); } else { @@ -8560,8 +8686,8 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint goto loader_error; } buffer_add_int (buf, array->len); - for (guint i = 0; i < array->len; ++i) { - MonoMethod *method = (MonoMethod *)g_ptr_array_index (array, i); + for (guint k = 0; k < array->len; ++k) { + MonoMethod *method = (MonoMethod *)g_ptr_array_index (array, k); buffer_add_methodid (buf, domain, method); } @@ -8603,7 +8729,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint int tindex, ioffset; gboolean variance_used; MonoClass *iclass; - int len, nmethods; + int nmethods; gpointer iter; MonoMethod *method; @@ -8627,7 +8753,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint buffer_add_methodid (buf, domain, method); } MonoMethod **klass_vtable = m_class_get_vtable (klass); - for (int i = 0; i < nmethods; ++i) + for (i = 0; i < nmethods; ++i) buffer_add_methodid (buf, domain, klass_vtable [i + ioffset]); } break; @@ -8690,6 +8816,44 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint } break; } + case MDBGPROT_CMD_TYPE_BIND_GENERIC_PARAMETERS: { + MonoType **type_argv; + int type_argc; + MonoDomain *d; + if (!mono_class_is_gtd (klass)) + { + buffer_add_typeid (buf, domain, klass); + break; + } + type_argc = decode_int (p, &p, end); + type_argv = g_new0 (MonoType*, type_argc); + for (i = 0; i < type_argc; ++i) { + MonoClass *klass_to_bind = decode_typeid (p, &p, end, &d, &err); + if (err != ERR_NONE) { + g_free (type_argv); + return err; + } + if (domain != d) { + g_free (type_argv); + return ERR_INVALID_ARGUMENT; + } + type_argv [i] = m_class_get_byval_arg (klass_to_bind); + } + MonoClass *bound_class = mono_class_bind_generic_parameters (klass, type_argc, type_argv, FALSE/*check if is dynamic*/); + buffer_add_typeid (buf, domain, bound_class); + g_free (type_argv); + break; + } + case MDBGPROT_CMD_TYPE_ELEMENT_TYPE: + { + buffer_add_int (buf, m_class_get_byval_arg (klass)->type); + break; + } + case MDBGPROT_CMD_TYPE_RANK: + { + buffer_add_byte (buf, m_class_get_rank (klass)); + break; + } default: err = ERR_NOT_IMPLEMENTED; goto exit; @@ -9266,6 +9430,39 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g } break; } + case MDBGPROT_CMD_METHOD_BIND_GENERIC_TYPE_PARAMETERS: { + MonoType **type_argv; + int i, type_argc; + MonoDomain *d; + MonoMethod *m; + type_argc = decode_int (p, &p, end); + type_argv = g_new0 (MonoType*, type_argc); + for (i = 0; i < type_argc; ++i) { + MonoClass *klass = decode_typeid (p, &p, end, &d, &err); + if (err != ERR_NONE) { + g_free (type_argv); + return err; + } + if (domain != d) { + g_free (type_argv); + return ERR_INVALID_ARGUMENT; + } + type_argv [i] = m_class_get_byval_arg (klass); + } + MonoClass *bound_class = mono_class_bind_generic_parameters (method->klass, type_argc, type_argv, FALSE/*check if is dynamic*/); + g_free (type_argv); + gpointer iter = NULL; + mono_class_setup_methods (bound_class); + while ((m = mono_class_get_methods (bound_class, &iter))) { + if (method->token == m->token) + { + buffer_add_methodid (buf, domain, m); + break; + } + } + buffer_add_int (buf, -1); + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -9330,7 +9527,10 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (suspend_count) wait_for_suspend(); } - int64_t sp_received = m_dbgprot_decode_long(p, &p, end); + gpointer sp_received; + int len; + uint8_t* sp_received_byte_array = m_dbgprot_decode_byte_array (p, &p, end, &len); + memcpy(&sp_received, sp_received_byte_array, sizeof(gpointer)); mono_loader_lock(); tls = (DebuggerTlsData*)mono_g_hash_table_lookup(thread_to_tls, thread); @@ -9342,12 +9542,12 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf) for (int i = 0; i < tls->frame_count; i++) { - PRINT_DEBUG_MSG(1, "[dbg] Searching Context [%d] - [%" PRIu64 "] - [%" PRId64 "]\n", i, (uint64_t) MONO_CONTEXT_GET_SP (&tls->frames [i]->ctx), sp_received); - if (sp_received == (uint64_t)MONO_CONTEXT_GET_SP (&tls->frames [i]->ctx)) { + if (sp_received == tls->frames [i]->frame_addr) { buffer_add_int(buf, i); break; } } + g_free (sp_received_byte_array); break; } case MDBGPROT_CMD_THREAD_GET_CONTEXT: { @@ -9366,7 +9566,7 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (start_frame < tls->frame_count) { - buffer_add_long(buf, (uint64_t)MONO_CONTEXT_GET_SP (&tls->frames [start_frame]->ctx)); + m_dbgprot_buffer_add_byte_array (buf, (uint8_t *) &tls->frames [start_frame]->frame_addr, sizeof(gpointer)); } break; } @@ -9682,6 +9882,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) return cmd_stack_frame_get_this (frame, sig, buf, jit); break; } + case MDBGPROT_CMD_STACK_FRAME_SET_VALUES_2: case CMD_STACK_FRAME_SET_VALUES: { guint8 *val_buf; MonoType *t; @@ -9694,8 +9895,9 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) for (i = 0; i < len; ++i) { pos = decode_int (p, &p, end); - if (pos < 0) { + if (command == MDBGPROT_CMD_STACK_FRAME_SET_VALUES_2 && sig->hasthis) //0 == this + pos++; pos = - pos - 1; g_assert (pos >= 0 && GINT_TO_UINT32(pos) < jit->num_params); @@ -9781,6 +9983,23 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) } break; } + case MDBGPROT_CMD_STACK_FRAME_GET_ADDRESS: { + buffer_add_long (buf, (gssize)frame->frame_addr); + break; + } + case MDBGPROT_CMD_STACK_FRAME_GET_COUNT: { + MonoDebugLocalsInfo *locals; + locals = mono_debug_lookup_locals (frame->de.method); + if (locals) + buffer_add_int (buf, locals->num_locals); + else + buffer_add_int (buf, 0); + break; + } + case MDBGPROT_CMD_STACK_FRAME_GET_PARAMETERS_COUNT: { + buffer_add_int (buf, jit->num_params + (sig->hasthis ? 1 : 0)); + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -9923,44 +10142,6 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf) return ERR_NONE; } -static void -create_file_to_check_memory_address (void) -{ - if (file_check_valid_memory != -1) - return; - char *file_name = g_strdup_printf ("debugger_check_valid_memory.%d", mono_process_current_pid ()); - filename_check_valid_memory = g_build_filename (g_get_tmp_dir (), file_name, (const char*)NULL); - file_check_valid_memory = open(filename_check_valid_memory, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR); - g_free (file_name); -} - -static gboolean -valid_memory_address (gpointer addr, gint size) -{ -#ifndef _MSC_VER - gboolean ret = TRUE; - create_file_to_check_memory_address (); - if(file_check_valid_memory < 0) { - return TRUE; - } - write (file_check_valid_memory, (gpointer)addr, 1); - if (errno == EFAULT) { - ret = FALSE; - } -#else - int i = 0; - gboolean ret = FALSE; - __try { - for (i = 0; i < size; i++) - *((volatile char*)addr+i); - ret = TRUE; - } __except(1) { - return ret; - } -#endif - return ret; -} - static ErrorCode pointer_commands (int command, guint8 *p, guint8 *end, Buffer *buf) { @@ -10038,14 +10219,16 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf) case CMD_OBJECT_REF_GET_TYPE: buffer_add_typeid (buf, obj->vtable->domain, mono_class_from_mono_type_internal (((MonoReflectionType*)obj->vtable->type)->type)); break; - case CMD_OBJECT_REF_GET_VALUES_ICORDBG: { + case CMD_OBJECT_REF_GET_VALUES_BY_FIELD_TOKEN: { len = 1; - MonoClass *dummy_class; - int field_token = decode_int (p, &p, end); i = 0; - f = mono_field_from_token_checked (m_class_get_image (obj_type), field_token, &dummy_class, NULL, error); - if (f) { - goto get_field_value; + MonoClass* klass = decode_typeid (p, &p, end, NULL, &err); + int field_token = decode_int (p, &p, end); + gpointer iter = NULL; + + while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (mono_class_get_field_token (f) == field_token) + goto get_field_value; } goto invalid_fieldid; } @@ -10105,6 +10288,18 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf) } } break; + case MDBGPROT_CMD_OBJECT_REF_SET_VALUES_BY_FIELD_TOKEN: + len = decode_int (p, &p, end); + i = 0; + int field_token = decode_int (p, &p, end); + for (k = obj_type; k; k = m_class_get_parent (k)) { + gpointer iter = NULL; + while ((f = mono_class_get_fields_internal (k, &iter))) { + if (mono_class_get_field_token (f) == field_token) + goto set_field_value; + } + } + goto invalid_fieldid; case CMD_OBJECT_REF_SET_VALUES: len = decode_int (p, &p, end); @@ -10123,7 +10318,7 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf) } if (!found) goto invalid_fieldid; - +set_field_value: if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) { guint8 *val; MonoVTable *vtable; diff --git a/src/mono/mono/component/debugger-engine.c b/src/mono/mono/component/debugger-engine.c index 2a05aba440a075..02f7eb090f6aec 100644 --- a/src/mono/mono/component/debugger-engine.c +++ b/src/mono/mono/component/debugger-engine.c @@ -922,8 +922,8 @@ mono_de_ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, void *tls, PRINT_DEBUG_MSG (1, "[%p] Breakpoint hit during async step-out at %s hit, continuing stepping out.\n", (gpointer)(gsize)mono_native_thread_id_get (), method->name); return FALSE; } - - if (req->depth == STEP_DEPTH_OVER && (sp->flags & MONO_SEQ_POINT_FLAG_NONEMPTY_STACK) && !(sp->flags & MONO_SEQ_POINT_FLAG_NESTED_CALL)) { + //if we are paused in the end of a method "}" the next step should be in the line which is calling this method + if (req->depth == STEP_DEPTH_OVER && (sp->flags & MONO_SEQ_POINT_FLAG_NONEMPTY_STACK) && !(sp->flags & MONO_SEQ_POINT_FLAG_NESTED_CALL) && req->start_method == method) { /* * These seq points are inserted by the JIT after calls, step over needs to skip them. */ @@ -966,7 +966,7 @@ mono_de_ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, void *tls, mono_debug_free_method_async_debug_info (async_method); } - if (req->size != STEP_SIZE_LINE) + if (req->size != STEP_SIZE_LINE_COLUMN) return TRUE; /* Have to check whenever a different source line was reached */ @@ -979,8 +979,9 @@ mono_de_ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, void *tls, PRINT_DEBUG_MSG (1, "[%p] No line number info for il offset %x, don't know if it's in the same line single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), sp->il_offset); req->last_method = method; req->last_line = -1; + req->last_column = -1; return hit; - } else if (loc && method == req->last_method && loc->row == req->last_line) { + } else if (loc && method == req->last_method && loc->row == req->last_line && loc->column == req->last_column) { int nframes; rt_callbacks.ss_calculate_framecount (tls, ctx, FALSE, NULL, &nframes); if (nframes == req->nframes) { // If the frame has changed we're clearly not on the same source line. @@ -992,6 +993,7 @@ mono_de_ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, void *tls, if (loc) { req->last_method = method; req->last_line = loc->row; + req->last_column = loc->column; mono_debug_free_source_location (loc); } diff --git a/src/mono/mono/component/debugger-engine.h b/src/mono/mono/component/debugger-engine.h index 8b06239983758a..b0f6c5ca729b38 100644 --- a/src/mono/mono/component/debugger-engine.h +++ b/src/mono/mono/component/debugger-engine.h @@ -149,7 +149,7 @@ #define CMD_OBJECT_REF_IS_COLLECTED MDBGPROT_CMD_OBJECT_REF_IS_COLLECTED #define CMD_OBJECT_REF_GET_TYPE MDBGPROT_CMD_OBJECT_REF_GET_TYPE -#define CMD_OBJECT_REF_GET_VALUES_ICORDBG MDBGPROT_CMD_OBJECT_REF_GET_VALUES_ICORDBG +#define CMD_OBJECT_REF_GET_VALUES_BY_FIELD_TOKEN MDBGPROT_CMD_OBJECT_REF_GET_VALUES_BY_FIELD_TOKEN #define CMD_OBJECT_REF_GET_VALUES MDBGPROT_CMD_OBJECT_REF_GET_VALUES #define CMD_OBJECT_REF_SET_VALUES MDBGPROT_CMD_OBJECT_REF_SET_VALUES #define CMD_OBJECT_REF_GET_ADDRESS MDBGPROT_CMD_OBJECT_REF_GET_ADDRESS @@ -168,7 +168,7 @@ #define STEP_DEPTH_OUT MDBGPROT_STEP_DEPTH_OUT #define STEP_DEPTH_INTO MDBGPROT_STEP_DEPTH_INTO #define STEP_SIZE_MIN MDBGPROT_STEP_SIZE_MIN -#define STEP_SIZE_LINE MDBGPROT_STEP_SIZE_LINE +#define STEP_SIZE_LINE_COLUMN MDBGPROT_STEP_SIZE_LINE_COLUMN #define SUSPEND_POLICY_NONE MDBGPROT_SUSPEND_POLICY_NONE #define SUSPEND_POLICY_ALL MDBGPROT_SUSPEND_POLICY_ALL diff --git a/src/mono/mono/component/debugger-protocol.h b/src/mono/mono/component/debugger-protocol.h index 475bc807a6149b..cbcecb43304ace 100644 --- a/src/mono/mono/component/debugger-protocol.h +++ b/src/mono/mono/component/debugger-protocol.h @@ -38,7 +38,9 @@ typedef enum { MDBGPROT_CMD_GET_ASSEMBLY_BY_NAME = 18, MDBGPROT_CMD_GET_MODULE_BY_GUID = 19, MDBGPROT_CMD_GET_ASSEMBLY_BYTES = 20, //wasm specific - MDBGPROT_CMD_GET_ENC_CAPABILITIES = 21 + MDBGPROT_CMD_GET_ENC_CAPABILITIES = 21, + MDBGPROT_CMD_VM_GET_OBJECT_ID_BY_ADDRESS = 22, + MDBGPROT_CMD_GET_INTERNAL_TYPE_CLASS = 23 } MdbgProtCmdVM; typedef enum { @@ -182,7 +184,8 @@ typedef enum { MDBGPROT_CMD_METHOD_GET_CLASS_TOKEN = 13, MDBGPROT_CMD_METHOD_HAS_ASYNC_DEBUG_INFO = 14, MDBGPROT_CMD_METHOD_GET_NAME_FULL = 15, - MDBGPROT_CMD_METHOD_GET_PRETTY_NAME = 16 + MDBGPROT_CMD_METHOD_GET_PRETTY_NAME = 16, + MDBGPROT_CMD_METHOD_BIND_GENERIC_TYPE_PARAMETERS = 17 } MdbgProtCmdMethod; typedef enum { @@ -206,9 +209,13 @@ typedef enum { MDBGPROT_CMD_TYPE_IS_INITIALIZED = 18, MDBGPROT_CMD_TYPE_CREATE_INSTANCE = 19, MDBGPROT_CMD_TYPE_GET_VALUE_SIZE = 20, - MDBGPROT_CMD_TYPE_GET_VALUES_ICORDBG = 21, + MDBGPROT_CMD_TYPE_GET_VALUES_BY_FIELD_TOKEN = 21, MDBGPROT_CMD_TYPE_GET_PARENTS = 22, - MDBGPROT_CMD_TYPE_INITIALIZE = 23 + MDBGPROT_CMD_TYPE_INITIALIZE = 23, + MDBGPROT_CMD_TYPE_BIND_GENERIC_PARAMETERS = 24, + MDBGPROT_CMD_TYPE_ELEMENT_TYPE = 25, + MDBGPROT_CMD_TYPE_RANK = 26, + MDBGPROT_CMD_TYPE_SET_VALUES_BY_FIELD_TOKEN = 27 } MdbgProtCmdType; typedef enum { @@ -218,7 +225,11 @@ typedef enum { MDBGPROT_CMD_STACK_FRAME_GET_DOMAIN = 4, MDBGPROT_CMD_STACK_FRAME_SET_THIS = 5, MDBGPROT_CMD_STACK_FRAME_GET_ARGUMENT = 6, - MDBGPROT_CMD_STACK_FRAME_GET_ARGUMENTS = 7 + MDBGPROT_CMD_STACK_FRAME_GET_ARGUMENTS = 7, + MDBGPROT_CMD_STACK_FRAME_GET_ADDRESS = 8, + MDBGPROT_CMD_STACK_FRAME_SET_VALUES_2 = 9, + MDBGPROT_CMD_STACK_FRAME_GET_COUNT = 10, + MDBGPROT_CMD_STACK_FRAME_GET_PARAMETERS_COUNT = 11 } MdbgProtCmdStackFrame; typedef enum { @@ -246,9 +257,10 @@ typedef enum { MDBGPROT_CMD_OBJECT_REF_GET_DOMAIN = 5, MDBGPROT_CMD_OBJECT_REF_SET_VALUES = 6, MDBGPROT_CMD_OBJECT_REF_GET_INFO = 7, - MDBGPROT_CMD_OBJECT_REF_GET_VALUES_ICORDBG = 8, + MDBGPROT_CMD_OBJECT_REF_GET_VALUES_BY_FIELD_TOKEN = 8, MDBGPROT_CMD_OBJECT_REF_DELEGATE_GET_METHOD = 9, - MDBGPROT_CMD_OBJECT_IS_DELEGATE = 10 + MDBGPROT_CMD_OBJECT_IS_DELEGATE = 10, + MDBGPROT_CMD_OBJECT_REF_SET_VALUES_BY_FIELD_TOKEN = 11 } MdbgProtCmdObject; typedef enum { @@ -326,7 +338,7 @@ typedef enum { typedef enum { MDBGPROT_STEP_SIZE_MIN = 0, - MDBGPROT_STEP_SIZE_LINE = 1 + MDBGPROT_STEP_SIZE_LINE_COLUMN = 1 } MdbgProtStepSize; typedef enum { diff --git a/src/mono/mono/component/debugger.h b/src/mono/mono/component/debugger.h index fe149608827216..7dca4d2d30317d 100644 --- a/src/mono/mono/component/debugger.h +++ b/src/mono/mono/component/debugger.h @@ -95,6 +95,7 @@ typedef struct { MonoMethod *start_method; MonoMethod *last_method; int last_line; + int last_column; /* Whenever single stepping is performed using start/stop_single_stepping () */ gboolean global; /* The list of breakpoints used to implement step-over */ diff --git a/src/mono/mono/component/hot_reload-internals.h b/src/mono/mono/component/hot_reload-internals.h index 65cdcde8f56bfb..d893a497f57000 100644 --- a/src/mono/mono/component/hot_reload-internals.h +++ b/src/mono/mono/component/hot_reload-internals.h @@ -32,6 +32,8 @@ struct _MonoClassMetadataUpdateInfo { GSList *added_events; /* a set of MonoClassMetadataUpdateEvent* values */ MonoClassRuntimeMetadataUpdateInfo runtime; + + uint32_t generation; /* must be updated when a GTD gets added props, events or fields; must be updated when a GINST copies updated info from the parent */ }; /* diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index 120d227d7ccace..ac8236f78775ad 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -2305,10 +2305,7 @@ apply_enclog_pass2 (Pass2Context *ctx, MonoImage *image_base, BaselineInfo *base } case MONO_TABLE_PROPERTY: { /* allow updates to existing properties. */ - if (!is_addition) - /* FIXME: use DeltaInfo:prev_gen_rows instead of image_base */ - g_assert (token_index <= table_info_get_rows (&image_base->tables [token_table])); - else { + if (is_addition) { g_assert (add_property_propertymap != 0); uint32_t parent_type_token = mono_metadata_decode_row_col (&image_base->tables [MONO_TABLE_PROPERTYMAP], mono_metadata_token_index (add_property_propertymap) - 1, MONO_PROPERTY_MAP_PARENT); @@ -2362,10 +2359,7 @@ apply_enclog_pass2 (Pass2Context *ctx, MonoImage *image_base, BaselineInfo *base } case MONO_TABLE_EVENT: { - if (!is_addition) - /* FIXME: use DeltaInfo:prev_gen_rows instead of image_base */ - g_assert (token_index <= table_info_get_rows (&image_base->tables [token_table])); - else { + if (is_addition) { g_assert (add_event_eventmap != 0); uint32_t parent_type_token = mono_metadata_decode_row_col (&image_base->tables [MONO_TABLE_EVENTMAP], mono_metadata_token_index (add_event_eventmap) - 1, MONO_EVENT_MAP_PARENT); @@ -2869,6 +2863,7 @@ add_member_to_baseline (BaselineInfo *base_info, DeltaInfo *delta_info, MonoClas GSList *members = klass_info->added_members; klass_info->added_members = g_slist_prepend_mem_manager (m_class_get_mem_manager (klass), members, GUINT_TO_POINTER (member_token)); add_member_parent (base_info, m_class_get_type_token (klass), member_token); + klass_info->generation = delta_info->generation; } @@ -3025,6 +3020,7 @@ hot_reload_get_field (MonoClass *klass, uint32_t fielddef_token) { static MonoProperty * hot_reload_get_property (MonoClass *klass, uint32_t property_token) { + g_assert (m_class_get_class_kind (klass) != MONO_CLASS_GINST); MonoClassMetadataUpdateInfo *info = mono_class_get_or_add_metadata_update_info (klass); g_assert (mono_metadata_token_table (property_token) == MONO_TABLE_PROPERTY); GSList *added_props = info->added_props; @@ -3040,6 +3036,7 @@ hot_reload_get_property (MonoClass *klass, uint32_t property_token) static MonoEvent * hot_reload_get_event (MonoClass *klass, uint32_t event_token) { + g_assert (m_class_get_class_kind (klass) != MONO_CLASS_GINST); MonoClassMetadataUpdateInfo *info = mono_class_get_or_add_metadata_update_info (klass); g_assert (mono_metadata_token_table (event_token) == MONO_TABLE_EVENT); GSList *added_events = info->added_events; @@ -3108,6 +3105,8 @@ add_property_to_existing_class (MonoImage *image_base, BaselineInfo *base_info, parent_info->added_props = g_slist_prepend_mem_manager (m_class_get_mem_manager (parent_klass), parent_info->added_props, prop); + parent_info->generation = generation; + return prop; } @@ -3134,6 +3133,8 @@ add_event_to_existing_class (MonoImage *image_base, BaselineInfo *base_info, uin parent_info->added_events = g_slist_prepend_mem_manager (m_class_get_mem_manager (parent_klass), parent_info->added_events, evt); + parent_info->generation = generation; + return evt; } @@ -3167,7 +3168,6 @@ add_semantic_method_to_existing_property (MonoImage *image_base, BaselineInfo *b g_assert (dest != NULL); - g_assert (*dest == NULL); MonoMethod *method = mono_get_method_checked (image_base, method_token, klass, NULL, error); mono_error_assert_ok (error); @@ -3207,7 +3207,6 @@ add_semantic_method_to_existing_event (MonoImage *image_base, BaselineInfo *base } g_assert (dest != NULL); - g_assert (*dest == NULL); MonoMethod *method = mono_get_method_checked (image_base, method_token, klass, NULL, error); mono_error_assert_ok (error); @@ -3318,6 +3317,8 @@ hot_reload_get_static_field_addr (MonoClassField *field) static MonoMethod * hot_reload_find_method_by_name (MonoClass *klass, const char *name, int param_count, int flags, MonoError *error) { + g_assert (!mono_class_is_ginst (klass)); + GSList *members = hot_reload_get_added_members (klass); if (!members) return NULL; @@ -3366,13 +3367,19 @@ hot_reload_added_methods_iter (MonoClass *klass, gpointer *iter) uint32_t idx = GPOINTER_TO_UINT (*iter); g_assert (idx >= mono_class_get_method_count (klass)); - GSList *members = hot_reload_get_added_members (klass); + GSList *members = NULL; + int class_kind = m_class_get_class_kind (klass); + if (class_kind == MONO_CLASS_GINST) { + MonoClass *gklass = mono_class_get_generic_class (klass)->container_class; + members = hot_reload_get_added_members (gklass); + } else { + members = hot_reload_get_added_members (klass); + } + if (!members) return NULL; - // expect to only see class defs here. Rationale: adding methods to generic classes is not - // allowed (if a generation adds a new generic class, it won't be here - those methods will - // be in the normal iteration code, not here. - g_assert (m_class_get_class_kind (klass) == MONO_CLASS_DEF); + // We don't expect to see arrays or pointers here since they don't own MONO_TABLE_METHOD entries. + g_assert (class_kind == MONO_CLASS_DEF || class_kind == MONO_CLASS_GTD || class_kind == MONO_CLASS_GINST); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "Iterating added methods of 0x%08x idx = %u", m_class_get_type_token (klass), idx); @@ -3386,9 +3393,18 @@ hot_reload_added_methods_iter (MonoClass *klass, gpointer *iter) if (cur_count == idx) { // found a method, advance iter and return the method. *iter = GUINT_TO_POINTER (1+idx); - ERROR_DECL (local_error); - MonoMethod *method = mono_get_method_checked (m_class_get_image (klass), token, klass, NULL, local_error); - mono_error_cleanup (local_error); + MonoMethod *method = NULL; + if (class_kind == MONO_CLASS_GINST) { + MonoClass *gklass = mono_class_get_generic_class (klass)->container_class; + ERROR_DECL (local_error); + MonoMethod *gmethod = mono_get_method_checked (m_class_get_image (gklass), token, klass, NULL, local_error); + method = mono_class_inflate_generic_method_full_checked (gmethod, klass, mono_class_get_context (klass), local_error); + mono_error_cleanup (local_error); + } else { + ERROR_DECL (local_error); + method = mono_get_method_checked (m_class_get_image (klass), token, klass, NULL, local_error); + mono_error_cleanup (local_error); + } return method; } cur_count++; @@ -3477,7 +3493,7 @@ hot_reload_get_method_params (MonoImage *base_image, uint32_t methoddef_token, u static const char * hot_reload_get_capabilities (void) { - return "Baseline AddMethodToExistingType AddStaticFieldToExistingType NewTypeDefinition ChangeCustomAttributes AddInstanceFieldToExistingType"; + return "Baseline AddMethodToExistingType AddStaticFieldToExistingType NewTypeDefinition ChangeCustomAttributes AddInstanceFieldToExistingType GenericAddMethodToExistingType GenericUpdateMethod"; } static GENERATE_GET_CLASS_WITH_CACHE_DECL (hot_reload_instance_field_table); @@ -3515,10 +3531,120 @@ hot_reload_added_field_ldflda (MonoObject *instance, MonoType *field_type, uint3 return result; } +static void recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataUpdateInfo *gtd_info); + +static MonoClassMetadataUpdateInfo * +hot_reload_get_or_add_ginst_update_info(MonoClass *ginst) +{ + g_assert (m_class_get_class_kind (ginst) == MONO_CLASS_GINST); + MonoClassMetadataUpdateInfo *info = mono_class_get_metadata_update_info (ginst); + + gboolean needToRefresh = FALSE; + + if (!info) + needToRefresh = TRUE; + + MonoClass *gtd = mono_class_get_generic_type_definition (ginst); + MonoClassMetadataUpdateInfo *gtd_info = mono_class_get_metadata_update_info (gtd); + + if (!gtd_info) + return NULL; + + if (info && info->generation < gtd_info->generation) + needToRefresh = TRUE; + + if (!needToRefresh) + return info; + + mono_loader_lock (); + info = mono_class_get_metadata_update_info (ginst); + if (info && info->generation == gtd_info->generation) { + mono_loader_unlock (); + return info; + } + + recompute_ginst_update_info (ginst, gtd, gtd_info); + + info = mono_class_get_metadata_update_info (ginst); + mono_loader_unlock (); + return info; +} + +#define mono_class_new0(klass,struct_type, n_structs) \ + ((struct_type *) mono_class_alloc0 ((klass), ((gsize) sizeof (struct_type)) * ((gsize) (n_structs)))) + +static void +recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataUpdateInfo *gtd_info) +{ + // if ginst has a `MonoClassMetadataUpdateInfo`, use it to start with, otherwise, allocate a new one + MonoClassMetadataUpdateInfo *info = mono_class_get_or_add_metadata_update_info (ginst); + + if (!info) + info = mono_class_new0 (ginst, MonoClassMetadataUpdateInfo, 1); + + // replace info->added_props by a new list re-computed from gtd_info->added_props + info->added_props = NULL; + for (GSList *ptr = gtd_info->added_props; ptr; ptr = ptr->next) { + MonoClassMetadataUpdateProperty *gtd_added_prop = (MonoClassMetadataUpdateProperty *)ptr->data; + MonoClassMetadataUpdateProperty *added_prop = mono_class_new0 (ginst, MonoClassMetadataUpdateProperty, 1); + + added_prop->prop = gtd_added_prop->prop; + added_prop->token = gtd_added_prop->token; + + ERROR_DECL (error); + if (added_prop->prop.get) + added_prop->prop.get = mono_class_inflate_generic_method_full_checked ( + added_prop->prop.get, ginst, mono_class_get_context (ginst), error); + if (added_prop->prop.set) + added_prop->prop.set = mono_class_inflate_generic_method_full_checked ( + added_prop->prop.set, ginst, mono_class_get_context (ginst), error); + g_assert (is_ok (error)); /*FIXME proper error handling*/ + + added_prop->prop.parent = ginst; + + info->added_props = g_slist_prepend_mem_manager (m_class_get_mem_manager (ginst), info->added_props, (gpointer)added_prop); + } + + // replace info->added_events by a new list re-computed from gtd_info->added_events + info->added_events = NULL; + for (GSList *ptr = gtd_info->added_events; ptr; ptr = ptr->next) { + MonoClassMetadataUpdateEvent *gtd_added_event = (MonoClassMetadataUpdateEvent *)ptr->data; + MonoClassMetadataUpdateEvent *added_event = mono_class_new0 (ginst, MonoClassMetadataUpdateEvent, 1); + + added_event->evt = gtd_added_event->evt; + + ERROR_DECL (error); + if (added_event->evt.add) + added_event->evt.add = mono_class_inflate_generic_method_full_checked ( + added_event->evt.add, ginst, mono_class_get_context (ginst), error); + if (added_event->evt.remove) + added_event->evt.remove = mono_class_inflate_generic_method_full_checked ( + added_event->evt.remove, ginst, mono_class_get_context (ginst), error); + if (added_event->evt.raise) + added_event->evt.raise = mono_class_inflate_generic_method_full_checked ( + added_event->evt.raise, ginst, mono_class_get_context (ginst), error); + g_assert (is_ok (error)); /*FIXME proper error handling*/ + + added_event->evt.parent = ginst; + + info->added_events = g_slist_prepend_mem_manager (m_class_get_mem_manager (ginst), info->added_events, (gpointer)added_event); + } + + // finally, update the generation of the ginst info to the same one as the gtd + info->generation = gtd_info->generation; + // we're done info is now up to date +} + static MonoProperty * hot_reload_added_properties_iter (MonoClass *klass, gpointer *iter) { - MonoClassMetadataUpdateInfo *info = mono_class_get_metadata_update_info (klass); + MonoClassMetadataUpdateInfo *info; + if (mono_class_is_ginst (klass)) { + info = hot_reload_get_or_add_ginst_update_info (klass); + } else { + info = mono_class_get_metadata_update_info (klass); + } + if (!info) return NULL; diff --git a/src/mono/mono/metadata/appdomain.c b/src/mono/mono/metadata/appdomain.c index 686ec7e0ed5935..44c8cf3de8c5ba 100644 --- a/src/mono/mono/metadata/appdomain.c +++ b/src/mono/mono/metadata/appdomain.c @@ -571,6 +571,10 @@ mono_domain_fire_assembly_load_event (MonoDomain *domain, MonoAssembly *assembly if (!method) goto exit; + if (assembly->dynamic) + /* Called by RuntimeAssemblyBuilder:.ctor () after the manifest module has been created */ + goto exit; + MonoReflectionAssemblyHandle assembly_handle; assembly_handle = mono_assembly_get_object_handle (assembly, error); goto_if_nok (error, exit); diff --git a/src/mono/mono/metadata/assembly-load-context.c b/src/mono/mono/metadata/assembly-load-context.c index 04aaeaaef826f4..dec9f96b6755f3 100644 --- a/src/mono/mono/metadata/assembly-load-context.c +++ b/src/mono/mono/metadata/assembly-load-context.c @@ -682,6 +682,21 @@ mono_alc_get_all_loaded_assemblies (void) return assemblies; } +GPtrArray* +mono_alc_get_all (void) +{ + // FIXME: prevent the individual ALCs from being collected until the iteration is done. + GSList *tmp; + GPtrArray *all_alcs = g_ptr_array_new (); + MonoAssemblyLoadContext *alc; + alcs_lock (); + for (tmp = alcs; tmp; tmp = tmp->next) { + alc = (MonoAssemblyLoadContext *)tmp->data; + g_ptr_array_add (all_alcs, alc); + } + alcs_unlock (); + return all_alcs; +} MonoBoolean ves_icall_System_Reflection_LoaderAllocatorScout_Destroy (gpointer native) @@ -722,3 +737,4 @@ ves_icall_System_Reflection_LoaderAllocatorScout_Destroy (gpointer native) return TRUE; #endif } + diff --git a/src/mono/mono/metadata/class-accessors.c b/src/mono/mono/metadata/class-accessors.c index e6e952d74e7f2b..4cc08da084bafc 100644 --- a/src/mono/mono/metadata/class-accessors.c +++ b/src/mono/mono/metadata/class-accessors.c @@ -620,11 +620,10 @@ MonoClassMetadataUpdateInfo* mono_class_get_metadata_update_info (MonoClass *klass) { switch (m_class_get_class_kind (klass)) { - case MONO_CLASS_GTD: - return NULL; case MONO_CLASS_DEF: - return (MonoClassMetadataUpdateInfo *)get_pointer_property (klass, PROP_METADATA_UPDATE_INFO); + case MONO_CLASS_GTD: case MONO_CLASS_GINST: + return (MonoClassMetadataUpdateInfo *)get_pointer_property (klass, PROP_METADATA_UPDATE_INFO); case MONO_CLASS_GPARAM: case MONO_CLASS_ARRAY: case MONO_CLASS_POINTER: @@ -643,13 +642,13 @@ mono_class_set_metadata_update_info (MonoClass *klass, MonoClassMetadataUpdateIn { switch (m_class_get_class_kind (klass)) { case MONO_CLASS_GTD: - g_assertf (0, "%s: EnC metadata update info on generic types is not supported", __func__); - break; case MONO_CLASS_DEF: + case MONO_CLASS_GINST: set_pointer_property (klass, PROP_METADATA_UPDATE_INFO, value); return; - case MONO_CLASS_GINST: case MONO_CLASS_GPARAM: + /* metadata-update: this shouldn't happen */ + g_assert_not_reached(); case MONO_CLASS_POINTER: case MONO_CLASS_GC_FILLER: g_assert_not_reached (); @@ -664,11 +663,12 @@ mono_class_has_metadata_update_info (MonoClass *klass) { switch (m_class_get_class_kind (klass)) { case MONO_CLASS_GTD: - return FALSE; case MONO_CLASS_DEF: return get_pointer_property (klass, PROP_METADATA_UPDATE_INFO) != NULL; case MONO_CLASS_GINST: case MONO_CLASS_GPARAM: + /* metadata-update: this shouldn't happen */ + g_assert_not_reached(); case MONO_CLASS_POINTER: case MONO_CLASS_GC_FILLER: return FALSE; diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 8976f00197a486..382ce07d6856f2 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1142,7 +1142,7 @@ mono_method_can_access_field_full (MonoMethod *method, MonoClassField *field, Mo gboolean mono_class_can_access_class (MonoClass *access_class, MonoClass *target_class); -MonoClass * +MONO_COMPONENT_API MonoClass * mono_class_get_generic_type_definition (MonoClass *klass); gboolean diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index 0491ce5f3a1cc7..88f74cdffdd7c9 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -5913,7 +5913,7 @@ mono_class_get_method_from_name_checked (MonoClass *klass, const char *name, mono_class_init_internal (klass); - if (mono_class_is_ginst (klass) && !m_class_get_methods (klass)) { + if (mono_class_is_ginst (klass) && (!m_class_get_methods (klass) || m_class_get_image (klass)->has_updates)) { res = mono_class_get_method_from_name_checked (mono_class_get_generic_class (klass)->container_class, name, param_count, flags, error); if (res) diff --git a/src/mono/mono/metadata/coree.c b/src/mono/mono/metadata/coree.c index 2efdfd25adb648..37c94daf32fdb4 100644 --- a/src/mono/mono/metadata/coree.c +++ b/src/mono/mono/metadata/coree.c @@ -646,7 +646,7 @@ STDAPI MonoFixupCorEE(HMODULE ModuleHandle) *(Trampoline)++ = 0xFF; *(Trampoline)++ = 0xE3; #else -#error Unsupported architecture. + g_assert_not_reached(); #endif #else ProcRva = (DWORD)(ExportFixup->ProcAddress.DWordPtr - (DWORD_PTR)DosHeader); diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index 7d593629689055..2401075a6758fd 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -186,6 +186,9 @@ ICALL_EXPORT void ves_icall_System_Threading_LowLevelLifoSemaphore_ReleaseIn /* include these declarations if we're in the threaded wasm runtime, or if we're building a wasm-targeting cross compiler and we need to support --print-icall-table */ #if (defined(HOST_BROWSER) && !defined(DISABLE_THREADS)) || (defined(TARGET_WASM) && defined(ENABLE_ICALL_SYMBOL_MAP)) +ICALL_EXPORT gpointer ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_InitInternal (void); +ICALL_EXPORT void ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_PrepareAsyncWaitInternal (gpointer sem_ptr, gint32 timeout_ms, gpointer success_cb, gpointer timeout_cb, intptr_t user_data); + ICALL_EXPORT MonoBoolean ves_icall_System_Threading_WebWorkerEventLoop_HasUnsettledInteropPromisesNative(void); ICALL_EXPORT void ves_icall_System_Threading_WebWorkerEventLoop_KeepalivePushInternal (void); ICALL_EXPORT void ves_icall_System_Threading_WebWorkerEventLoop_KeepalivePopInternal (void); diff --git a/src/mono/mono/metadata/icall-def.h b/src/mono/mono/metadata/icall-def.h index 33bf8de3e0fe3e..3fc1a6e1cebf62 100644 --- a/src/mono/mono/metadata/icall-def.h +++ b/src/mono/mono/metadata/icall-def.h @@ -567,6 +567,16 @@ NOHANDLES(ICALL(ILOCK_21, "Increment(long&)", ves_icall_System_Threading_Interlo NOHANDLES(ICALL(ILOCK_22, "MemoryBarrierProcessWide", ves_icall_System_Threading_Interlocked_MemoryBarrierProcessWide)) NOHANDLES(ICALL(ILOCK_23, "Read(long&)", ves_icall_System_Threading_Interlocked_Read_Long)) +/* include these icalls if we're in the threaded wasm runtime, or if we're building a wasm-targeting cross compiler and we need to support --print-icall-table */ +#if (defined(HOST_BROWSER) && !defined(DISABLE_THREADS)) || (defined(TARGET_WASM) && defined(ENABLE_ICALL_SYMBOL_MAP)) +ICALL_TYPE(LIFOASYNCSEM, "System.Threading.LowLevelLifoAsyncWaitSemaphore", LIFOASYNCSEM_1) +NOHANDLES(ICALL(LIFOASYNCSEM_1, "DeleteInternal", ves_icall_System_Threading_LowLevelLifoSemaphore_DeleteInternal)) +NOHANDLES(ICALL(LIFOASYNCSEM_2, "InitInternal", ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_InitInternal)) +NOHANDLES(ICALL(LIFOASYNCSEM_3, "PrepareAsyncWaitInternal", ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_PrepareAsyncWaitInternal)) +NOHANDLES(ICALL(LIFOASYNCSEM_4, "ReleaseInternal", ves_icall_System_Threading_LowLevelLifoSemaphore_ReleaseInternal)) +#endif + + ICALL_TYPE(LIFOSEM, "System.Threading.LowLevelLifoSemaphore", LIFOSEM_1) NOHANDLES(ICALL(LIFOSEM_1, "DeleteInternal", ves_icall_System_Threading_LowLevelLifoSemaphore_DeleteInternal)) NOHANDLES(ICALL(LIFOSEM_2, "InitInternal", ves_icall_System_Threading_LowLevelLifoSemaphore_InitInternal)) diff --git a/src/mono/mono/metadata/icall-signatures.h b/src/mono/mono/metadata/icall-signatures.h index 16b35efa530ce9..d45f1a569c31e8 100644 --- a/src/mono/mono/metadata/icall-signatures.h +++ b/src/mono/mono/metadata/icall-signatures.h @@ -206,6 +206,7 @@ ICALL_SIG (3, (ptr, object, int)) \ ICALL_SIG (3, (ptr, ptr, int)) \ ICALL_SIG (3, (ptr, ptr, int32)) \ ICALL_SIG (3, (ptr, ptr, ptr)) \ +ICALL_SIG (3, (ptr, ptr, object)) \ ICALL_SIG (3, (ptr, ptr, ptrref)) \ ICALL_SIG (3, (ptr, uint32, ptrref)) \ ICALL_SIG (3, (uint32, double, double)) \ diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 63a83b091ee51d..0a7dbc9749595c 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -6176,7 +6176,7 @@ mono_method_get_unmanaged_wrapper_ftnptr_internal (MonoMethod *method, gboolean } else { g_assert (!only_unmanaged_callers_only); } - return mono_get_runtime_callbacks ()->get_ftnptr (method, error); + return mono_get_runtime_callbacks ()->get_ftnptr (method, FALSE, error); } MonoBoolean diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 984c26721eec57..122d8dcdd18b71 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -203,6 +203,7 @@ MONO_JIT_ICALL (mono_gc_wbarrier_generic_nostore_internal) \ MONO_JIT_ICALL (mono_gc_wbarrier_range_copy) \ MONO_JIT_ICALL (mono_gchandle_get_target_internal) \ MONO_JIT_ICALL (mono_generic_class_init) \ +MONO_JIT_ICALL (mono_get_addr_compiled_method) \ MONO_JIT_ICALL (mono_get_assembly_object) \ MONO_JIT_ICALL (mono_get_method_object) \ MONO_JIT_ICALL (mono_get_native_calli_wrapper) \ diff --git a/src/mono/mono/metadata/loader-internals.h b/src/mono/mono/metadata/loader-internals.h index d58404aff6b693..3f64f48c6272ef 100644 --- a/src/mono/mono/metadata/loader-internals.h +++ b/src/mono/mono/metadata/loader-internals.h @@ -61,11 +61,11 @@ typedef struct { GHashTable *delegate_end_invoke_cache; GHashTable *runtime_invoke_signature_cache; GHashTable *runtime_invoke_sig_cache; + GHashTable *delegate_abstract_invoke_cache; /* * indexed by SignaturePointerPair */ - GHashTable *delegate_abstract_invoke_cache; GHashTable *delegate_bound_static_invoke_cache; /* @@ -305,6 +305,9 @@ mono_alc_find_assembly (MonoAssemblyLoadContext *alc, MonoAssemblyName *aname); MONO_COMPONENT_API GPtrArray* mono_alc_get_all_loaded_assemblies (void); +GPtrArray* +mono_alc_get_all (void); + MONO_API void mono_loader_save_bundled_library (int fd, uint64_t offset, uint64_t size, const char *destfname); diff --git a/src/mono/mono/metadata/loader.c b/src/mono/mono/metadata/loader.c index 123753bf4c8160..afb16c6351d072 100644 --- a/src/mono/mono/metadata/loader.c +++ b/src/mono/mono/metadata/loader.c @@ -486,9 +486,16 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con return NULL; } int mcount = mono_class_get_method_count (klass); - MonoMethod **klass_methods = m_class_get_methods (klass); - for (i = 0; i < mcount; ++i) { - MonoMethod *m = klass_methods [i]; + i = -1; + gpointer iter = NULL; + MonoMethod *m = NULL; + gboolean matched = FALSE; + /* FIXME: metadata-update iterating using + * mono_class_get_methods will break if `m` is NULL. Need to + * reconcile with the `if (!m)` "we must cope" comment below. + */ + while ((m = mono_class_get_methods (klass, &iter))) { + ++i; MonoMethodSignature *msig; /* We must cope with failing to load some of the types. */ @@ -507,16 +514,33 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con continue; if (sig->call_convention == MONO_CALL_VARARG) { - if (mono_metadata_signature_vararg_match (sig, msig)) + if (mono_metadata_signature_vararg_match (sig, msig)) { + matched = TRUE; break; + } } else { - if (mono_metadata_signature_equal (sig, msig)) + if (mono_metadata_signature_equal (sig, msig)) { + matched = TRUE; break; + } } } - if (i < mcount) - return mono_class_get_method_by_index (from_class, i); + if (matched) { + if (i < mcount) + return mono_class_get_method_by_index (from_class, i); + else if (m != NULL) { + // FIXME: metadata-update: hack + // it's from a metadata-update, probably + m = mono_class_inflate_generic_method_full_checked ( + m, from_class, mono_class_get_context (from_class), error); + mono_error_assert_ok (error); + g_assert (m != NULL); + g_assert (m->klass == from_class); + g_assert (m->is_inflated); + return m; + } + } return NULL; } diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index 54e37d2036d998..06a20123dbee63 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -1990,7 +1990,7 @@ emit_delegate_end_invoke_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *sig) } static void -emit_delegate_invoke_internal_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodSignature *invoke_sig, gboolean static_method_with_first_arg_bound, gboolean callvirt, gboolean closed_over_null, MonoMethod *method, MonoMethod *target_method, MonoClass *target_class, MonoGenericContext *ctx, MonoGenericContainer *container) +emit_delegate_invoke_internal_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodSignature *invoke_sig, MonoMethodSignature *target_method_sig, gboolean static_method_with_first_arg_bound, gboolean callvirt, gboolean closed_over_null, MonoMethod *method, MonoMethod *target_method, MonoClass *target_class, MonoGenericContext *ctx, MonoGenericContainer *container) { int local_i, local_len, local_delegates, local_d, local_target, local_res = 0; int pos0, pos1, pos2; @@ -2088,19 +2088,12 @@ emit_delegate_invoke_internal_ilgen (MonoMethodBuilder *mb, MonoMethodSignature if (callvirt) { if (!closed_over_null) { - /* if target_method is not really virtual, turn it into a direct call */ - if (!(target_method->flags & METHOD_ATTRIBUTE_VIRTUAL) || m_class_is_valuetype (target_class)) { - mono_mb_emit_ldarg (mb, 1); - for (i = 1; i < sig->param_count; ++i) - mono_mb_emit_ldarg (mb, i + 1); - mono_mb_emit_op (mb, CEE_CALL, target_method); - } else { - mono_mb_emit_ldarg (mb, 1); - mono_mb_emit_op (mb, CEE_CASTCLASS, target_class); - for (i = 1; i < sig->param_count; ++i) - mono_mb_emit_ldarg (mb, i + 1); - mono_mb_emit_op (mb, CEE_CALLVIRT, target_method); - } + for (i = 1; i <= sig->param_count; ++i) + mono_mb_emit_ldarg (mb, i); + mono_mb_emit_ldarg (mb, 1); + mono_mb_emit_ldarg (mb, 0); + mono_mb_emit_icall (mb, mono_get_addr_compiled_method); + mono_mb_emit_op (mb, CEE_CALLI, target_method_sig); } else { mono_mb_emit_byte (mb, CEE_LDNULL); for (i = 0; i < sig->param_count; ++i) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index e7aff60aee5e24..977ecd9e768e72 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -324,6 +324,7 @@ mono_marshal_init (void) register_icall (monoeg_g_free, mono_icall_sig_void_ptr, FALSE); register_icall (mono_object_isinst_icall, mono_icall_sig_object_object_ptr, TRUE); register_icall (mono_struct_delete_old, mono_icall_sig_void_ptr_ptr, FALSE); + register_icall (mono_get_addr_compiled_method, mono_icall_sig_ptr_ptr_object, FALSE); register_icall (mono_delegate_begin_invoke, mono_icall_sig_object_object_ptr, FALSE); register_icall (mono_delegate_end_invoke, mono_icall_sig_object_object_ptr, FALSE); register_icall (mono_gc_wbarrier_generic_nostore_internal, mono_icall_sig_void_ptr, TRUE); @@ -2085,13 +2086,11 @@ free_signature_pointer_pair (SignaturePointerPair *pair) MonoMethod * mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt, gboolean static_method_with_first_arg_bound, MonoMethod *target_method) { - MonoMethodSignature *sig, *invoke_sig; + MonoMethodSignature *sig, *invoke_sig, *target_method_sig = NULL; MonoMethodBuilder *mb; MonoMethod *res; GHashTable *cache; gpointer cache_key = NULL; - SignaturePointerPair key = { NULL, NULL }; - SignaturePointerPair *new_key; char *name; MonoClass *target_class = NULL; gboolean closed_over_null = FALSE; @@ -2101,7 +2100,6 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt WrapperInfo *info; WrapperSubtype subtype = WRAPPER_SUBTYPE_NONE; MonoMemoryManager *mem_manager = NULL; - gboolean found; g_assert (method && m_class_get_parent (method->klass) == mono_defaults.multicastdelegate_class && !strcmp (method->name, "Invoke")); @@ -2129,6 +2127,11 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt } closed_over_null = sig->param_count == mono_method_signature_internal (target_method)->param_count; + + /* + * We don't want to use target_method's signature because it can be freed early + */ + target_method_sig = mono_method_signature_internal (target_method); } if (static_method_with_first_arg_bound) { @@ -2188,17 +2191,16 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt cache_ptr = &mono_method_get_wrapper_cache (method)->delegate_abstract_invoke_cache; - /* We need to cache the signature+method pair */ + /* We need to cache the signature */ mono_marshal_lock (); - if (!*cache_ptr) - *cache_ptr = g_hash_table_new_full (signature_pointer_pair_hash, (GEqualFunc)signature_pointer_pair_equal, (GDestroyNotify)free_signature_pointer_pair, NULL); - cache = *cache_ptr; - key.sig = invoke_sig; - key.pointer = target_method; - res = (MonoMethod *)g_hash_table_lookup (cache, &key); + cache = get_cache (cache_ptr, + (GHashFunc)mono_signature_hash, + (GCompareFunc)mono_metadata_signature_equal); + res = (MonoMethod *)g_hash_table_lookup (cache, invoke_sig); mono_marshal_unlock (); if (res) return res; + cache_key = invoke_sig; } else { // Inflated methods should not be in this cache because it's not stored on the imageset. g_assert (!method->is_inflated); @@ -2239,7 +2241,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt /* FIXME: Other subtypes */ mb->mem_manager = m_method_get_mem_manager (method); - get_marshal_cb ()->emit_delegate_invoke_internal (mb, sig, invoke_sig, static_method_with_first_arg_bound, callvirt, closed_over_null, method, target_method, target_class, ctx, container); + get_marshal_cb ()->emit_delegate_invoke_internal (mb, sig, invoke_sig, target_method_sig, static_method_with_first_arg_bound, callvirt, closed_over_null, method, target_method, target_class, ctx, container); get_marshal_cb ()->mb_skip_visibility (mb); @@ -2251,13 +2253,6 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt def = mono_mb_create_and_cache_full (cache, cache_key, mb, sig, sig->param_count + 16, info, NULL); res = cache_generic_delegate_wrapper (cache, orig_method, def, ctx); - } else if (callvirt) { - new_key = g_new0 (SignaturePointerPair, 1); - *new_key = key; - - res = mono_mb_create_and_cache_full (cache, new_key, mb, sig, sig->param_count + 16, info, &found); - if (found) - g_free (new_key); } else { res = mono_mb_create_and_cache_full (cache, cache_key, mb, sig, sig->param_count + 16, info, NULL); } @@ -5481,6 +5476,49 @@ mono_struct_delete_old (MonoClass *klass, char *ptr) } } +void* +mono_get_addr_compiled_method (gpointer arg, MonoDelegate *del) +{ + ERROR_DECL (error); + MonoMethod *res, *method = del->method; + gpointer addr; + gboolean need_unbox = FALSE; + + if (arg == NULL) { + mono_error_set_null_reference (error); + mono_error_set_pending_exception (error); + return NULL; + } + + MonoClass *klass = del->object.vtable->klass; + MonoMethod *invoke = mono_get_delegate_invoke_internal (klass); + MonoMethodSignature *invoke_sig = mono_method_signature_internal (invoke); + + MonoClass *arg_class = NULL; + if (m_type_is_byref (invoke_sig->params [0])) { + arg_class = mono_class_from_mono_type_internal (invoke_sig->params [0]); + } else { + MonoObject *object = (MonoObject*)arg; + arg_class = object->vtable->klass; + } + + res = mono_class_get_virtual_method (arg_class, method, error); + + if (!is_ok (error)) { + mono_error_set_pending_exception (error); + return NULL; + } + + need_unbox = m_class_is_valuetype (res->klass) && !m_class_is_valuetype (method->klass); + addr = mono_get_runtime_callbacks ()->get_ftnptr (res, need_unbox, error); + if (!is_ok (error)) { + mono_error_set_pending_exception (error); + return NULL; + } + + return addr; +} + void ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure (gpointer src, MonoReflectionTypeHandle type, MonoError *error) { @@ -6255,8 +6293,6 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) */ if (image->wrapper_caches.runtime_invoke_method_cache) clear_runtime_invoke_method_cache (image->wrapper_caches.runtime_invoke_method_cache, method); - if (image->wrapper_caches.delegate_abstract_invoke_cache) - g_hash_table_foreach_remove (image->wrapper_caches.delegate_abstract_invoke_cache, signature_pointer_pair_matches_pointer, method); // FIXME: Need to clear the caches in other images as well if (image->wrapper_caches.delegate_bound_static_invoke_cache) g_hash_table_remove (image->wrapper_caches.delegate_bound_static_invoke_cache, mono_method_signature_internal (method)); diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index 6cd33778301f93..e6ad3153bbfda1 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -328,7 +328,7 @@ typedef struct { void (*emit_runtime_invoke_dynamic) (MonoMethodBuilder *mb); void (*emit_delegate_begin_invoke) (MonoMethodBuilder *mb, MonoMethodSignature *sig); void (*emit_delegate_end_invoke) (MonoMethodBuilder *mb, MonoMethodSignature *sig); - void (*emit_delegate_invoke_internal) (MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodSignature *invoke_sig, gboolean static_method_with_first_arg_bound, gboolean callvirt, gboolean closed_over_null, MonoMethod *method, MonoMethod *target_method, MonoClass *target_class, MonoGenericContext *ctx, MonoGenericContainer *container); + void (*emit_delegate_invoke_internal) (MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodSignature *invoke_sig, MonoMethodSignature *target_method_sig, gboolean static_method_with_first_arg_bound, gboolean callvirt, gboolean closed_over_null, MonoMethod *method, MonoMethod *target_method, MonoClass *target_class, MonoGenericContext *ctx, MonoGenericContainer *container); void (*emit_synchronized_wrapper) (MonoMethodBuilder *mb, MonoMethod *method, MonoGenericContext *ctx, MonoGenericContainer *container, MonoMethod *enter_method, MonoMethod *exit_method, MonoMethod *gettypefromhandle_method); void (*emit_unbox_wrapper) (MonoMethodBuilder *mb, MonoMethod *method); void (*emit_array_accessor_wrapper) (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *sig, MonoGenericContext *ctx); @@ -624,6 +624,10 @@ ICALL_EXPORT void mono_struct_delete_old (MonoClass *klass, char *ptr); +ICALL_EXPORT +void* +mono_get_addr_compiled_method (gpointer arg, MonoDelegate *del); + int mono_emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index 91d8dd9564db56..c564777f848370 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -7029,18 +7029,27 @@ mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod if (num_overrides) *num_overrides = 0; - if (!tdef->base) + if (!tdef->base && !image->has_updates) return; loc.t = tdef; loc.col_idx = MONO_METHODIMPL_CLASS; loc.idx = mono_metadata_token_index (type_token); + loc.result = 0; - /* FIXME metadata-update */ + gboolean found = tdef->base && mono_binary_search (&loc, tdef->base, table_info_get_rows (tdef), tdef->row_size, table_locator) != NULL; - if (!mono_binary_search (&loc, tdef->base, table_info_get_rows (tdef), tdef->row_size, table_locator)) + if (!found && !image->has_updates) return; + if (G_UNLIKELY (image->has_updates)) { + if (!found && !mono_metadata_update_metadata_linear_search (image, tdef, &loc, table_locator)) { + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_METADATA_UPDATE, "NO Found interfaces for class 0x%08x", type_token); + return; + } + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_METADATA_UPDATE, "Found interfaces for class 0x%08x starting at 0x%08x", type_token, loc.result); + } + start = loc.result; end = start + 1; /* @@ -7052,7 +7061,7 @@ mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod else break; } - guint32 rows = table_info_get_rows (tdef); + guint32 rows = mono_metadata_table_num_rows (image, MONO_TABLE_METHODIMPL); while (end < rows) { if (loc.idx == mono_metadata_decode_row_col (tdef, end, MONO_METHODIMPL_CLASS)) end++; diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 10cd43c27a03e6..9312793f853379 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -532,15 +532,23 @@ netcore_probe_for_module (MonoImage *image, const char *file_name, int flags, Mo // If the difference becomes a problem, overhaul this algorithm to match theirs exactly ERROR_DECL (bad_image_error); + gboolean probe_first_without_prepend = FALSE; #if defined(HOST_ANDROID) // On Android, try without any path additions first. It is sensitive to probing that will always miss // and lookup for some libraries is required to use a relative path - module = netcore_probe_for_module_variations (NULL, file_name, lflags, error); - if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE) - mono_error_move (bad_image_error, error); + probe_first_without_prepend = TRUE; +#else + if (file_name != NULL && g_path_is_absolute (file_name)) + probe_first_without_prepend = TRUE; #endif + if (module == NULL && probe_first_without_prepend) { + module = netcore_probe_for_module_variations (NULL, file_name, lflags, error); + if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE) + mono_error_move (bad_image_error, error); + } + // Check the NATIVE_DLL_SEARCH_DIRECTORIES for (int i = 0; i < pinvoke_search_directories_count && module == NULL; ++i) { mono_error_cleanup (error); @@ -563,15 +571,13 @@ netcore_probe_for_module (MonoImage *image, const char *file_name, int flags, Mo g_free (mdirname); } -#if !defined(HOST_ANDROID) - // Try without any path additions - if (module == NULL) + // Try without any path additions, if we didn't try it already + if (module == NULL && !probe_first_without_prepend) { module = netcore_probe_for_module_variations (NULL, file_name, lflags, error); if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE) mono_error_move (bad_image_error, error); } -#endif // TODO: Pass remaining flags on to LoadLibraryEx on Windows where appropriate, see https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportsearchpath?view=netcore-3.1 diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index a87e50de2b7086..b968762c210cce 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -616,6 +616,7 @@ struct _MonoInternalThread { * longer */ MonoLongLivedThreadData *longlived; MonoBoolean threadpool_thread; + MonoBoolean external_eventloop; guint8 apartment_state; gint32 managed_id; guint32 small_id; @@ -695,7 +696,7 @@ typedef struct { void (*get_jit_stats)(gint64 *methods_compiled, gint64 *cil_code_size_bytes, gint64 *native_code_size_bytes, gint64 *jit_time); void (*get_exception_stats)(guint32 *exception_count); // Same as compile_method, but returns a MonoFtnDesc in llvmonly mode - gpointer (*get_ftnptr)(MonoMethod *method, MonoError *error); + gpointer (*get_ftnptr)(MonoMethod *method, gboolean need_unbox, MonoError *error); void (*interp_jit_info_foreach)(InterpJitInfoFunc func, gpointer user_data); gboolean (*interp_sufficient_stack)(gsize size); void (*init_class) (MonoClass *klass); @@ -1463,8 +1464,10 @@ MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMe MonoArrayHandle mono_param_get_objects_internal (MonoMethod *method, MonoClass *refclass, MonoError *error); +MONO_COMPONENT_API MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic); + MonoType* mono_reflection_bind_generic_parameters (MonoReflectionTypeHandle type, int type_argc, MonoType **types, MonoError *error); void diff --git a/src/mono/mono/metadata/profiler.c b/src/mono/mono/metadata/profiler.c index 0a76a5dace43e8..841f070d1490b8 100644 --- a/src/mono/mono/metadata/profiler.c +++ b/src/mono/mono/metadata/profiler.c @@ -114,23 +114,6 @@ load_profiler_from_directory (const char *directory, const char *libname, const return FALSE; } -static gboolean -load_profiler_from_installation (const char *libname, const char *name, const char *desc) -{ - ERROR_DECL (load_error); - - MonoDl *module = mono_dl_open_runtime_lib (libname, MONO_DL_EAGER, load_error); - - if (!module) { - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Could not open from installation: %s", mono_error_get_message_without_fields (load_error)); - mono_error_cleanup (load_error); - return FALSE; - } - - mono_error_assert_ok (load_error); - return load_profiler (module, name, desc); -} - /** * mono_profiler_load: * @@ -192,9 +175,6 @@ mono_profiler_load (const char *desc) libname = g_strdup_printf ("mono-profiler-%s", mname); - if (load_profiler_from_installation (libname, mname, desc)) - goto done; - if (load_profiler_from_directory (NULL, libname, mname, desc)) goto done; diff --git a/src/mono/mono/metadata/threads-types.h b/src/mono/mono/metadata/threads-types.h index fe57d74a02e393..5e89f84bef211a 100644 --- a/src/mono/mono/metadata/threads-types.h +++ b/src/mono/mono/metadata/threads-types.h @@ -78,6 +78,10 @@ typedef enum { MONO_THREAD_CREATE_FLAGS_DEBUGGER = 0x02, MONO_THREAD_CREATE_FLAGS_FORCE_CREATE = 0x04, MONO_THREAD_CREATE_FLAGS_SMALL_STACK = 0x08, + // "external eventloop" means the thread main function can return without killing the thread + // and the thread will continue to be attached to the runtime and may invoke embedding APIs + // and managed calls. There is usually some platform-specific way to shut down the thread. + MONO_THREAD_CREATE_FLAGS_EXTERNAL_EVENTLOOP = 0x10, } MonoThreadCreateFlags; MONO_COMPONENT_API MonoInternalThread* diff --git a/src/mono/mono/metadata/threads.c b/src/mono/mono/metadata/threads.c index abe6cae20c51e3..0788d9ccdac13c 100644 --- a/src/mono/mono/metadata/threads.c +++ b/src/mono/mono/metadata/threads.c @@ -1088,6 +1088,7 @@ typedef struct { MonoThreadStart start_func; gpointer start_func_arg; gboolean force_attach; + gboolean external_eventloop; gboolean failed; MonoCoopSem registered; } StartInfo; @@ -1173,6 +1174,8 @@ start_wrapper_internal (StartInfo *start_info, gsize *stack_ptr) /* Let the thread that called Start() know we're ready */ mono_coop_sem_post (&start_info->registered); + gboolean external_eventloop = start_info->external_eventloop; + if (mono_atomic_dec_i32 (&start_info->ref) == 0) { mono_coop_sem_destroy (&start_info->registered); g_free (start_info); @@ -1240,6 +1243,12 @@ start_wrapper_internal (StartInfo *start_info, gsize *stack_ptr) THREAD_DEBUG (g_message ("%s: (%" G_GSIZE_FORMAT ") Start wrapper terminating", __func__, mono_native_thread_id_get ())); + if (G_UNLIKELY (external_eventloop)) { + /* if the thread wants to stay alive in an external eventloop, don't clean up after it */ + if (mono_thread_platform_external_eventloop_keepalive_check ()) + return 0; + } + /* Do any cleanup needed for apartment state. This * cannot be done in mono_thread_detach_internal since * mono_thread_detach_internal could be called for a @@ -1266,9 +1275,19 @@ start_wrapper (gpointer data) info = mono_thread_info_attach (); info->runtime_thread = TRUE; + gboolean external_eventloop = start_info->external_eventloop; /* Run the actual main function of the thread */ res = start_wrapper_internal (start_info, (gsize*)info->stack_end); + if (G_UNLIKELY (external_eventloop)) { + /* if the thread wants to stay alive, don't clean up after it */ + if (mono_thread_platform_external_eventloop_keepalive_check ()) { + /* while we wait in the external eventloop, we're GC safe */ + MONO_REQ_GC_SAFE_MODE; + return 0; + } + } + mono_thread_info_exit (res); g_assert_not_reached (); @@ -1355,6 +1374,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoThreadStart start_info->start_func_arg = start_func_arg; start_info->force_attach = flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE; start_info->failed = FALSE; + start_info->external_eventloop = (flags & MONO_THREAD_CREATE_FLAGS_EXTERNAL_EVENTLOOP) != 0; mono_coop_sem_init (&start_info->registered, 0); if (flags != MONO_THREAD_CREATE_FLAGS_SMALL_STACK) @@ -4913,7 +4933,11 @@ ves_icall_System_Threading_Thread_StartInternal (MonoThreadObjectHandle thread_h return; } - res = create_thread (internal, internal, NULL, NULL, stack_size, MONO_THREAD_CREATE_FLAGS_NONE, error); + MonoThreadCreateFlags create_flags = MONO_THREAD_CREATE_FLAGS_NONE; + if (G_UNLIKELY (internal->external_eventloop)) + create_flags |= MONO_THREAD_CREATE_FLAGS_EXTERNAL_EVENTLOOP; + + res = create_thread (internal, internal, NULL, NULL, stack_size, create_flags, error); if (!res) { UNLOCK_THREAD (internal); return; @@ -4952,25 +4976,62 @@ ves_icall_System_Threading_LowLevelLifoSemaphore_InitInternal (void) void ves_icall_System_Threading_LowLevelLifoSemaphore_DeleteInternal (gpointer sem_ptr) { - LifoSemaphore *sem = (LifoSemaphore *)sem_ptr; - mono_lifo_semaphore_delete (sem); + LifoSemaphoreBase *sem = (LifoSemaphoreBase *)sem_ptr; + switch (sem->kind) { + case LIFO_SEMAPHORE_NORMAL: + mono_lifo_semaphore_delete ((LifoSemaphore*)sem); + break; +#if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) + case LIFO_SEMAPHORE_ASYNCWAIT: + mono_lifo_semaphore_asyncwait_delete ((LifoSemaphoreAsyncWait*)sem); + break; +#endif + default: + g_assert_not_reached(); + } } gint32 ves_icall_System_Threading_LowLevelLifoSemaphore_TimedWaitInternal (gpointer sem_ptr, gint32 timeout_ms) { LifoSemaphore *sem = (LifoSemaphore *)sem_ptr; + g_assert (sem->base.kind == LIFO_SEMAPHORE_NORMAL); return mono_lifo_semaphore_timed_wait (sem, timeout_ms); } void ves_icall_System_Threading_LowLevelLifoSemaphore_ReleaseInternal (gpointer sem_ptr, gint32 count) { - LifoSemaphore *sem = (LifoSemaphore *)sem_ptr; - mono_lifo_semaphore_release (sem, count); + LifoSemaphoreBase *sem = (LifoSemaphoreBase *)sem_ptr; + switch (sem->kind) { + case LIFO_SEMAPHORE_NORMAL: + mono_lifo_semaphore_release ((LifoSemaphore*)sem, count); + break; +#if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) + case LIFO_SEMAPHORE_ASYNCWAIT: + mono_lifo_semaphore_asyncwait_release ((LifoSemaphoreAsyncWait*)sem, count); + break; +#endif + default: + g_assert_not_reached(); + } } #if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) +gpointer +ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_InitInternal (void) +{ + return (gpointer)mono_lifo_semaphore_asyncwait_init (); +} + +void +ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_PrepareAsyncWaitInternal (gpointer sem_ptr, gint32 timeout_ms, gpointer success_cb, gpointer timedout_cb, intptr_t user_data) +{ + LifoSemaphoreAsyncWait *sem = (LifoSemaphoreAsyncWait *)sem_ptr; + g_assert (sem->base.kind == LIFO_SEMAPHORE_ASYNCWAIT); + mono_lifo_semaphore_asyncwait_prepare_wait (sem, timeout_ms, (LifoSemaphoreAsyncWaitCallbackFn)success_cb, (LifoSemaphoreAsyncWaitCallbackFn)timedout_cb, user_data); +} + void ves_icall_System_Threading_WebWorkerEventLoop_KeepalivePushInternal (void) { @@ -4996,6 +5057,18 @@ ves_icall_System_Threading_WebWorkerEventLoop_HasUnsettledInteropPromisesNative( /* for the AOT cross compiler with --print-icall-table these don't need to be callable, they just * need to be defined */ #if defined(TARGET_WASM) && defined(ENABLE_ICALL_SYMBOL_MAP) +gpointer +ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_InitInternal (void) +{ + g_assert_not_reached (); +} + +void +ves_icall_System_Threading_LowLevelLifoAsyncWaitSemaphore_PrepareAsyncWaitInternal (gpointer sem_ptr, gint32 timeout_ms, gpointer success_cb, gpointer timedout_cb, intptr_t user_data) +{ + g_assert_not_reached (); +} + void ves_icall_System_Threading_WebWorkerEventLoop_KeepalivePushInternal (void) { @@ -5013,6 +5086,5 @@ ves_icall_System_Threading_WebWorkerEventLoop_HasUnsettledInteropPromisesNative( { g_assert_not_reached(); } - #endif /* defined(TARGET_WASM) && defined(ENABLE_ICALL_SYMBOL_MAP) */ diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 2d39b5dbe266d9..49fe1b7f822c2d 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -82,6 +82,9 @@ if(HAVE_SYS_ICU) if(ICU_LIBDIR) set(ICU_LDFLAGS "-L${ICU_LIBDIR}") endif() + + add_library(icu_shim_objects OBJECT "${icu_shim_sources}") + set(HAVE_ICU_SHIM 1) endif() # @@ -350,7 +353,7 @@ if(HOST_WIN32) set_source_files_properties(${ZLIB_SOURCES} PROPERTIES COMPILE_OPTIONS "/wd4005;/wd4127;/wd4131;/wd4244") endif() -set(monosgen-sources "${icu_shim_sources};${mini_sources};${ZLIB_SOURCES}") +set(monosgen-sources "${mini_sources};${ZLIB_SOURCES}") add_library(monosgen-objects OBJECT "${monosgen-sources}") target_link_libraries (monosgen-objects PRIVATE monoapi eglib_api utils_objects sgen_objects metadata_objects) @@ -379,6 +382,9 @@ if(NOT DISABLE_SHARED_LIBS) endif(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X) set_target_properties(monosgen-shared PROPERTIES OUTPUT_NAME ${MONO_SHARED_LIB_NAME}) target_link_libraries(monosgen-shared PRIVATE monoapi eglib_objects utils_objects sgen_objects metadata_objects) + if(HAVE_ICU_SHIM) + target_link_libraries(monosgen-shared PRIVATE icu_shim_objects) + endif() target_include_directories (monosgen-shared PRIVATE monoapi) if(TARGET_WIN32) # on Windows the import library for the shared mono library will have the same name as the static library, @@ -436,6 +442,9 @@ if(NOT DISABLE_SHARED_LIBS) add_library(${frameworkconfig} SHARED $) target_compile_definitions(${frameworkconfig} PRIVATE -DMONO_DLL_EXPORT) target_link_libraries(${frameworkconfig} PRIVATE monoapi eglib_objects utils_objects sgen_objects metadata_objects) + if(HAVE_ICU_SHIM) + target_link_libraries(${frameworkconfig} PRIVATE icu_shim_objects) + endif() target_link_libraries(${frameworkconfig} PRIVATE ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS}) if(ICU_LDFLAGS) @@ -538,7 +547,11 @@ if(NOT DISABLE_EXECUTABLES) if(MONO_CROSS_COMPILE_EXECUTABLE_NAME) set_target_properties(mono-sgen PROPERTIES OUTPUT_NAME mono-aot-cross) endif() - target_link_libraries(mono-sgen PRIVATE monoapi eglib_api monosgen-static ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS}) + target_link_libraries(mono-sgen PRIVATE monoapi eglib_api monosgen-static) + if(HAVE_ICU_SHIM) + target_link_libraries(mono-sgen PRIVATE icu_shim_objects) + endif() + target_link_libraries(mono-sgen PRIVATE ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS}) # Alpine Linux implements ucontext in a different library if(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X) target_link_libraries(mono-sgen PRIVATE ucontext) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 82b9698765a32b..124fa7ac723c2b 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -217,7 +217,7 @@ typedef struct MonoAotOptions { gboolean use_trampolines_page; gboolean no_instances; // We are collecting inflated methods and emitting non-inflated - gboolean dedup; + gboolean dedup_skip; // The name of the assembly for which the AOT module is going to have all deduped methods moved to. // When set, we are emitting inflated methods only char *dedup_include; @@ -295,6 +295,13 @@ typedef struct _UnwindInfoSectionCacheItem { } UnwindInfoSectionCacheItem; #endif +typedef enum { + DEDUP_NONE, // dedup is turned off + DEDUP_SKIP, // dedup is on, dedup assembly is not provided + DEDUP_COLLECT, // dedup is on, this assembly is not the dedup image, so just collect the methods + DEDUP_EMIT // dedup is on, this assembly is the dedup image, emit collected methods +} DedupPhase; + typedef struct MonoAotCompile { MonoImage *image; GPtrArray *methods; @@ -381,7 +388,6 @@ typedef struct MonoAotCompile { gboolean llvm; gboolean has_jitted_code; gboolean is_full_aot; - gboolean dedup_collect_only; MonoAotFileFlags flags; MonoDynamicStream blob; gboolean blob_closed; @@ -416,8 +422,8 @@ typedef struct MonoAotCompile { FILE *compiled_methods_outfile; int datafile_offset; int gc_name_offset; - // In this mode, we are emitting dedupable methods that we encounter - gboolean dedup_emit_mode; + + DedupPhase dedup_phase; } MonoAotCompile; typedef struct { @@ -519,6 +525,12 @@ mono_aot_mode_is_hybrid (MonoAotOptions *opts) return opts->mode == MONO_AOT_MODE_HYBRID; } +static void +dedup_change_phase (MonoAotCompile *acfg, int next_phase) +{ + acfg->dedup_phase = next_phase; +} + static void aot_printf (MonoAotCompile *acfg, const gchar *format, ...) { @@ -4300,6 +4312,22 @@ get_method_index (MonoAotCompile *acfg, MonoMethod *method) return index - 1; } +static gboolean +collect_dedup_method (MonoAotCompile *acfg, MonoMethod *method) +{ + // Check if the dedup is enabled, and if the current method can be deduplicated + if ((acfg->dedup_phase == DEDUP_SKIP || acfg->dedup_phase == DEDUP_COLLECT) && mono_aot_can_dedup (method)) { + if (acfg->dedup_phase == DEDUP_SKIP) + return TRUE; + // Remember for later + if (acfg->dedup_phase == DEDUP_COLLECT && !g_hash_table_lookup (dedup_methods, method)) + g_hash_table_insert (dedup_methods, method, method); + } + return FALSE; +} + + + static int add_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean extra, int depth) { @@ -4389,16 +4417,8 @@ add_extra_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean prefer mono_error_assert_ok (error); } - if ((acfg->aot_opts.dedup || acfg->aot_opts.dedup_include) && mono_aot_can_dedup (method)) { - if (acfg->aot_opts.dedup) { - /* Don't emit instances */ - return; - } else if (!acfg->dedup_emit_mode) { - /* Remember for later */ - if (!g_hash_table_lookup (dedup_methods, method)) - g_hash_table_insert (dedup_methods, method, method); - } - } + if (collect_dedup_method (acfg, method)) + return; if (acfg->aot_opts.log_generics) aot_printf (acfg, "%*sAdding method %s.\n", depth, "", mono_method_get_full_name (method)); @@ -6390,7 +6410,7 @@ is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc if (callee_cfg) { gboolean direct_callable = TRUE; - if (direct_callable && (acfg->aot_opts.dedup || acfg->aot_opts.dedup_include) && mono_aot_can_dedup (patch_info->data.method)) + if (direct_callable && acfg->dedup_phase != DEDUP_NONE && mono_aot_can_dedup (patch_info->data.method)) direct_callable = FALSE; if (direct_callable && !acfg->llvm && !(!callee_cfg->has_got_slots && mono_class_is_before_field_init (callee_cfg->method->klass))) @@ -7248,7 +7268,8 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint case MONO_PATCH_INFO_DELEGATE_INFO: case MONO_PATCH_INFO_VIRT_METHOD: case MONO_PATCH_INFO_GSHAREDVT_METHOD: - case MONO_PATCH_INFO_GSHAREDVT_CALL: { + case MONO_PATCH_INFO_GSHAREDVT_CALL: + case MONO_PATCH_INFO_SIGNATURE: { tmp.type = patch_type; tmp.data.target = data; encode_patch (acfg, &tmp, p, &p); @@ -8793,7 +8814,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts) } else if (str_begins_with (arg, "internal-logfile=")) { opts->logfile = g_strdup (arg + strlen ("internal-logfile=")); } else if (str_begins_with (arg, "dedup-skip")) { - opts->dedup = TRUE; + opts->dedup_skip = TRUE; } else if (str_begins_with (arg, "dedup-include=")) { opts->dedup_include = g_strdup (arg + strlen ("dedup-include=")); } else if (str_begins_with (arg, "mtriple=")) { @@ -14060,6 +14081,7 @@ acfg_create (MonoAssembly *ass, guint32 jit_opts) acfg->gshared_instances = g_hash_table_new (NULL, NULL); acfg->prefer_instances = g_hash_table_new (NULL, NULL); acfg->exported_methods = g_ptr_array_new (); + acfg->dedup_phase = DEDUP_NONE; mono_os_mutex_init_recursive (&acfg->mutex); init_got_info (&acfg->got_info); @@ -14706,15 +14728,20 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) acfg = acfg_create (ass, jit_opts); memcpy (&acfg->aot_opts, aot_options, sizeof (MonoAotOptions)); - - if (acfg->aot_opts.dedup_include && ass != dedup_assembly) - acfg->dedup_collect_only = TRUE; + if (acfg->aot_opts.dedup_skip || acfg->aot_opts.dedup_include) { + if (acfg->aot_opts.dedup_skip) + dedup_change_phase (acfg, DEDUP_SKIP); + else if (acfg->aot_opts.dedup_include && ass != dedup_assembly) + dedup_change_phase (acfg, DEDUP_COLLECT); + else + dedup_change_phase (acfg, DEDUP_EMIT); + } if (acfg->aot_opts.logfile) { acfg->logfile = fopen (acfg->aot_opts.logfile, "a+"); } - if (acfg->aot_opts.compiled_methods_outfile && !acfg->dedup_collect_only) { + if (acfg->aot_opts.compiled_methods_outfile && acfg->dedup_phase != DEDUP_COLLECT) { acfg->compiled_methods_outfile = fopen (acfg->aot_opts.compiled_methods_outfile, "w+"); if (!acfg->compiled_methods_outfile) aot_printerrf (acfg, "Unable to open compiled-methods-outfile specified file %s\n", acfg->aot_opts.compiled_methods_outfile); @@ -14765,14 +14792,14 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) if (acfg->jit_opts & MONO_OPT_GSHAREDVT) mono_set_generic_sharing_vt_supported (TRUE); - if (!acfg->dedup_collect_only) + if (acfg->dedup_phase != DEDUP_COLLECT) aot_printf (acfg, "Mono Ahead of Time compiler - compiling assembly %s\n", image->name); if (!acfg->aot_opts.deterministic) generate_aotid ((guint8*) &acfg->image->aotid); char *aotid = mono_guid_to_string (acfg->image->aotid); - if (!acfg->dedup_collect_only && !acfg->aot_opts.deterministic) + if (acfg->dedup_phase != DEDUP_COLLECT && !acfg->aot_opts.deterministic) aot_printf (acfg, "AOTID %s\n", aotid); g_free (aotid); @@ -14878,9 +14905,9 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) if (mini_safepoints_enabled ()) acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SAFEPOINTS); - // The methods in dedup-emit amodules must be available on runtime startup + // The methods in dedup AOT module must be available on runtime startup // Note: Only one such amodule can have this attribute - if (ass == dedup_assembly) + if (acfg->dedup_phase == DEDUP_EMIT) acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_EAGER_LOAD); if (acfg->aot_opts.instances_logfile_path) { @@ -14972,7 +14999,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) return 1; } - if (ass == dedup_assembly) { + if (acfg->dedup_phase == DEDUP_EMIT) { /* Add collected dedup-able methods */ aot_printf (acfg, "Adding %d dedup-ed methods.\n", g_hash_table_size (dedup_methods)); @@ -14980,8 +15007,6 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) MonoMethod *key; MonoMethod *method; - acfg->dedup_emit_mode = TRUE; - g_hash_table_iter_init (&iter, dedup_methods); while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&method)) add_method_full (acfg, method, TRUE, 0); @@ -15064,7 +15089,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) TV_GETTIME (btv); acfg->stats.jit_time = GINT64_TO_INT (TV_ELAPSED (atv, btv)); - if (acfg->dedup_collect_only) { + if (acfg->dedup_phase == DEDUP_COLLECT) { /* We only collected methods from this assembly */ acfg_free (acfg); return 0; diff --git a/src/mono/mono/mini/cpu-arm64.mdesc b/src/mono/mono/mini/cpu-arm64.mdesc index cfb6dc74e4efdd..5d582da5a1bc8e 100644 --- a/src/mono/mono/mini/cpu-arm64.mdesc +++ b/src/mono/mono/mini/cpu-arm64.mdesc @@ -467,6 +467,15 @@ arm64_cbzw: src1:i len:16 arm64_cbzx: src1:i len:16 arm64_cbnzw: src1:i len:16 arm64_cbnzx: src1:i len:16 +lzcnt32: dest:i src1:i len:4 +lzcnt64: dest:i src1:i len:4 +lscnt32: dest:i src1:i len:4 +lscnt64: dest:i src1:i len:4 +xop_i8_i8: dest:i src1:i len:4 +xop_i4_i4: dest:i src1:i len:4 +arm64_smulh: dest:i src1:i src2:i len:4 +arm64_umulh: dest:i src1:i src2:i len:4 +arm64_hint: len:4 atomic_add_i4: dest:i src1:i src2:i len:32 atomic_add_i8: dest:i src1:i src2:i len:32 @@ -515,18 +524,19 @@ extract_r4: dest:f src1:x len:4 extract_r8: dest:f src1:x len:4 arm64_xaddv: dest:x src1:x len:8 xop_ovr_x_x: dest:x src1:x len:4 +xop_ovr_x_x_x: dest:x src1:x src2:x len:4 expand_i1: dest:x src1:i len:4 expand_i2: dest:x src1:i len:4 expand_i4: dest:x src1:i len:4 expand_i8: dest:x src1:i len:4 expand_r4: dest:x src1:f len:4 expand_r8: dest:x src1:f len:4 -insert_i1: dest:x src1:i len:4 -insert_i2: dest:x src1:i len:4 -insert_i4: dest:x src1:i len:4 -insert_i8: dest:x src1:i len:4 -insert_r4: dest:x src1:f len:4 -insert_r8: dest:x src1:f len:4 +insert_i1: dest:x src1:x src2:i len:8 +insert_i2: dest:x src1:x src2:i len:8 +insert_i4: dest:x src1:x src2:i len:8 +insert_i8: dest:x src1:x src2:i len:8 +insert_r4: dest:x src1:x src2:f len:12 +insert_r8: dest:x src1:x src2:f len:12 create_scalar_int: dest:x src1:i len:8 create_scalar_float: dest:x src1:f len:12 create_scalar_unsafe_int: dest:x src1:i len:4 @@ -542,6 +552,8 @@ arm64_fcvtn2: dest:x src1:x src2:x len:4 clob:1 xunop: dest:x src1:x len:4 arm64_ushl: dest:x src1:x src2:x len:4 arm64_ext_imm: dest:x src1:x src2:x len:4 +xinsert_i8: dest:x src1:x src2:i src3:i len:20 +xinsert_r8: dest:x src1:x src2:f src3:i len:20 generic_class_init: src1:a len:44 clob:c gc_safe_point: src1:i len:12 clob:c diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 76ddf76a52cfd8..f3802f7afe5e85 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -80,6 +80,7 @@ #include #include +#include #ifdef TARGET_ARM #include @@ -8588,7 +8589,6 @@ metadata_update_prepare_to_invalidate (void) /* (2) invalidate all the registered imethods */ } - static void interp_invalidate_transformed (void) { @@ -8599,17 +8599,27 @@ interp_invalidate_transformed (void) need_stw_restart = TRUE; } - // FIXME: Enumerate all memory managers - MonoJitMemoryManager *jit_mm = get_default_jit_mm (); + GPtrArray *alcs = mono_alc_get_all (); - jit_mm_lock (jit_mm); - mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform, NULL); - jit_mm_unlock (jit_mm); + if (alcs) { + MonoAssemblyLoadContext* alc; + for (guint i = 0; i < alcs->len; ++i) { + alc = (MonoAssemblyLoadContext*)g_ptr_array_index (alcs, i); + MonoJitMemoryManager *jit_mm = (MonoJitMemoryManager*)(alc->memory_manager->runtime_info); + + jit_mm_lock (jit_mm); + mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform, NULL); + jit_mm_unlock (jit_mm); + } + + g_ptr_array_free (alcs, TRUE); + } if (need_stw_restart) mono_restart_world (MONO_THREAD_INFO_FLAGS_NO_GC); } + typedef struct { MonoJitInfo **jit_info_array; gint size; @@ -8627,27 +8637,34 @@ interp_copy_jit_info_func (gpointer imethod, gpointer user_data) static void interp_jit_info_foreach (InterpJitInfoFunc func, gpointer user_data) { - InterpCopyJitInfoFuncUserData copy_jit_info_data; - - // FIXME: Enumerate all memory managers - MonoJitMemoryManager *jit_mm = get_default_jit_mm (); + GPtrArray *alcs = mono_alc_get_all (); + + if (alcs) { + MonoAssemblyLoadContext* alc; + for (guint i = 0; i < alcs->len; ++i) { + alc = (MonoAssemblyLoadContext*)g_ptr_array_index (alcs, i); + MonoJitMemoryManager *jit_mm = (MonoJitMemoryManager*)(alc->memory_manager->runtime_info); + InterpCopyJitInfoFuncUserData copy_jit_info_data; + // Can't keep memory manager lock while iterating and calling callback since it might take other locks + // causing poential deadlock situations. Instead, create copy of interpreter imethod jinfo pointers into + // plain array and use pointers from array when when running callbacks. + copy_jit_info_data.size = mono_atomic_load_i32 (&(jit_mm->interp_code_hash.num_entries)); + copy_jit_info_data.next = 0; + copy_jit_info_data.jit_info_array = (MonoJitInfo**) g_new (MonoJitInfo*, copy_jit_info_data.size); + if (copy_jit_info_data.jit_info_array) { + jit_mm_lock (jit_mm); + mono_internal_hash_table_apply (&jit_mm->interp_code_hash, interp_copy_jit_info_func, ©_jit_info_data); + jit_mm_unlock (jit_mm); + } - // Can't keep memory manager lock while iterating and calling callback since it might take other locks - // causing poential deadlock situations. Instead, create copy of interpreter imethod jinfo pointers into - // plain array and use pointers from array when when running callbacks. - copy_jit_info_data.size = mono_atomic_load_i32 (&(jit_mm->interp_code_hash.num_entries)); - copy_jit_info_data.next = 0; - copy_jit_info_data.jit_info_array = (MonoJitInfo**) g_new (MonoJitInfo*, copy_jit_info_data.size); - if (copy_jit_info_data.jit_info_array) { - jit_mm_lock (jit_mm); - mono_internal_hash_table_apply (&jit_mm->interp_code_hash, interp_copy_jit_info_func, ©_jit_info_data); - jit_mm_unlock (jit_mm); - } - - if (copy_jit_info_data.jit_info_array) { - for (int i = 0; i < copy_jit_info_data.next; ++i) - func (copy_jit_info_data.jit_info_array [i], user_data); - g_free (copy_jit_info_data.jit_info_array); + if (copy_jit_info_data.jit_info_array) { + for (int j = 0; j < copy_jit_info_data.next; ++j) + func (copy_jit_info_data.jit_info_array [j], user_data); + g_free (copy_jit_info_data.jit_info_array); + } + } + + g_ptr_array_free (alcs, TRUE); } } diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 0d1f23b50af57f..ce237e2de102db 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -146,6 +146,7 @@ interp_insert_ins_bb (TransformData *td, InterpBasicBlock *bb, InterpInst *prev_ else new_inst->next->prev = new_inst; + new_inst->il_offset = -1; return new_inst; } @@ -10864,6 +10865,9 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, MonoG generate_code (td, method, header, generic_context, error); goto_if_nok (error, exit); + // Any newly created instructions will have undefined il_offset + td->current_il_offset = -1; + g_assert (td->inline_depth == 0); if (td->has_localloc) diff --git a/src/mono/mono/mini/ir-emit.h b/src/mono/mono/mini/ir-emit.h index 937222f568c22e..9165de198f19d8 100644 --- a/src/mono/mono/mini/ir-emit.h +++ b/src/mono/mono/mini/ir-emit.h @@ -882,6 +882,13 @@ static int ccount = 0; #define MONO_EMIT_NEW_IMPLICIT_EXCEPTION_LOAD_STORE(cfg) do { \ } while (0) +#define MONO_EMIT_EXPLICIT_NULL_CHECK(cfg, reg) do { \ + cfg->flags |= MONO_CFG_HAS_CHECK_THIS; \ + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, (reg), 0); \ + MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException"); \ + MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, reg); \ + } while (0) + /* Emit an explicit null check which doesn't depend on SIGSEGV signal handling */ #define MONO_EMIT_NULL_CHECK(cfg, reg, out_of_page) do { \ if (cfg->explicit_null_checks || (out_of_page)) { \ diff --git a/src/mono/mono/mini/llvm-intrinsics.h b/src/mono/mono/mini/llvm-intrinsics.h index df1ec108d59f0a..10932f78bc4ccf 100644 --- a/src/mono/mono/mini/llvm-intrinsics.h +++ b/src/mono/mono/mini/llvm-intrinsics.h @@ -242,16 +242,21 @@ INTRINS(AESNI_AESDECLAST, x86_aesni_aesdeclast, X86) INTRINS(AESNI_AESENC, x86_aesni_aesenc, X86) INTRINS(AESNI_AESENCLAST, x86_aesni_aesenclast, X86) INTRINS(AESNI_AESIMC, x86_aesni_aesimc, X86) -INTRINS_OVR(SSE_SADD_SATI8, sadd_sat, Generic, v128_i1_t) -INTRINS_OVR(SSE_UADD_SATI8, uadd_sat, Generic, v128_i1_t) -INTRINS_OVR(SSE_SADD_SATI16, sadd_sat, Generic, v128_i2_t) -INTRINS_OVR(SSE_UADD_SATI16, uadd_sat, Generic, v128_i2_t) INTRINS_OVR(SSE_SSUB_SATI8, ssub_sat, Generic, v128_i1_t) INTRINS_OVR(SSE_USUB_SATI8, usub_sat, Generic, v128_i1_t) INTRINS_OVR(SSE_SSUB_SATI16, ssub_sat, Generic, v128_i2_t) INTRINS_OVR(SSE_USUB_SATI16, usub_sat, Generic, v128_i2_t) #endif +#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_WASM) +INTRINS_OVR(SSE_SADD_SATI8, sadd_sat, Generic, v128_i1_t) +INTRINS_OVR(SSE_UADD_SATI8, uadd_sat, Generic, v128_i1_t) +INTRINS_OVR(SSE_SADD_SATI16, sadd_sat, Generic, v128_i2_t) +INTRINS_OVR(SSE_UADD_SATI16, uadd_sat, Generic, v128_i2_t) +#endif +#if defined(TARGET_ARM64) || defined(TARGET_WASM) +INTRINS_OVR_TAG(SIMD_POPCNT, ctpop, Generic, V64 | V128 | I1) +#endif #if defined(TARGET_WASM) INTRINS_OVR(WASM_EXTADD_PAIRWISE_SIGNED_V16, wasm_extadd_pairwise_signed, Wasm, sse_i2_t) INTRINS_OVR(WASM_EXTADD_PAIRWISE_SIGNED_V8, wasm_extadd_pairwise_signed, Wasm, sse_i4_t) @@ -265,6 +270,8 @@ INTRINS_OVR(WASM_ANYTRUE_V16, wasm_anytrue, Wasm, sse_i1_t) INTRINS_OVR(WASM_ANYTRUE_V8, wasm_anytrue, Wasm, sse_i2_t) INTRINS_OVR(WASM_ANYTRUE_V4, wasm_anytrue, Wasm, sse_i4_t) INTRINS_OVR(WASM_ANYTRUE_V2, wasm_anytrue, Wasm, sse_i8_t) +INTRINS_OVR(WASM_AVERAGE_ROUNDED_V16, wasm_avgr_unsigned, Wasm, sse_i1_t) +INTRINS_OVR(WASM_AVERAGE_ROUNDED_V8, wasm_avgr_unsigned, Wasm, sse_i2_t) INTRINS_OVR(WASM_BITMASK_V16, wasm_bitmask, Wasm, sse_i1_t) INTRINS_OVR(WASM_BITMASK_V8, wasm_bitmask, Wasm, sse_i2_t) INTRINS_OVR(WASM_BITMASK_V4, wasm_bitmask, Wasm, sse_i4_t) @@ -276,7 +283,12 @@ INTRINS_OVR_2_ARG(WASM_NARROW_SIGNED_V16, wasm_narrow_signed, Wasm, sse_i1_t, ss INTRINS_OVR_2_ARG(WASM_NARROW_SIGNED_V8, wasm_narrow_signed, Wasm, sse_i2_t, sse_i4_t) INTRINS_OVR_2_ARG(WASM_NARROW_UNSIGNED_V16, wasm_narrow_unsigned, Wasm, sse_i1_t, sse_i2_t) INTRINS_OVR_2_ARG(WASM_NARROW_UNSIGNED_V8, wasm_narrow_unsigned, Wasm, sse_i2_t, sse_i4_t) +INTRINS(WASM_Q15MULR_SAT_SIGNED, wasm_q15mulr_sat_signed, Wasm) INTRINS(WASM_SHUFFLE, wasm_shuffle, Wasm) +INTRINS_OVR(WASM_SUB_SAT_SIGNED_V16, wasm_sub_sat_signed, Wasm, sse_i1_t) +INTRINS_OVR(WASM_SUB_SAT_SIGNED_V8, wasm_sub_sat_signed, Wasm, sse_i2_t) +INTRINS_OVR(WASM_SUB_SAT_UNSIGNED_V16, wasm_sub_sat_unsigned, Wasm, sse_i1_t) +INTRINS_OVR(WASM_SUB_SAT_UNSIGNED_V8, wasm_sub_sat_unsigned, Wasm, sse_i2_t) INTRINS(WASM_SWIZZLE, wasm_swizzle, Wasm) #endif #if defined(TARGET_ARM64) @@ -306,6 +318,7 @@ INTRINS(AARCH64_SHA256SU1, aarch64_crypto_sha256su1, Arm64) INTRINS(AARCH64_SHA256H, aarch64_crypto_sha256h, Arm64) INTRINS(AARCH64_SHA256H2, aarch64_crypto_sha256h2, Arm64) INTRINS(AARCH64_PMULL64, aarch64_neon_pmull64, Arm64) +INTRINS(AARCH64_HINT, aarch64_hint, Arm64) INTRINS_OVR_TAG_KIND(AARCH64_ADV_SIMD_FACGE, aarch64_neon_facge, Arm64, Ftoi, Scalar | V64 | V128 | I4 | I8) INTRINS_OVR_TAG_KIND(AARCH64_ADV_SIMD_FACGT, aarch64_neon_facgt, Arm64, Ftoi, Scalar | V64 | V128 | I4 | I8) @@ -411,8 +424,6 @@ INTRINS_OVR(AARCH64_ADV_SIMD_PMULL, aarch64_neon_pmull, Arm64, v128_i2_t) INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FMULX, aarch64_neon_fmulx, Arm64, Scalar | V64 | V128 | R4 | R8) -INTRINS_OVR_TAG(AARCH64_ADV_SIMD_CNT, ctpop, Generic, V64 | V128 | I1) - INTRINS_OVR_TAG(AARCH64_ADV_SIMD_URECPE, aarch64_neon_urecpe, Arm64, V64 | V128 | I4) INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRECPE, aarch64_neon_frecpe, Arm64, Scalar | V64 | V128 | R4 | R8) INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRECPX, aarch64_neon_frecpx, Arm64, Scalar | R4 | R8) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index ca2d17cb66114b..9e67f9969e88da 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -2474,6 +2474,9 @@ mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass static gboolean context_used_is_mrgctx (MonoCompile *cfg, int context_used) { + if (mono_opt_experimental_gshared_mrgctx) + return context_used != 0; + /* gshared dim methods use an mrgctx */ if (mini_method_is_default_method (cfg->method)) return context_used != 0; @@ -2598,6 +2601,7 @@ get_gshared_info_slot (MonoCompile *cfg, MonoJumpInfo *patch_info, MonoRgctxInfo case MONO_PATCH_INFO_DELEGATE_INFO: case MONO_PATCH_INFO_GSHAREDVT_METHOD: case MONO_PATCH_INFO_GSHAREDVT_CALL: + case MONO_PATCH_INFO_SIGNATURE: data = (gpointer)patch_info->data.target; break; default: @@ -7973,7 +7977,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b vtable_arg = emit_get_rgctx_method (cfg, context_used, cmethod, MONO_RGCTX_INFO_METHOD_RGCTX); - if ((!(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod))) { + if ((!(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod)) && !delegate_invoke) { if (virtual_) check_this = TRUE; virtual_ = FALSE; @@ -8393,7 +8397,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b g_assert (!called_is_supported_tailcall || !tailcall || tailcall_cmethod == cmethod); g_assert (!called_is_supported_tailcall || tailcall_fsig == fsig); g_assert (!called_is_supported_tailcall || tailcall_virtual == virtual_); - g_assert (!called_is_supported_tailcall || tailcall_extra_arg == (vtable_arg || imt_arg || will_have_imt_arg || mono_class_is_interface (cmethod->klass))); + //g_assert (!called_is_supported_tailcall || tailcall_extra_arg == (vtable_arg || imt_arg || will_have_imt_arg || mono_class_is_interface (cmethod->klass))); if (common_call) // FIXME goto call_end && !common_call often skips tailcall processing. ins = mini_emit_method_call_full (cfg, cmethod, fsig, tailcall, sp, virtual_ ? sp [0] : NULL, @@ -10022,6 +10026,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b EMIT_NEW_BIALU_IMM (cfg, ptr, OP_PADD_IMM, dreg, sp [0]->dreg, foffset); store = mini_emit_storing_write_barrier (cfg, ptr, sp [1]); } else { + if (MONO_TYPE_ISSTRUCT (field->type)) + /* The decomposition might end up calling a copy/wbarrier function which doesn't do null checks */ + MONO_EMIT_EXPLICIT_NULL_CHECK (cfg, sp [0]->dreg); + EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, field->type, sp [0]->dreg, foffset, sp [1]->dreg); } } diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 938b351d3f067a..f163a76f505082 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -408,6 +408,65 @@ mono_arch_finish_init (void) { } +static gboolean +is_type_float_macro (MonoTypeEnum type) +{ + return (type == MONO_TYPE_R4 || type == MONO_TYPE_R8); +} + +static gboolean +is_type_unsigned_macro (MonoTypeEnum type) +{ + return (type == MONO_TYPE_U1 || type == MONO_TYPE_U2 || type == MONO_TYPE_U4 || type == MONO_TYPE_U8); +} + +static int +get_vector_size_macro (MonoInst *ins) +{ + g_assert (ins->klass); + int size = mono_class_value_size (ins->klass, NULL); + switch (size) { + case 16: + return VREG_FULL; + case 8: + return VREG_LOW; + default: + g_assert_not_reached (); + } +} + +static int +get_type_size_macro (MonoTypeEnum type) +{ + switch (type) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return TYPE_I8; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return TYPE_I16; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return TYPE_I32; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + return TYPE_I64; + case MONO_TYPE_I: + case MONO_TYPE_U: +#if TARGET_SIZEOF_VOID_P == 8 + return TYPE_I64; +#else + return TYPE_I32; +#endif + case MONO_TYPE_R4: + return TYPE_F32; + case MONO_TYPE_R8: + return TYPE_F64; + default: + g_assert_not_reached (); + } +} + /* The maximum length is 2 instructions */ static guint8* emit_imm (guint8 *code, int dreg, int imm) @@ -962,6 +1021,33 @@ emit_xextract_r8 (guint8* code, int dreg, int sreg1, int sreg2) return ret; } +static guint8* +emit_xinsert_i8_r8 (guint8* code, MonoTypeEnum type, int dreg, int src_reg, int repl_reg, int index_reg) +{ + guint8* ret = code; + gboolean is_float = is_type_float_macro (type); + int extra_code = 0; + + if (dreg != src_reg) { + arm_neon_mov (ret, dreg, src_reg); + extra_code = 4; + } + + arm_cbnzw (ret, index_reg, code + 12 + extra_code); + + if (is_float) { + arm_neon_ins_e (ret, TYPE_I64, dreg, repl_reg, 0, 0); + arm_b (ret, code + 16 + extra_code); + arm_neon_ins_e (ret, TYPE_I64, dreg, repl_reg, 1, 0); + } else { + arm_neon_ins_g (ret, TYPE_I64, dreg, repl_reg, 0); + arm_b (ret, code + 16 + extra_code); + arm_neon_ins_g (ret, TYPE_I64, dreg, repl_reg, 1); + } + + return ret; // max. 5 instructions generated = 20 Bytes +} + static guint8* emit_call (MonoCompile *cfg, guint8* code, MonoJumpInfoType patch_type, gconstpointer data) { @@ -1102,7 +1188,7 @@ emit_thunk (guint8 *code, gconstpointer target) } static gpointer -create_thunk (MonoCompile *cfg, guchar *code, const guchar *target) +create_thunk (MonoCompile *cfg, guchar *code, const guchar *target, int relocation) { MonoJitInfo *ji; MonoThunkJitInfo *info; @@ -1174,7 +1260,7 @@ create_thunk (MonoCompile *cfg, guchar *code, const guchar *target) if (!target_thunk) { jit_mm_unlock (jit_mm); - g_print ("thunk failed %p->%p, thunk space=%d method %s", code, target, thunks_size, cfg ? mono_method_full_name (cfg->method, TRUE) : mono_method_full_name (jinfo_get_method (ji), TRUE)); + g_print ("thunk failed %p->%p, thunk space=%d method %s, relocation %d", code, target, thunks_size, cfg ? mono_method_full_name (cfg->method, TRUE) : mono_method_full_name (jinfo_get_method (ji), TRUE), relocation); g_assert_not_reached (); } @@ -1197,7 +1283,7 @@ arm_patch_full (MonoCompile *cfg, guint8 *code, guint8 *target, int relocation) } else { gpointer thunk; - thunk = create_thunk (cfg, code, target); + thunk = create_thunk (cfg, code, target, relocation); g_assert (arm_is_bl_disp (code, thunk)); arm_b (code, thunk); } @@ -1231,7 +1317,7 @@ arm_patch_full (MonoCompile *cfg, guint8 *code, guint8 *target, int relocation) } else { gpointer thunk; - thunk = create_thunk (cfg, code, target); + thunk = create_thunk (cfg, code, target, relocation); g_assert (arm_is_bl_disp (code, thunk)); arm_bl (code, thunk); } @@ -3496,72 +3582,13 @@ emit_branch_island (MonoCompile *cfg, guint8 *code, int start_offset) return code; } -static gboolean -is_type_float_macro (MonoTypeEnum type) -{ - return (type == MONO_TYPE_R4 || type == MONO_TYPE_R8); -} - -static gboolean -is_type_unsigned_macro (MonoTypeEnum type) -{ - return (type == MONO_TYPE_U1 || type == MONO_TYPE_U2 || type == MONO_TYPE_U4 || type == MONO_TYPE_U8); -} - -static int -get_vector_size_macro (MonoInst *ins) -{ - g_assert (ins->klass); - int size = mono_class_value_size (ins->klass, NULL); - switch (size) { - case 16: - return VREG_FULL; - case 8: - return VREG_LOW; - default: - g_assert_not_reached (); - } -} - -static int -get_type_size_macro (MonoTypeEnum type) -{ - switch (type) { - case MONO_TYPE_I1: - case MONO_TYPE_U1: - return TYPE_I8; - case MONO_TYPE_I2: - case MONO_TYPE_U2: - return TYPE_I16; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - return TYPE_I32; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - return TYPE_I64; - case MONO_TYPE_I: - case MONO_TYPE_U: -#if TARGET_SIZEOF_VOID_P == 8 - return TYPE_I64; -#else - return TYPE_I32; -#endif - case MONO_TYPE_R4: - return TYPE_F32; - case MONO_TYPE_R8: - return TYPE_F64; - default: - g_assert_not_reached (); - } -} - void mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) { MonoInst *ins; MonoCallInst *call; guint8 *code = cfg->native_code + cfg->code_len; - int start_offset, max_len, dreg, sreg1, sreg2; + int start_offset, max_len, dreg, sreg1, sreg2, sreg3; target_mgreg_t imm; if (cfg->verbose_level > 2) @@ -3588,6 +3615,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) dreg = ins->dreg; sreg1 = ins->sreg1; sreg2 = ins->sreg2; + sreg3 = ins->sreg3; imm = ins->inst_imm; if (opcode_simd_status [ins->opcode - OP_START] == OPCODE_SIMD) @@ -3795,6 +3823,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) g_assert_not_reached (); } break; + case OP_XOP_OVR_X_X_X: { + IntrinsicId iid = (IntrinsicId) ins->inst_c0; + switch (iid) { + case INTRINS_AARCH64_ADV_SIMD_TBL1: + arm_neon_tbl1_16b (code, dreg, sreg1, sreg2); + break; + default: + g_assert_not_reached (); + break; + } + break; + } case OP_XZERO: arm_neon_eor_16b (code, dreg, dreg, dreg); break; @@ -3869,7 +3909,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_XEXTRACT_I8: code = emit_xextract_i8 (code, dreg, sreg1, sreg2); break; - case OP_XEXTRACT_R8: code = emit_xextract_r8 (code, dreg, sreg1, sreg2); break; @@ -3881,12 +3920,28 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) g_assert_not_reached (); break; + case OP_XINSERT_I1: + case OP_XINSERT_I2: + case OP_XINSERT_I4: + case OP_XINSERT_R4: + g_assert_not_reached(); + break; + case OP_XINSERT_I8: + code = emit_xinsert_i8_r8 (code, MONO_TYPE_I8, dreg, sreg1, sreg2, sreg3); + break; + case OP_XINSERT_R8: + code = emit_xinsert_i8_r8 (code, MONO_TYPE_R8, dreg, sreg1, sreg2, sreg3); + break; + case OP_INSERT_I1: case OP_INSERT_I2: case OP_INSERT_I4: case OP_INSERT_I8: { const int t = get_type_size_macro (ins->inst_c1); - arm_neon_ins_g(code, t, dreg, sreg1, ins->inst_c0); + if (dreg != sreg1) + arm_neon_mov (code, dreg, sreg1); + + arm_neon_ins_g(code, t, dreg, sreg2, ins->inst_c0); break; } case OP_INSERT_R4: @@ -3900,7 +3955,20 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) t = SIZE_8; break; } - arm_neon_ins_e(code, t, dreg, sreg1, ins->inst_c0, 0); + + if (dreg != sreg1) { + if (dreg != sreg2) { + arm_neon_mov (code, dreg, sreg1); + arm_neon_ins_e(code, t, dreg, sreg2, ins->inst_c0, 0); + } else { + arm_neon_mov (code, NEON_TMP_REG, sreg1); + arm_neon_ins_e(code, t, NEON_TMP_REG, sreg2, ins->inst_c0, 0); + arm_neon_mov (code, dreg, NEON_TMP_REG); + } + } else { + g_assert (dreg != sreg2); + arm_neon_ins_e(code, t, dreg, sreg2, ins->inst_c0, 0); + } break; } case OP_ARM64_XTN: @@ -3994,7 +4062,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } break; } - // Enable this when adding support for Narrow and enable support for Create at the same time + // This requires Vector64 SIMD support // case OP_XCONCAT: // arm_neon_ext_16b(code, dreg, sreg1, sreg2, 8); // break; @@ -5281,6 +5349,46 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) arm_strx (code, i, ins->sreg1, MONO_STRUCT_OFFSET (MonoContext, regs) + i * sizeof (target_mgreg_t)); break; + /**** Arm.ArmBase ****/ + case OP_LZCNT32: + arm_clzw (code, dreg, sreg1); + break; + + case OP_LSCNT32: + arm_clsw (code, dreg, sreg1); + break; + + case OP_LZCNT64: + arm_clzx (code, dreg, sreg1); + break; + + case OP_LSCNT64: + arm_clsx (code, dreg, sreg1); + break; + + case OP_ARM64_SMULH: + arm_smulh (code, dreg, sreg1, sreg2); + break; + + case OP_ARM64_UMULH: + arm_umulh (code, dreg, sreg1, sreg2); + break; + + case OP_XOP_I8_I8: + g_assert (ins->inst_c0 == INTRINS_BITREVERSE_I64); + arm_rbitx (code, dreg, sreg1); + break; + + case OP_XOP_I4_I4: + g_assert (ins->inst_c0 == INTRINS_BITREVERSE_I32); + arm_rbitw (code, dreg, sreg1); + break; + + case OP_ARM64_HINT: + g_assert (ins->inst_c0 <= ARMHINT_SEVL); + arm_hint (code, ins->inst_c0); + break; + default: g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__); g_assert_not_reached (); diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 54ea2a8e147d8b..cfb7d4358c8ca3 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -2956,6 +2956,8 @@ mini_rgctx_info_type_to_patch_info_type (MonoRgctxInfoType info_type) case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE: case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT: return MONO_PATCH_INFO_GSHAREDVT_CALL; + case MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI: + return MONO_PATCH_INFO_SIGNATURE; default: printf ("%d\n", info_type); g_assert_not_reached (); @@ -3726,6 +3728,9 @@ mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_v if (!mono_method_is_generic_sharable (method, allow_type_vars)) return FALSE; + if (mono_opt_experimental_gshared_mrgctx) + return method->is_inflated; + if (method->is_inflated && mono_method_get_context (method)->method_inst) return TRUE; @@ -4081,7 +4086,11 @@ mini_method_needs_mrgctx (MonoMethod *m) return TRUE; if (m->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (m->klass)) return TRUE; - return (mini_method_get_context (m) && mini_method_get_context (m)->method_inst); + + if (mono_opt_experimental_gshared_mrgctx) + return mini_method_get_context (m) != NULL; + else + return (mini_method_get_context (m) && mini_method_get_context (m)->method_inst); } /* diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index d4e3e3754966b4..e2e9e2dd78d540 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -4756,7 +4756,8 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, mono_llvm_add_instr_byval_attr (lcall, 1 + ainfo->pindex, LLVMGetElementType (param_types [ainfo->pindex])); } - gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (sig->ret)); + MonoClass *retclass = mono_class_from_mono_type_internal (sig->ret); + gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, retclass); gboolean should_promote_to_value = FALSE; const char *load_name = NULL; /* @@ -4821,11 +4822,17 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, case LLVMArgGsharedvtFixedVtype: values [ins->dreg] = LLVMBuildLoad2 (builder, rtype, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (rtype), FALSE), ""); break; - case LLVMArgWasmVtypeAsScalar: + case LLVMArgWasmVtypeAsScalar: { + /* + * If the vtype contains references, making the store volatile ensures there is a reference + * on the stack. + */ + gboolean is_volatile = m_class_has_references (retclass); if (!addresses [call->inst.dreg]) addresses [call->inst.dreg] = build_alloca_address (ctx, sig->ret); - LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (LLVMTypeOf (lcall)), FALSE)); + emit_store (builder, lcall, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (LLVMTypeOf (lcall)), FALSE), is_volatile); break; + } default: if (sig->ret->type != MONO_TYPE_VOID) /* If the method returns an unsigned value, need to zext it */ @@ -5827,6 +5834,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) case OP_NOT_NULL: case OP_LIVERANGE_START: case OP_LIVERANGE_END: + case OP_TAILCALL_PARAMETER: break; case OP_ICONST: values [ins->dreg] = const_int32 (ins->inst_c0); @@ -7774,6 +7782,12 @@ MONO_RESTORE_WARNING values [ins->dreg] = result; break; } + case OP_XOP_OVR_X_X: { + IntrinsicId iid = (IntrinsicId) ins->inst_c0; + llvm_ovr_tag_t ovr_tag = ovr_tag_from_mono_vector_class (ins->klass); + values [ins->dreg] = call_overloaded_intrins (ctx, iid, ovr_tag, &lhs, ""); + break; + } #endif #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_WASM) case OP_EXTRACTX_U2: @@ -10257,6 +10271,13 @@ MONO_RESTORE_WARNING values [ins->dreg] = LLVMBuildSExt (builder, result, ret_t, ""); break; } + case OP_ARM64_HINT: { + g_assert (ins->inst_c0 <= ARMHINT_SEVL); + LLVMValueRef hintid = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE); + LLVMValueRef args [] = { hintid }; + call_intrins (ctx, INTRINS_AARCH64_HINT, args, ""); + break; + } case OP_ARM64_EXT: { LLVMTypeRef ret_t = LLVMTypeOf (lhs); unsigned int elems = LLVMGetVectorSize (ret_t); @@ -11452,12 +11473,6 @@ MONO_RESTORE_WARNING values [ins->dreg] = call_overloaded_intrins (ctx, iid, ovr_tag, args, ""); break; } - case OP_XOP_OVR_X_X: { - IntrinsicId iid = (IntrinsicId) ins->inst_c0; - llvm_ovr_tag_t ovr_tag = ovr_tag_from_mono_vector_class (ins->klass); - values [ins->dreg] = call_overloaded_intrins (ctx, iid, ovr_tag, &lhs, ""); - break; - } case OP_XOP_OVR_X_X_X: { IntrinsicId iid = (IntrinsicId) ins->inst_c0; llvm_ovr_tag_t ovr_tag = ovr_tag_from_mono_vector_class (ins->klass); @@ -11734,13 +11749,20 @@ MONO_RESTORE_WARNING } case OP_IL_SEQ_POINT: break; - default: { + case OP_ARGLIST: + case OP_TAILCALL: + case OP_TAILCALL_REG: + case OP_TAILCALL_MEMBASE: + case OP_CKFINITE: { char reason [128]; sprintf (reason, "opcode %s", mono_inst_name (ins->opcode)); set_failure (ctx, reason); break; } + default: + g_error ("opcode %d %s", ins->opcode, mono_inst_name (ins->opcode)); + break; } if (!ctx_ok (ctx)) diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h index 29c6809e243357..00f382b4148d94 100644 --- a/src/mono/mono/mini/mini-ops.h +++ b/src/mono/mono/mini/mini-ops.h @@ -1465,6 +1465,7 @@ MINI_OP(OP_ARM64_CBZX, "arm64_cbzx", NONE, IREG, NONE) /* Branch if sreg1 != 0 */ MINI_OP(OP_ARM64_CBNZW, "arm64_cbnzw", NONE, IREG, NONE) MINI_OP(OP_ARM64_CBNZX, "arm64_cbnzx", NONE, IREG, NONE) +MINI_OP(OP_ARM64_HINT, "arm64_hint", NONE, NONE, NONE) #endif /* Same as OUTARG_VT, but has a dreg */ diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 18a237024c7515..cc2069539ac635 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -2817,11 +2817,11 @@ mono_jit_compile_method_jit_only (MonoMethod *method, MonoError *error) * On llvmonly, this returns a MonoFtnDesc, otherwise it returns a normal function pointer. */ static gpointer -get_ftnptr_for_method (MonoMethod *method, MonoError *error) +get_ftnptr_for_method (MonoMethod *method, gboolean need_unbox, MonoError *error) { if (!mono_llvm_only) { gpointer res = mono_jit_compile_method (method, error); - res = mini_add_method_trampoline (method, res, mono_method_needs_static_rgctx_invoke (method, TRUE), FALSE); + res = mini_add_method_trampoline (method, res, mono_method_needs_static_rgctx_invoke (method, TRUE), need_unbox); return res; } else { return mini_llvmonly_load_method_ftndesc (method, FALSE, FALSE, error); diff --git a/src/mono/mono/mini/mini-windows.c b/src/mono/mono/mini/mini-windows.c index c678f4c4594c45..f5d81c537a6910 100644 --- a/src/mono/mono/mini/mini-windows.c +++ b/src/mono/mono/mini/mini-windows.c @@ -283,7 +283,9 @@ thread_timer_expired (HANDLE thread) if (GetThreadContext (thread, &context)) { guchar *ip; -#ifdef _WIN64 +#ifdef _ARM64_ + ip = (guchar *) context.Pc; +#elif _WIN64 ip = (guchar *) context.Rip; #else ip = (guchar *) context.Eip; diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index 497ed8365eca6c..89f6ebdb46701d 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -3051,7 +3051,10 @@ mini_get_rgctx_access_for_method (MonoMethod *method) if (method->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (method->klass)) return MONO_RGCTX_ACCESS_MRGCTX; - return MONO_RGCTX_ACCESS_THIS; + if (mono_opt_experimental_gshared_mrgctx) + return MONO_RGCTX_ACCESS_MRGCTX; + else + return MONO_RGCTX_ACCESS_THIS; } /* diff --git a/src/mono/mono/mini/simd-arm64.h b/src/mono/mono/mini/simd-arm64.h index b9c0b7507236fa..9bd2c31cb7dd79 100644 --- a/src/mono/mono/mini/simd-arm64.h +++ b/src/mono/mono/mini/simd-arm64.h @@ -55,6 +55,10 @@ SIMD_OP (128, OP_XUNOP, OP_ARM64_SXTL, TDS, arm_neo SIMD_OP (128, OP_XUNOP, OP_ARM64_SXTL2, TDS, arm_neon_sxtl2, arm_neon_sxtl2, arm_neon_sxtl2, _UNDEF, _UNDEF, _UNDEF) SIMD_OP (128, OP_XUNOP, OP_ARM64_UXTL, TDS, arm_neon_uxtl, arm_neon_uxtl, arm_neon_uxtl, _UNDEF, _UNDEF, _UNDEF) SIMD_OP (128, OP_XUNOP, OP_ARM64_UXTL2, TDS, arm_neon_uxtl2, arm_neon_uxtl2, arm_neon_uxtl2, _UNDEF, _UNDEF, _UNDEF) +SIMD_OP (128, OP_XUNOP, OP_CVT_FP_SI, WTDS, _UNDEF, _UNDEF, arm_neon_fcvtzs, arm_neon_fcvtzs, _UNDEF, _UNDEF) +SIMD_OP (128, OP_XUNOP, OP_CVT_FP_UI, WTDS, _UNDEF, _UNDEF, arm_neon_fcvtzu, arm_neon_fcvtzu, _UNDEF, _UNDEF) +SIMD_OP (128, OP_XUNOP, OP_CVT_SI_FP, WTDS, _UNDEF, _UNDEF, _UNDEF, _UNDEF, arm_neon_scvtf, arm_neon_scvtf) +SIMD_OP (128, OP_XUNOP, OP_CVT_UI_FP, WTDS, _UNDEF, _UNDEF, _UNDEF, _UNDEF, arm_neon_ucvtf, arm_neon_ucvtf) SIMD_OP (128, OP_XBINOP, OP_IADD, WTDSS, arm_neon_add, arm_neon_add, arm_neon_add, arm_neon_add, _UNDEF, _UNDEF) SIMD_OP (128, OP_XBINOP, OP_FADD, WTDSS, _UNDEF, _UNDEF, _UNDEF, _UNDEF, arm_neon_fadd, arm_neon_fadd) SIMD_OP (128, OP_XBINOP, OP_ISUB, WTDSS, arm_neon_sub, arm_neon_sub, arm_neon_sub, arm_neon_sub, _UNDEF, _UNDEF) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 6e6afa17eb34ef..ac74b87dbc4a3a 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -1326,6 +1326,7 @@ emit_msb_shift_vector_constant (MonoCompile *cfg, MonoClass *arg_class, MonoType return msb_shift_vec; } +/* Emit intrinsics in System.Numerics.Vector and System.Runtime.Intrinsics.Vector64/128/256/512 */ static MonoInst* emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) { @@ -1340,28 +1341,31 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; } - if (!strcmp (m_class_get_name (cmethod->klass), "Vector256") || !strcmp (m_class_get_name (cmethod->klass), "Vector512")) + int vector_size; + if (!strcmp (m_class_get_name (cmethod->klass), "Vector64")) + vector_size = 64; + else if (!strcmp (m_class_get_name (cmethod->klass), "Vector128")) + vector_size = 128; + else if (!strcmp (m_class_get_name (cmethod->klass), "Vector256")) + vector_size = 256; + else if (!strcmp (m_class_get_name (cmethod->klass), "Vector512")) + vector_size = 512; + else if (!strcmp (m_class_get_name (cmethod->klass), "Vector")) + vector_size = register_size * 8; + else + return NULL; + + if (vector_size == 256 || vector_size == 512) return NULL; // FIXME: This limitation could be removed once everything here are supported by mini JIT on arm64 #ifdef TARGET_ARM64 if (!COMPILE_LLVM (cfg)) { - if (!(!strcmp (m_class_get_name (cmethod->klass), "Vector128") || !strcmp (m_class_get_name (cmethod->klass), "Vector"))) + if (vector_size != 128) return NULL; switch (id) { - case SN_ConvertToDouble: - case SN_ConvertToInt32: - case SN_ConvertToInt64: - case SN_ConvertToSingle: - case SN_ConvertToUInt32: - case SN_ConvertToUInt64: - case SN_Create: case SN_GetLower: case SN_GetUpper: - case SN_Shuffle: - case SN_ToVector128: - case SN_ToVector128Unsafe: - case SN_WithElement: return NULL; default: break; @@ -1485,9 +1489,16 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_ConvertToDouble: { -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) if ((arg0_type != MONO_TYPE_I8) && (arg0_type != MONO_TYPE_U8)) return NULL; +#if defined(TARGET_ARM64) + if (!COMPILE_LLVM (cfg)) { + return emit_simd_ins_for_sig (cfg, klass, OP_XUNOP, + arg0_type == MONO_TYPE_I8 ? OP_CVT_SI_FP : OP_CVT_UI_FP, + MONO_TYPE_R8, fsig, args); + } +#endif +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); int size = mono_class_value_size (arg_class, NULL); int op = -1; @@ -1502,9 +1513,17 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_ConvertToInt32: case SN_ConvertToUInt32: { -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) if (arg0_type != MONO_TYPE_R4) return NULL; +#if defined(TARGET_ARM64) + if (!COMPILE_LLVM (cfg)) { + return emit_simd_ins_for_sig (cfg, klass, OP_XUNOP, + id == SN_ConvertToInt32 ? OP_CVT_FP_SI : OP_CVT_FP_UI, + id == SN_ConvertToInt32 ? MONO_TYPE_I4 : MONO_TYPE_U4, + fsig, args); + } +#endif +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) int op = id == SN_ConvertToInt32 ? OP_CVT_FP_SI : OP_CVT_FP_UI; return emit_simd_ins_for_sig (cfg, klass, op, -1, arg0_type, fsig, args); #else @@ -1513,9 +1532,17 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_ConvertToInt64: case SN_ConvertToUInt64: { -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) if (arg0_type != MONO_TYPE_R8) return NULL; +#if defined(TARGET_ARM64) + if (!COMPILE_LLVM (cfg)) { + return emit_simd_ins_for_sig (cfg, klass, OP_XUNOP, + id == SN_ConvertToInt64 ? OP_CVT_FP_SI : OP_CVT_FP_UI, + id == SN_ConvertToInt64 ? MONO_TYPE_I8 : MONO_TYPE_U8, + fsig, args); + } +#endif +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); int size = mono_class_value_size (arg_class, NULL); int op = -1; @@ -1529,9 +1556,16 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_ConvertToSingle: { -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) if ((arg0_type != MONO_TYPE_I4) && (arg0_type != MONO_TYPE_U4)) return NULL; +#if defined(TARGET_ARM64) + if (!COMPILE_LLVM (cfg)) { + return emit_simd_ins_for_sig (cfg, klass, OP_XUNOP, + arg0_type == MONO_TYPE_I4 ? OP_CVT_SI_FP : OP_CVT_UI_FP, + MONO_TYPE_R4, fsig, args); + } +#endif +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) int op = arg0_type == MONO_TYPE_I4 ? OP_CVT_SI_FP : OP_CVT_UI_FP; return emit_simd_ins_for_sig (cfg, klass, op, -1, arg0_type, fsig, args); #else @@ -1546,8 +1580,14 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi MonoInst* ins = emit_simd_ins (cfg, klass, type_to_expand_op (etype->type), args [0]->dreg, -1); ins->inst_c1 = arg0_type; return ins; - } else if (is_create_from_half_vectors_overload (fsig)) + } else if (is_create_from_half_vectors_overload (fsig)) { +#if defined(TARGET_ARM64) + // Require Vector64 SIMD support + if (!COMPILE_LLVM (cfg)) + return NULL; +#endif return emit_simd_ins (cfg, klass, OP_XCONCAT, args [0]->dreg, args [1]->dreg); + } else if (is_elementwise_create_overload (fsig, etype)) return emit_vector_create_elementwise (cfg, fsig, fsig->ret, arg0_type, args); break; @@ -1981,6 +2021,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; #ifdef TARGET_WASM return emit_simd_ins_for_sig (cfg, klass, OP_WASM_SIMD_SWIZZLE, -1, -1, fsig, args); +#elif defined(TARGET_ARM64) + if (vector_size == 128 && (arg0_type == MONO_TYPE_I1 || arg0_type == MONO_TYPE_U1)) + return emit_simd_ins_for_sig (cfg, klass, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_TBL1, 0, fsig, args); + return NULL; #else return NULL; #endif @@ -2043,13 +2087,61 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi elems = 4; } + if (args [1]->opcode == OP_ICONST) { + // If the index is provably a constant, we can generate vastly better code. + int index = args[1]->inst_c0; + + if (index < 0 || index >= elems) { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [1]->dreg, elems); + MONO_EMIT_NEW_COND_EXC (cfg, GE_UN, "ArgumentOutOfRangeException"); + } + + int insert_op = type_to_insert_op (arg0_type); + MonoInst *ins = emit_simd_ins (cfg, klass, insert_op, args [0]->dreg, args [2]->dreg); + ins->inst_c0 = index; + ins->inst_c1 = arg0_type; + return ins; + } + + if (!COMPILE_LLVM(cfg) && fsig->params [0]->type != MONO_TYPE_GENERICINST) { + return NULL; + } + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [1]->dreg, elems); MONO_EMIT_NEW_COND_EXC (cfg, GE_UN, "ArgumentOutOfRangeException"); - int insert_op = type_to_xinsert_op (arg0_type); - MonoInst *ins = emit_simd_ins (cfg, klass, insert_op, args [0]->dreg, args [2]->dreg); - ins->sreg3 = args [1]->dreg; - ins->inst_c1 = arg0_type; - return ins; + + if (COMPILE_LLVM(cfg) || type_to_width_log2 (arg0_type) == 3) { + int insert_op = type_to_xinsert_op (arg0_type); + MonoInst *ins = emit_simd_ins (cfg, klass, insert_op, args [0]->dreg, args [2]->dreg); + ins->sreg3 = args [1]->dreg; + ins->inst_c1 = arg0_type; + return ins; + } else { + // Create a blank reg and spill it. + // Overwrite memory with original value. + // Overwrite [spilled + index << elem_size_log2] with replacement value + // Read back. + // TODO: on x86, use a LEA + MonoInst* scratch = emit_xzero (cfg, args [0]->klass); + MonoInst* scratcha; + NEW_VARLOADA_VREG (cfg, scratcha, scratch->dreg, fsig->params [0]); + MONO_ADD_INS (cfg->cbb, scratcha); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, mono_type_to_store_membase (cfg, fsig->params [0]), scratcha->dreg, 0, args [0]->dreg); + + int offset_reg = alloc_lreg (cfg); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SHL_IMM, offset_reg, args [1]->dreg, type_to_width_log2 (arg0_type)); + int addr_reg = alloc_preg (cfg); + MONO_EMIT_NEW_BIALU(cfg, OP_PADD, addr_reg, scratcha->dreg, offset_reg); + + MONO_EMIT_NEW_STORE_MEMBASE (cfg, mono_type_to_store_membase (cfg, fsig->params [2]), addr_reg, 0, args [2]->dreg); + + MonoInst* ret; + NEW_LOAD_MEMBASE (cfg, ret, mono_type_to_load_membase (cfg, fsig->ret), scratch->dreg, scratcha->dreg, 0); + MONO_ADD_INS (cfg->cbb, ret); + + return ret; + } + break; } case SN_WidenLower: case SN_WidenUpper: { @@ -3046,6 +3138,7 @@ static SimdIntrinsic armbase_methods [] = { {SN_LeadingZeroCount}, {SN_MultiplyHigh}, {SN_ReverseElementBits}, + {SN_Yield}, {SN_get_IsSupported}, }; @@ -3335,7 +3428,7 @@ static SimdIntrinsic advsimd_methods [] = { {SN_PolynomialMultiply, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_PMUL}, {SN_PolynomialMultiplyWideningLower, OP_ARM64_PMULL}, {SN_PolynomialMultiplyWideningUpper, OP_ARM64_PMULL2}, - {SN_PopCount, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_CNT}, + {SN_PopCount, OP_XOP_OVR_X_X, INTRINS_SIMD_POPCNT}, {SN_ReciprocalEstimate, None, None, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_URECPE, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FRECPE}, {SN_ReciprocalEstimateScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_AARCH64_ADV_SIMD_FRECPE}, {SN_ReciprocalExponentScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_AARCH64_ADV_SIMD_FRECPX}, @@ -3489,7 +3582,7 @@ static const SimdIntrinsic dp_methods [] = { static const IntrinGroup supported_arm_intrinsics [] = { { "AdvSimd", MONO_CPU_ARM64_NEON, advsimd_methods, sizeof (advsimd_methods) }, { "Aes", MONO_CPU_ARM64_CRYPTO, crypto_aes_methods, sizeof (crypto_aes_methods) }, - { "ArmBase", MONO_CPU_ARM64_BASE, armbase_methods, sizeof (armbase_methods) }, + { "ArmBase", MONO_CPU_ARM64_BASE, armbase_methods, sizeof (armbase_methods), TRUE }, { "Crc32", MONO_CPU_ARM64_CRC, crc32_methods, sizeof (crc32_methods) }, { "Dp", MONO_CPU_ARM64_DP, dp_methods, sizeof (dp_methods) }, { "Rdm", MONO_CPU_ARM64_RDM, rdm_methods, sizeof (rdm_methods) }, @@ -3525,6 +3618,14 @@ emit_arm64_intrinsics ( (is_64bit ? OP_XOP_I8_I8 : OP_XOP_I4_I4), (is_64bit ? INTRINS_BITREVERSE_I64 : INTRINS_BITREVERSE_I32), arg0_type, fsig, args); + case SN_Yield: { + MonoInst* ins; + MONO_INST_NEW (cfg, ins, OP_ARM64_HINT); + ins->inst_c0 = ARMHINT_YIELD; + MONO_ADD_INS (cfg->cbb, ins); + return ins; + } + default: g_assert_not_reached (); // if a new API is added we need to either implement it or change IsSupported to false } @@ -4961,20 +5062,37 @@ static SimdIntrinsic wasmbase_methods [] = { }; static SimdIntrinsic packedsimd_methods [] = { + {SN_Abs, OP_VECTOR_IABS}, {SN_Add}, {SN_AddPairwiseWidening}, + {SN_AddSaturate}, + {SN_AllTrue}, {SN_And, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_AND}, + {SN_AndNot}, + {SN_AnyTrue}, + {SN_AverageRounded}, {SN_Bitmask, OP_WASM_SIMD_BITMASK}, - {SN_CompareEqual}, - {SN_CompareNotEqual}, + {SN_BitwiseSelect, OP_BSL}, + {SN_CompareEqual, OP_XCOMPARE, CMP_EQ, OP_XCOMPARE, CMP_EQ, OP_XCOMPARE_FP, CMP_EQ}, + {SN_CompareGreaterThan, OP_XCOMPARE, CMP_GT, OP_XCOMPARE, CMP_GT_UN, OP_XCOMPARE_FP, CMP_GT}, + {SN_CompareGreaterThanOrEqual, OP_XCOMPARE, CMP_GE, OP_XCOMPARE, CMP_GE_UN, OP_XCOMPARE_FP, CMP_GE}, + {SN_CompareLessThan, OP_XCOMPARE, CMP_LT, OP_XCOMPARE, CMP_LT_UN, OP_XCOMPARE_FP, CMP_LT}, + {SN_CompareLessThanOrEqual, OP_XCOMPARE, CMP_LE, OP_XCOMPARE, CMP_LE_UN, OP_XCOMPARE_FP, CMP_LE}, + {SN_CompareNotEqual, OP_XCOMPARE, CMP_NE, OP_XCOMPARE, CMP_NE, OP_XCOMPARE_FP, CMP_NE}, {SN_ConvertNarrowingSignedSaturate}, {SN_ConvertNarrowingUnsignedSaturate}, {SN_Dot, OP_XOP_X_X_X, INTRINS_WASM_DOT}, {SN_ExtractLane}, + {SN_Max, OP_XBINOP, OP_IMIN, OP_XBINOP, OP_IMIN_UN}, + {SN_Min, OP_XBINOP, OP_IMAX, OP_XBINOP, OP_IMAX_UN}, {SN_Multiply}, + {SN_MultiplyRoundedSaturateQ15, OP_XOP_X_X_X, INTRINS_WASM_Q15MULR_SAT_SIGNED}, {SN_MultiplyWideningLower, OP_WASM_EXTMUL_LOWER, 0, OP_WASM_EXTMUL_LOWER_U}, {SN_MultiplyWideningUpper, OP_WASM_EXTMUL_UPPER, 0, OP_WASM_EXTMUL_UPPER_U}, {SN_Negate}, + {SN_Not, OP_WASM_ONESCOMPLEMENT}, + {SN_Or, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_OR}, + {SN_PopCount, OP_XOP_OVR_X_X, INTRINS_SIMD_POPCNT}, {SN_ReplaceLane}, {SN_ShiftLeft, OP_SIMD_SHL}, {SN_ShiftRightArithmetic, OP_SIMD_SSHR}, @@ -4982,7 +5100,9 @@ static SimdIntrinsic packedsimd_methods [] = { {SN_Shuffle, OP_WASM_SIMD_SHUFFLE}, {SN_Splat}, {SN_Subtract}, + {SN_SubtractSaturate}, {SN_Swizzle, OP_WASM_SIMD_SWIZZLE}, + {SN_Xor, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_XOR}, {SN_get_IsSupported}, }; @@ -5064,6 +5184,72 @@ emit_wasm_supported_intrinsics ( return emit_simd_ins_for_binary_op (cfg, klass, fsig, args, arg0_type, id); case SN_Negate: return emit_simd_ins_for_unary_op (cfg, klass, fsig, args, arg0_type, id); + case SN_AndNot: { + /* Swap lhs and rhs because Vector128 needs lhs & !rhs + whereas SSE2 does !lhs & rhs */ + MonoInst *tmp = args[0]; + args[0] = args[1]; + args[1] = tmp; + op = OP_VECTOR_ANDN; + // continue with default emit + break; + } + case SN_AnyTrue: { + op = OP_XOP_X_X; + + switch (arg0_type) { + case MONO_TYPE_U1: + case MONO_TYPE_I1: + c0 = INTRINS_WASM_ANYTRUE_V16; + break; + case MONO_TYPE_U2: + case MONO_TYPE_I2: + c0 = INTRINS_WASM_ANYTRUE_V8; + break; + case MONO_TYPE_U4: + case MONO_TYPE_I4: + c0 = INTRINS_WASM_ANYTRUE_V4; + break; + case MONO_TYPE_U8: + case MONO_TYPE_I8: + c0 = INTRINS_WASM_ANYTRUE_V2; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } + case SN_AllTrue: { + op = OP_XOP_X_X; + + switch (arg0_type) { + case MONO_TYPE_U1: + case MONO_TYPE_I1: + c0 = INTRINS_WASM_ALLTRUE_V16; + break; + case MONO_TYPE_U2: + case MONO_TYPE_I2: + c0 = INTRINS_WASM_ALLTRUE_V8; + break; + case MONO_TYPE_U4: + case MONO_TYPE_I4: + c0 = INTRINS_WASM_ALLTRUE_V4; + break; + case MONO_TYPE_U8: + case MONO_TYPE_I8: + c0 = INTRINS_WASM_ALLTRUE_V2; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } case SN_AddPairwiseWidening: { op = OP_XOP_X_X; @@ -5088,6 +5274,48 @@ emit_wasm_supported_intrinsics ( return NULL; } + case SN_AddSaturate: { + op = OP_XOP_X_X_X; + + switch (arg0_type) { + case MONO_TYPE_I1: + c0 = INTRINS_SSE_SADD_SATI8; + break; + case MONO_TYPE_I2: + c0 = INTRINS_SSE_SADD_SATI16; + break; + case MONO_TYPE_U1: + c0 = INTRINS_SSE_UADD_SATI8; + break; + case MONO_TYPE_U2: + c0 = INTRINS_SSE_UADD_SATI16; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } + case SN_AverageRounded: { + op = OP_XOP_X_X_X; + + switch (arg0_type) { + case MONO_TYPE_U1: + c0 = INTRINS_WASM_AVERAGE_ROUNDED_V16; + break; + case MONO_TYPE_U2: + c0 = INTRINS_WASM_AVERAGE_ROUNDED_V8; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } case SN_CompareEqual: return emit_simd_ins_for_sig (cfg, klass, type_enum_is_float (arg0_type) ? OP_XCOMPARE_FP : OP_XCOMPARE, CMP_EQ, arg0_type, fsig, args); case SN_CompareNotEqual: @@ -5144,6 +5372,30 @@ emit_wasm_supported_intrinsics ( g_assert (fsig->param_count == 1 && mono_metadata_type_equal (fsig->params [0], etype)); return emit_simd_ins (cfg, klass, type_to_expand_op (etype->type), args [0]->dreg, -1); } + case SN_SubtractSaturate: { + op = OP_XOP_X_X_X; + + switch (arg0_type) { + case MONO_TYPE_I1: + c0 = INTRINS_WASM_SUB_SAT_SIGNED_V16; + break; + case MONO_TYPE_I2: + c0 = INTRINS_WASM_SUB_SAT_SIGNED_V8; + break; + case MONO_TYPE_U1: + c0 = INTRINS_WASM_SUB_SAT_UNSIGNED_V16; + break; + case MONO_TYPE_U2: + c0 = INTRINS_WASM_SUB_SAT_UNSIGNED_V8; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } } // default emit path for cases with op set diff --git a/src/mono/mono/mini/simd-methods.h b/src/mono/mono/mini/simd-methods.h index 0e38696380cc5c..20db4e837c5f58 100644 --- a/src/mono/mono/mini/simd-methods.h +++ b/src/mono/mono/mini/simd-methods.h @@ -286,6 +286,7 @@ METHOD(CarrylessMultiply) // ArmBase METHOD(LeadingSignCount) METHOD(ReverseElementBits) +METHOD(Yield) // Crc32 METHOD(ComputeCrc32) METHOD(ComputeCrc32C) @@ -634,10 +635,14 @@ METHOD(MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh) // Arm.Dp METHOD(DotProductBySelectedQuadruplet) // Wasm +METHOD(AllTrue) +METHOD(AnyTrue) +METHOD(AverageRounded) METHOD(Bitmask) METHOD(ConvertNarrowingSignedSaturate) METHOD(ConvertNarrowingUnsignedSaturate) METHOD(ExtractLane) +METHOD(MultiplyRoundedSaturateQ15) METHOD(ReplaceLane) METHOD(ShiftLeft) METHOD(Splat) diff --git a/src/mono/mono/utils/lifo-semaphore.c b/src/mono/mono/utils/lifo-semaphore.c index 624e2bb3b74e68..51117ab972a66a 100644 --- a/src/mono/mono/utils/lifo-semaphore.c +++ b/src/mono/mono/utils/lifo-semaphore.c @@ -1,13 +1,21 @@ +#include +#include #include +#if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) +#include +#include +#endif + LifoSemaphore * mono_lifo_semaphore_init (void) { LifoSemaphore *semaphore = g_new0 (LifoSemaphore, 1); + semaphore->base.kind = LIFO_SEMAPHORE_NORMAL; if (semaphore == NULL) return NULL; - mono_coop_mutex_init (&semaphore->mutex); + mono_coop_mutex_init (&semaphore->base.mutex); return semaphore; } @@ -16,7 +24,7 @@ void mono_lifo_semaphore_delete (LifoSemaphore *semaphore) { g_assert (semaphore->head == NULL); - mono_coop_mutex_destroy (&semaphore->mutex); + mono_coop_mutex_destroy (&semaphore->base.mutex); g_free (semaphore); } @@ -26,12 +34,12 @@ mono_lifo_semaphore_timed_wait (LifoSemaphore *semaphore, int32_t timeout_ms) LifoSemaphoreWaitEntry wait_entry = {0}; mono_coop_cond_init (&wait_entry.condition); - mono_coop_mutex_lock (&semaphore->mutex); + mono_coop_mutex_lock (&semaphore->base.mutex); - if (semaphore->pending_signals > 0) { - --semaphore->pending_signals; + if (semaphore->base.pending_signals > 0) { + --semaphore->base.pending_signals; mono_coop_cond_destroy (&wait_entry.condition); - mono_coop_mutex_unlock (&semaphore->mutex); + mono_coop_mutex_unlock (&semaphore->base.mutex); return 1; } @@ -45,7 +53,7 @@ mono_lifo_semaphore_timed_wait (LifoSemaphore *semaphore, int32_t timeout_ms) // Wait for a signal or timeout int wait_error = 0; do { - wait_error = mono_coop_cond_timedwait (&wait_entry.condition, &semaphore->mutex, timeout_ms); + wait_error = mono_coop_cond_timedwait (&wait_entry.condition, &semaphore->base.mutex, timeout_ms); } while (wait_error == 0 && !wait_entry.signaled); if (wait_error == -1) { @@ -58,7 +66,7 @@ mono_lifo_semaphore_timed_wait (LifoSemaphore *semaphore, int32_t timeout_ms) } mono_coop_cond_destroy (&wait_entry.condition); - mono_coop_mutex_unlock (&semaphore->mutex); + mono_coop_mutex_unlock (&semaphore->base.mutex); return wait_entry.signaled; } @@ -66,7 +74,7 @@ mono_lifo_semaphore_timed_wait (LifoSemaphore *semaphore, int32_t timeout_ms) void mono_lifo_semaphore_release (LifoSemaphore *semaphore, uint32_t count) { - mono_coop_mutex_lock (&semaphore->mutex); + mono_coop_mutex_lock (&semaphore->base.mutex); while (count > 0) { LifoSemaphoreWaitEntry *wait_entry = semaphore->head; @@ -80,10 +88,239 @@ mono_lifo_semaphore_release (LifoSemaphore *semaphore, uint32_t count) mono_coop_cond_signal (&wait_entry->condition); --count; } else { - semaphore->pending_signals += count; + semaphore->base.pending_signals += count; + count = 0; + } + } + + mono_coop_mutex_unlock (&semaphore->base.mutex); +} + +#if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) + +LifoSemaphoreAsyncWait * +mono_lifo_semaphore_asyncwait_init (void) +{ + LifoSemaphoreAsyncWait *sem = g_new0 (LifoSemaphoreAsyncWait, 1); + if (sem == NULL) + return NULL; + sem->base.kind = LIFO_SEMAPHORE_ASYNCWAIT; + + mono_coop_mutex_init (&sem->base.mutex); + + return sem; +} + +void +mono_lifo_semaphore_asyncwait_delete (LifoSemaphoreAsyncWait *sem) +{ + /* FIXME: this is probably hard to guarantee - in-flight signaled semaphores still have wait entries */ + g_assert (sem->head == NULL); + mono_coop_mutex_destroy (&sem->base.mutex); + g_free (sem); +} + +enum { + LIFO_JS_WAITING = 0, + LIFO_JS_SIGNALED = 1, + LIFO_JS_SIGNALED_TIMEOUT_IGNORED = 2, + +}; + +static void +lifo_js_wait_entry_on_timeout (void *wait_entry_as_user_data); +static void +lifo_js_wait_entry_on_success (void *wait_entry_as_user_data); + + +static void +lifo_js_wait_entry_push (LifoSemaphoreAsyncWaitWaitEntry **head, + LifoSemaphoreAsyncWaitWaitEntry *entry) +{ + LifoSemaphoreAsyncWaitWaitEntry *next = *head; + *head = entry; + entry->next = next; + if (next) + next->previous = entry; +} + +static void +lifo_js_wait_entry_unlink (LifoSemaphoreAsyncWaitWaitEntry **head, + LifoSemaphoreAsyncWaitWaitEntry *entry) +{ + if (*head == entry) { + *head = entry->next; + } + if (entry->previous) { + entry->previous->next = entry->next; + } + if (entry->next) { + entry->next->previous = entry->previous; + } +} + +/* LOCKING: assumes semaphore is locked */ +static LifoSemaphoreAsyncWaitWaitEntry * +lifo_js_find_waiter (LifoSemaphoreAsyncWaitWaitEntry *entry) +{ + while (entry) { + if (entry->state == LIFO_JS_WAITING) + return entry; + entry = entry->next; + } + return NULL; +} + +static gboolean +lifo_js_wait_entry_no_thread (LifoSemaphoreAsyncWaitWaitEntry *entry, + pthread_t cur) +{ + while (entry) { + if (pthread_equal (entry->thread, cur)) + return FALSE; + entry = entry->next; + } + return TRUE; +} + +void +mono_lifo_semaphore_asyncwait_prepare_wait (LifoSemaphoreAsyncWait *sem, + int32_t timeout_ms, + LifoSemaphoreAsyncWaitCallbackFn success_cb, + LifoSemaphoreAsyncWaitCallbackFn timeout_cb, + intptr_t user_data) +{ + mono_coop_mutex_lock (&sem->base.mutex); + if (sem->base.pending_signals > 0) { + sem->base.pending_signals--; + mono_coop_mutex_unlock (&sem->base.mutex); + success_cb (sem, user_data); // FIXME: queue microtask + return; + } + + pthread_t cur = pthread_self (); + + /* Don't allow the current thread to wait multiple times. + * No particular reason for it, except that it makes reasoning a bit easier. + * This can probably be relaxed if there's a need. + */ + g_assert (lifo_js_wait_entry_no_thread(sem->head, cur)); + + LifoSemaphoreAsyncWaitWaitEntry *wait_entry = g_new0 (LifoSemaphoreAsyncWaitWaitEntry, 1); + wait_entry->success_cb = success_cb; + wait_entry->timeout_cb = timeout_cb; + wait_entry->sem = sem; + wait_entry->user_data = user_data; + wait_entry->thread = pthread_self(); + wait_entry->state = LIFO_JS_WAITING; + wait_entry->refcount = 1; // timeout owns the wait entry + wait_entry->js_timeout_id = emscripten_set_timeout (lifo_js_wait_entry_on_timeout, (double)timeout_ms, wait_entry); + lifo_js_wait_entry_push (&sem->head, wait_entry); + mono_coop_mutex_unlock (&sem->base.mutex); + return; +} + +void +mono_lifo_semaphore_asyncwait_release (LifoSemaphoreAsyncWait *sem, + uint32_t count) +{ + mono_coop_mutex_lock (&sem->base.mutex); + + while (count > 0) { + LifoSemaphoreAsyncWaitWaitEntry *wait_entry = lifo_js_find_waiter (sem->head); + if (wait_entry != NULL) { + /* found one. set its status and queue some work to run on the signaled thread */ + pthread_t target = wait_entry->thread; + wait_entry->state = LIFO_JS_SIGNALED; + wait_entry->refcount++; + // we're under the mutex - if we got here the timeout hasn't fired yet + g_assert (wait_entry->refcount == 2); + --count; + /* if we're on the same thread, don't run the callback while holding the lock */ + emscripten_dispatch_to_thread_async (target, EM_FUNC_SIG_VI, lifo_js_wait_entry_on_success, NULL, wait_entry); + } else { + sem->base.pending_signals += count; count = 0; } } - mono_coop_mutex_unlock (&semaphore->mutex); + mono_coop_mutex_unlock (&sem->base.mutex); +} + +static void +lifo_js_wait_entry_on_timeout (void *wait_entry_as_user_data) +{ + LifoSemaphoreAsyncWaitWaitEntry *wait_entry = (LifoSemaphoreAsyncWaitWaitEntry *)wait_entry_as_user_data; + g_assert (pthread_equal (wait_entry->thread, pthread_self())); + g_assert (wait_entry->sem != NULL); + LifoSemaphoreAsyncWait *sem = wait_entry->sem; + gboolean call_timeout_cb = FALSE; + LifoSemaphoreAsyncWaitCallbackFn timeout_cb = NULL; + intptr_t user_data = 0; + mono_coop_mutex_lock (&sem->base.mutex); + switch (wait_entry->state) { + case LIFO_JS_WAITING: + /* semaphore timed out before a Release. */ + g_assert (wait_entry->refcount == 1); + /* unlink and free the wait entry, run the user timeout_cb. */ + lifo_js_wait_entry_unlink (&sem->head, wait_entry); + timeout_cb = wait_entry->timeout_cb; + user_data = wait_entry->user_data; + g_free (wait_entry); + call_timeout_cb = TRUE; + break; + case LIFO_JS_SIGNALED: + /* seamphore was signaled, but the timeout callback ran before the success callback arrived */ + g_assert (wait_entry->refcount == 2); + /* set state to LIFO_JS_SIGNALED_TIMEOUT_IGNORED, decrement refcount, return */ + wait_entry->state = LIFO_JS_SIGNALED_TIMEOUT_IGNORED; + wait_entry->refcount--; + break; + case LIFO_JS_SIGNALED_TIMEOUT_IGNORED: + default: + g_assert_not_reached(); + } + mono_coop_mutex_unlock (&sem->base.mutex); + if (call_timeout_cb) { + timeout_cb (sem, user_data); + } +} + +static void +lifo_js_wait_entry_on_success (void *wait_entry_as_user_data) +{ + LifoSemaphoreAsyncWaitWaitEntry *wait_entry = (LifoSemaphoreAsyncWaitWaitEntry *)wait_entry_as_user_data; + g_assert (pthread_equal (wait_entry->thread, pthread_self())); + g_assert (wait_entry->sem != NULL); + LifoSemaphoreAsyncWait *sem = wait_entry->sem; + gboolean call_success_cb = FALSE; + LifoSemaphoreAsyncWaitCallbackFn success_cb = NULL; + intptr_t user_data = 0; + mono_coop_mutex_lock (&sem->base.mutex); + switch (wait_entry->state) { + case LIFO_JS_SIGNALED: + g_assert (wait_entry->refcount == 2); + emscripten_clear_timeout (wait_entry->js_timeout_id); + /* emscripten safeSetTimeout calls keepalive push which is popped by the timeout + * callback. If we cancel the timeout, we have to pop the keepalive ourselves. */ + emscripten_runtime_keepalive_pop(); + wait_entry->refcount--; + /* fallthru */ + case LIFO_JS_SIGNALED_TIMEOUT_IGNORED: + g_assert (wait_entry->refcount == 1); + lifo_js_wait_entry_unlink (&sem->head, wait_entry); + success_cb = wait_entry->success_cb; + user_data = wait_entry->user_data; + g_free (wait_entry); + call_success_cb = TRUE; + break; + case LIFO_JS_WAITING: + default: + g_assert_not_reached(); + } + mono_coop_mutex_unlock (&sem->base.mutex); + g_assert (call_success_cb); + success_cb (sem, user_data); } + +#endif /* HOST_BROWSER && !DISABLE_THREADS */ diff --git a/src/mono/mono/utils/lifo-semaphore.h b/src/mono/mono/utils/lifo-semaphore.h index 766f41aaaab6d4..a97a560e281161 100644 --- a/src/mono/mono/utils/lifo-semaphore.h +++ b/src/mono/mono/utils/lifo-semaphore.h @@ -3,6 +3,22 @@ #include +typedef struct _LifoSemaphoreBase LifoSemaphoreBase; + +struct _LifoSemaphoreBase +{ + MonoCoopMutex mutex; + uint32_t pending_signals; + uint8_t kind; +}; + +enum { + LIFO_SEMAPHORE_NORMAL = 1, +#if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) + LIFO_SEMAPHORE_ASYNCWAIT, +#endif +}; + typedef struct _LifoSemaphore LifoSemaphore; typedef struct _LifoSemaphoreWaitEntry LifoSemaphoreWaitEntry; @@ -14,9 +30,8 @@ struct _LifoSemaphoreWaitEntry { }; struct _LifoSemaphore { - MonoCoopMutex mutex; + LifoSemaphoreBase base; LifoSemaphoreWaitEntry *head; - uint32_t pending_signals; }; LifoSemaphore * @@ -31,4 +46,94 @@ mono_lifo_semaphore_timed_wait (LifoSemaphore *semaphore, int32_t timeout_ms); void mono_lifo_semaphore_release (LifoSemaphore *semaphore, uint32_t count); +#if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) +/* A type of lifo semaphore that can be waited from the JS event loop. + * + * Instead of a blocking timed_wait function, it uses a pair of callbacks: a success callback and a + * timeout callback. The wait function returns immediately and the callbacks will fire on the JS + * event loop when the semaphore is released or the timeout expires. + */ +typedef struct _LifoSemaphoreAsyncWait LifoSemaphoreAsyncWait; +/* + * Because the callbacks are asynchronous, it's possible for the same thread to attempt to wait + * multiple times for the same semaphore. For simplicity of reasoning, we dissallow that and + * assert. In principle we could support it, but we haven't implemented that. + */ +typedef struct _LifoSemaphoreAsyncWaitWaitEntry LifoSemaphoreAsyncWaitWaitEntry; + +typedef void (*LifoSemaphoreAsyncWaitCallbackFn)(LifoSemaphoreAsyncWait *semaphore, intptr_t user_data); + +struct _LifoSemaphoreAsyncWaitWaitEntry { + LifoSemaphoreAsyncWaitWaitEntry *previous; + LifoSemaphoreAsyncWaitWaitEntry *next; + LifoSemaphoreAsyncWaitCallbackFn success_cb; + LifoSemaphoreAsyncWaitCallbackFn timeout_cb; + LifoSemaphoreAsyncWait *sem; + intptr_t user_data; + pthread_t thread; + int32_t js_timeout_id; // only valid to access from the waiting thread + /* state and refcount are protected by the semaphore mutex */ + uint16_t state; /* 0 waiting, 1 signaled, 2 signaled - timeout ignored */ + uint16_t refcount; /* 1 if waiting, 2 if signaled, 1 if timeout fired while signaled and we're ignoring the timeout */ +}; + +struct _LifoSemaphoreAsyncWait { + LifoSemaphoreBase base; + LifoSemaphoreAsyncWaitWaitEntry *head; +}; + +LifoSemaphoreAsyncWait * +mono_lifo_semaphore_asyncwait_init (void); + +/* what to do with waiters? + * might be kind of academic - we don't expect to destroy these + */ +void +mono_lifo_semaphore_asyncwait_delete (LifoSemaphoreAsyncWait *semaphore); + +/* + * the timeout_cb is triggered by a JS setTimeout callback + * + * the success_cb is triggered using Emscripten's capability to push async work from one thread to + * another. That means the main thread will need to be able to process JS events (in order to + * assist threads in pushing work from one thread to another) in order for success callbacks to + * function. Emscripten also pumps the async work queues in other circumstances (during sleeps) but + * the main thread still needs to participate. + * + * There's a potential race the implementation needs to be careful about: + * when one thread releases a semaphore and queues the success callback to run, + * while the success callback is in flight, the timeout callback can fire. + * It is important that the called back functions don't destroy the wait entry until either both + * callbacks have fired, or the success callback has a chance to cancel the timeout callback. + * + * We use a refcount to delimit the lifetime of the wait entry. When the wait is created, the + * refcount is 1 and it is notionally owned by the timeout callback. When a sempahore is released, + * the refcount goes to 2. When a continuation fires, it decreases the refcount. If the timeout + * callback fires first if it sees a refcount of 2 it can decrement and return - we know a success + * continuation is in flight and we can allow it to complete. If the refcount is 1 we need to take the semaphore's mutex and remove the wait entry. (With double check locking - the refcount could go up). + * + * When the success continuation fires,it will examine the refcount. If the refcount is 1 at the + * outset, then the cancelation already tried to fire while we were in flight. If the refcount is 2 + * at the outset, then the success contination fired before the timeout, so we can cancel the + * timeout. In either case we can remove the wait entry. + * + * Both the success and timeout code only calls the user provided callbacks after the wait entry is + * destroyed. + * + * FIXME: should we just always use the mutex to protect the wait entry status+refcount? + * + * TODO: when we call emscripten_set_timeout it implicitly calls emscripten_runtime_keepalive_push which is + * popped when the timeout runs. But emscripten_clear_timeout doesn't pop - we need to pop ourselves + */ +void +mono_lifo_semaphore_asyncwait_prepare_wait (LifoSemaphoreAsyncWait *semaphore, int32_t timeout_ms, + LifoSemaphoreAsyncWaitCallbackFn success_cb, + LifoSemaphoreAsyncWaitCallbackFn timeout_cb, + intptr_t user_data); + +void +mono_lifo_semaphore_asyncwait_release (LifoSemaphoreAsyncWait *semaphore, uint32_t count); + +#endif /* HOST_BROWSER && !DISABLE_THREADS */ + #endif // __MONO_LIFO_SEMAPHORE_H__ diff --git a/src/mono/mono/utils/mono-dl.c b/src/mono/mono/utils/mono-dl.c index c4e5d5eafad243..5c613688aef5b8 100644 --- a/src/mono/mono/utils/mono-dl.c +++ b/src/mono/mono/utils/mono-dl.c @@ -599,74 +599,3 @@ mono_dl_fallback_unregister (MonoDlFallbackHandler *handler) g_slist_remove (fallback_handlers, handler); g_free (handler); } - -static MonoDl* -try_load (const char *lib_name, char *dir, int flags, MonoError *error) -{ - gpointer iter; - MonoDl *runtime_lib; - char *path; - iter = NULL; - while ((path = mono_dl_build_path (dir, lib_name, &iter))) { - mono_error_cleanup (error); - error_init_reuse (error); - runtime_lib = mono_dl_open (path, flags, error); - g_free (path); - if (runtime_lib) - return runtime_lib; - } - return NULL; -} - -MonoDl* -mono_dl_open_runtime_lib (const char* lib_name, int flags, MonoError *error) -{ - MonoDl *runtime_lib = NULL; - - char *resolvedname = minipal_getexepath(); - - if (!resolvedname) { - char *base; - char *name; - char *baseparent = NULL; - base = g_path_get_dirname (resolvedname); - name = g_strdup_printf ("%s/.libs", base); - runtime_lib = try_load (lib_name, name, flags, error); - g_free (name); - if (!runtime_lib) - baseparent = g_path_get_dirname (base); - if (!runtime_lib) { - mono_error_cleanup (error); - error_init_reuse (error); - name = g_strdup_printf ("%s/lib", baseparent); - runtime_lib = try_load (lib_name, name, flags, error); - g_free (name); - } -#ifdef __MACH__ - if (!runtime_lib) { - mono_error_cleanup (error); - error_init_reuse (error); - name = g_strdup_printf ("%s/Libraries", baseparent); - runtime_lib = try_load (lib_name, name, flags, error); - g_free (name); - } -#endif - if (!runtime_lib) { - mono_error_cleanup (error); - error_init_reuse (error); - name = g_strdup_printf ("%s/profiler/.libs", baseparent); - runtime_lib = try_load (lib_name, name, flags, error); - g_free (name); - } - g_free (base); - g_free (resolvedname); - g_free (baseparent); - } - if (!runtime_lib) { - mono_error_cleanup (error); - error_init_reuse (error); - runtime_lib = try_load (lib_name, NULL, flags, error); - } - - return runtime_lib; -} diff --git a/src/mono/mono/utils/mono-dl.h b/src/mono/mono/utils/mono-dl.h index d3893ff8a71390..7ed4fe089bb538 100644 --- a/src/mono/mono/utils/mono-dl.h +++ b/src/mono/mono/utils/mono-dl.h @@ -39,8 +39,6 @@ void mono_dl_close (MonoDl *module, MonoError *error); char* mono_dl_build_path (const char *directory, const char *name, void **iter); char* mono_dl_build_platform_path (const char *directory, const char *name, void **iter); -MonoDl* mono_dl_open_runtime_lib (const char *lib_name, int flags, MonoError *error); - MonoDl * mono_dl_open_self (MonoError *error); // This converts the MONO_DL_* enum to native flags, combines it with the other flags passed, and resolves some inconsistencies diff --git a/src/mono/mono/utils/mono-os-mutex.h b/src/mono/mono/utils/mono-os-mutex.h index 30f914b0893a29..20055973f81cf8 100644 --- a/src/mono/mono/utils/mono-os-mutex.h +++ b/src/mono/mono/utils/mono-os-mutex.h @@ -36,7 +36,7 @@ #if !defined(HOST_WIN32) -#if !defined(CLOCK_MONOTONIC) || defined(HOST_DARWIN) || defined(HOST_WASM) +#if !defined(CLOCK_MONOTONIC) || defined(HOST_DARWIN) || defined(HOST_WASI) #define BROKEN_CLOCK_SOURCE #endif diff --git a/src/mono/mono/utils/mono-threads-coop.c b/src/mono/mono/utils/mono-threads-coop.c index 4ed659d66058cc..b6263bd844cea1 100644 --- a/src/mono/mono/utils/mono-threads-coop.c +++ b/src/mono/mono/utils/mono-threads-coop.c @@ -219,6 +219,7 @@ typedef struct { __declspec(naked) void __cdecl copy_stack_data_internal_win32_wrapper (MonoThreadInfo *info, MonoStackData *stackdata_begin, MonoBuiltinUnwindInfo *unwind_info_data, CopyStackDataFunc func) { +#if defined(TARGET_X86) || defined(TARGET_AMD64) __asm { mov edx, dword ptr [esp + 0Ch] mov dword ptr [edx + 00h], ebx @@ -230,6 +231,7 @@ copy_stack_data_internal_win32_wrapper (MonoThreadInfo *info, MonoStackData *sta mov edx, dword ptr [esp + 10h] jmp edx }; +#endif } #endif diff --git a/src/mono/mono/utils/mono-threads-posix.c b/src/mono/mono/utils/mono-threads-posix.c index 08e843cdd7023e..a70691d01e8fe9 100644 --- a/src/mono/mono/utils/mono-threads-posix.c +++ b/src/mono/mono/utils/mono-threads-posix.c @@ -133,6 +133,15 @@ mono_threads_platform_exit (gsize exit_code) pthread_exit ((gpointer) exit_code); } +gboolean +mono_thread_platform_external_eventloop_keepalive_check (void) +{ + /* vanilla POSIX thread creation doesn't support an external eventloop: when the thread main + function returns, the thread is done. + */ + return FALSE; +} + #if HOST_FUCHSIA int mono_thread_info_get_system_max_stack_size (void) diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index 96e5446388a43a..6a33dfa0d5bc2f 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -301,6 +301,20 @@ mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_d #endif } +gboolean +mono_thread_platform_external_eventloop_keepalive_check (void) +{ +#if defined(HOST_BROWSER) && !defined(DISABLE_THREADS) + /* if someone called emscripten_runtime_keepalive_push (), the + * thread will stay alive in the JS event loop after returning + * from the thread's main function. + */ + return emscripten_runtime_keepalive_check (); +#else + return FALSE; +#endif +} + void mono_threads_platform_init (void) { } diff --git a/src/mono/mono/utils/mono-threads-windows.c b/src/mono/mono/utils/mono-threads-windows.c index 3e56205c0ab880..169449b831e839 100644 --- a/src/mono/mono/utils/mono-threads-windows.c +++ b/src/mono/mono/utils/mono-threads-windows.c @@ -501,6 +501,15 @@ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); static gboolean is_wow64 = FALSE; #endif +gboolean +mono_thread_platform_external_eventloop_keepalive_check (void) +{ + /* We don't support thread creation with an external eventloop on WIN32: when the thread start + function returns, the thread is done. + */ + return FALSE; +} + /* We do this at init time to avoid potential races with module opening */ void mono_threads_platform_init (void) diff --git a/src/mono/mono/utils/mono-threads.h b/src/mono/mono/utils/mono-threads.h index 6a548b1838c342..cdfc9f61336713 100644 --- a/src/mono/mono/utils/mono-threads.h +++ b/src/mono/mono/utils/mono-threads.h @@ -632,6 +632,9 @@ gboolean mono_threads_platform_in_critical_region (THREAD_INFO_TYPE *info); gboolean mono_threads_platform_yield (void); void mono_threads_platform_exit (gsize exit_code); +gboolean +mono_thread_platform_external_eventloop_keepalive_check (void); + void mono_threads_coop_begin_global_suspend (void); void mono_threads_coop_end_global_suspend (void); diff --git a/src/mono/mono/utils/mono-time.c b/src/mono/mono/utils/mono-time.c index 68831393bc7c34..2a89bd9d3d0772 100644 --- a/src/mono/mono/utils/mono-time.c +++ b/src/mono/mono/utils/mono-time.c @@ -119,9 +119,10 @@ gint64 mono_msec_boottime (void) { /* clock_gettime () is found by configure on Apple builds, but its only present from ios 10, macos 10.12, tvos 10 and watchos 3 */ -#if !defined (TARGET_WASM) && ((defined(HAVE_CLOCK_MONOTONIC_COARSE) || defined(HAVE_CLOCK_MONOTONIC)) && !(defined(TARGET_IOS) || defined(TARGET_OSX) || defined(TARGET_WATCHOS) || defined(TARGET_TVOS))) +#if ((defined(HAVE_CLOCK_MONOTONIC_COARSE) || defined(HAVE_CLOCK_MONOTONIC)) && !(defined(TARGET_IOS) || defined(TARGET_OSX) || defined(TARGET_WATCHOS) || defined(TARGET_TVOS))) clockid_t clockType = -#if HAVE_CLOCK_MONOTONIC_COARSE + /* emscripten exposes CLOCK_MONOTONIC_COARSE but doesn't implement it */ +#if defined(HAVE_CLOCK_MONOTONIC_COARSE) && !defined(TARGET_WASM) CLOCK_MONOTONIC_COARSE; /* good enough resolution, fastest speed */ #else CLOCK_MONOTONIC; diff --git a/src/mono/mono/utils/options-def.h b/src/mono/mono/utils/options-def.h index b7c65765b1b89a..566637dc0f2e37 100644 --- a/src/mono/mono/utils/options-def.h +++ b/src/mono/mono/utils/options-def.h @@ -145,6 +145,12 @@ DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-e DEFINE_INT(jiterpreter_wasm_bytes_limit, "jiterpreter-wasm-bytes-limit", 6 * 1024 * 1024, "Disable jiterpreter code generation once this many bytes of WASM have been generated") #endif // HOST_BROWSER +#ifdef HOST_WASM +DEFINE_BOOL_READONLY(experimental_gshared_mrgctx, "experimental-gshared-mrgctx", TRUE, "Use a mrgctx for all gshared methods") +#else +DEFINE_BOOL(experimental_gshared_mrgctx, "experimental-gshared-mrgctx", FALSE, "Use a mrgctx for all gshared methods") +#endif + /* Cleanup */ #undef DEFINE_OPTION_FULL #undef DEFINE_OPTION_READONLY diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props index dc074e761f24e1..a25a3d438d9f9a 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props @@ -31,7 +31,7 @@ Copyright (c) .NET Foundation. All rights reserved. / Root - $(StaticWebAssetsAdditionalBuildPropertiesToRemove);RuntimeIdentifier;SelfContained + $(StaticWebAssetsAdditionalBuildPropertiesToRemove);RuntimeIdentifier;SelfContained ComputeFilesToPublish;GetCurrentProjectPublishStaticWebAssetItems $(StaticWebAssetsAdditionalPublishProperties);BuildProjectReferences=false;ResolveAssemblyReferencesFindRelatedSatellites=true $(StaticWebAssetsAdditionalPublishPropertiesToRemove);NoBuild;RuntimeIdentifier diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index c610f34c1b6896..47b4cf3206231a 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -40,9 +40,9 @@ Copyright (c) .NET Foundation. All rights reserved. + - true true @@ -168,6 +168,10 @@ Copyright (c) .NET Foundation. All rights reserved. <_WasmInvariantGlobalization Condition="'$(_WasmInvariantGlobalization)' == ''">true <_WasmCopyOutputSymbolsToOutputDirectory>$(CopyOutputSymbolsToOutputDirectory) <_WasmCopyOutputSymbolsToOutputDirectory Condition="'$(_WasmCopyOutputSymbolsToOutputDirectory)'==''">true + <_WasmEnableThreads>$(WasmEnableThreads) + <_WasmEnableThreads Condition="'$(_WasmEnableThreads)' == ''">false + <_WasmEnableWebcil>$(WasmEnableWebcil) + <_WasmEnableWebcil Condition="'$(_WasmEnableWebcil)' == ''">false <_BlazorWebAssemblyStartupMemoryCache>$(BlazorWebAssemblyStartupMemoryCache) <_BlazorWebAssemblyJiterpreter>$(BlazorWebAssemblyJiterpreter) <_BlazorWebAssemblyRuntimeOptions>$(BlazorWebAssemblyRuntimeOptions) @@ -200,13 +204,23 @@ Copyright (c) .NET Foundation. All rights reserved. CopySymbols="$(_WasmCopyOutputSymbolsToOutputDirectory)" OutputPath="$(OutputPath)" FingerprintDotNetJs="$(WasmFingerprintDotnetJs)" + EnableThreads="$(_WasmEnableThreads)" > + + <_WasmBuildWebCilPath>$(IntermediateOutputPath)webcil + + + + + + + + + <_WasmPublishWebCilPath>$(IntermediateOutputPath)webcil\publish + + + + + + + - + <_SampleProject Condition="'$(_SampleProject)' == ''">$(MSBuildProjectFile) <_SampleAssembly Condition="'$(_SampleAssembly)' == ''">$(TargetFileName) + <_SampleProjectName>$([System.String]::Copy('$(_SampleProject)').Replace('.csproj','')) + --env MONO_LOG_LEVEL=debug --env MONO_LOG_MASK=all <_ExeExt Condition="$([MSBuild]::IsOSPlatform('WINDOWS'))">.exe @@ -13,7 +15,14 @@ TODOWASI - - tcplisten localhost:64000 - - env DEBUGGER_FD=4 --> + Condition="'$(WasmBuildNative)' != 'true'" + Command="$(WasmtimeDir)wasmtime$(_ExeExt) $(MONO_LOG_LEVEL) --dir . dotnet.wasm $(_SampleProjectName)" IgnoreExitCode="true" /> + + diff --git a/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj index 042811854a9253..cb410fa78f843a 100644 --- a/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj +++ b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj @@ -1,6 +1,10 @@ $(NetCoreAppCurrent) + diff --git a/src/mono/sample/wasm/Directory.Build.targets b/src/mono/sample/wasm/Directory.Build.targets index 0b45eb06b956bc..7ff3c4d09a7514 100644 --- a/src/mono/sample/wasm/Directory.Build.targets +++ b/src/mono/sample/wasm/Directory.Build.targets @@ -53,7 +53,7 @@ - + diff --git a/src/mono/sample/wasm/browser-bench/String.cs b/src/mono/sample/wasm/browser-bench/String.cs index 608801c5177b08..16cc2c6c9faa6c 100644 --- a/src/mono/sample/wasm/browser-bench/String.cs +++ b/src/mono/sample/wasm/browser-bench/String.cs @@ -23,7 +23,11 @@ public StringTask() new TextInfoToTitleCase(), new StringCompareMeasurement(), new StringEqualsMeasurement(), - new CompareInfoMeasurement(), + new CompareInfoCompareMeasurement(), + new CompareInfoStartsWithMeasurement(), + new CompareInfoEndsWithMeasurement(), + new StringStartsWithMeasurement(), + new StringEndsWithMeasurement(), }; } @@ -124,16 +128,21 @@ public class TextInfoToTitleCase : TextInfoMeasurement public override void RunStep() => textInfo.ToTitleCase(str); } - public class StringsCompare : StringMeasurement + public abstract class StringsCompare : StringMeasurement { - protected string str2; + protected string strDifferentSuffix; + protected string strDifferentPrefix; public void InitializeStringsForComparison() { InitializeString(); - // worst case: strings may differ only with the last char + // worst case: strings may differ only with the last/first char + char originalLastChar = data[len-1]; data[len-1] = (char)random.Next(0x80); - str2 = new string(data); + strDifferentSuffix = new string(data); + data[len-1] = originalLastChar; + data[0] = (char)random.Next(0x80); + strDifferentPrefix = new string(data); } public override string Name => "Strings Compare Base"; } @@ -149,7 +158,7 @@ public override Task BeforeBatch() return Task.CompletedTask; } public override string Name => "String Compare"; - public override void RunStep() => string.Compare(str, str2, cultureInfo, CompareOptions.None); + public override void RunStep() => string.Compare(str, strDifferentSuffix, cultureInfo, CompareOptions.None); } public class StringEqualsMeasurement : StringsCompare @@ -160,10 +169,10 @@ public override Task BeforeBatch() return Task.CompletedTask; } public override string Name => "String Equals"; - public override void RunStep() => string.Equals(str, str2, StringComparison.InvariantCulture); + public override void RunStep() => string.Equals(str, strDifferentSuffix, StringComparison.InvariantCulture); } - public class CompareInfoMeasurement : StringsCompare + public class CompareInfoCompareMeasurement : StringsCompare { protected CompareInfo compareInfo; @@ -174,7 +183,63 @@ public override Task BeforeBatch() return Task.CompletedTask; } public override string Name => "CompareInfo Compare"; - public override void RunStep() => compareInfo.Compare(str, str2); + public override void RunStep() => compareInfo.Compare(str, strDifferentSuffix); + } + + public class CompareInfoStartsWithMeasurement : StringsCompare + { + protected CompareInfo compareInfo; + + public override Task BeforeBatch() + { + compareInfo = new CultureInfo("hy-AM").CompareInfo; + InitializeStringsForComparison(); + return Task.CompletedTask; + } + public override string Name => "CompareInfo IsPrefix"; + public override void RunStep() => compareInfo.IsPrefix(str, strDifferentSuffix); + } + + public class CompareInfoEndsWithMeasurement : StringsCompare + { + protected CompareInfo compareInfo; + + public override Task BeforeBatch() + { + compareInfo = new CultureInfo("it-IT").CompareInfo; + InitializeStringsForComparison(); + return Task.CompletedTask; + } + public override string Name => "CompareInfo IsSuffix"; + public override void RunStep() => compareInfo.IsSuffix(str, strDifferentPrefix); + } + + public class StringStartsWithMeasurement : StringsCompare + { + protected CultureInfo cultureInfo; + + public override Task BeforeBatch() + { + cultureInfo = new CultureInfo("bs-BA"); + InitializeStringsForComparison(); + return Task.CompletedTask; + } + public override string Name => "String StartsWith"; + public override void RunStep() => str.StartsWith(strDifferentSuffix, false, cultureInfo); + } + + public class StringEndsWithMeasurement : StringsCompare + { + protected CultureInfo cultureInfo; + + public override Task BeforeBatch() + { + cultureInfo = new CultureInfo("nb-NO"); + InitializeStringsForComparison(); + return Task.CompletedTask; + } + public override string Name => "String EndsWith"; + public override void RunStep() => str.EndsWith(strDifferentPrefix, false, cultureInfo); } } } diff --git a/src/mono/sample/wasm/browser-threads-minimal/Program.cs b/src/mono/sample/wasm/browser-threads-minimal/Program.cs index 0b9784836bbd78..4379c9092bf618 100644 --- a/src/mono/sample/wasm/browser-threads-minimal/Program.cs +++ b/src/mono/sample/wasm/browser-threads-minimal/Program.cs @@ -18,6 +18,77 @@ public static int Main(string[] args) return 0; } + [JSExport] + public static async Task TestCanStartThread() + { + var tcs = new TaskCompletionSource(); + var t = new Thread(() => + { + var childTid = Thread.CurrentThread.ManagedThreadId; + tcs.SetResult(childTid); + }); + t.Start(); + var childTid = await tcs.Task; + t.Join(); + if (childTid == Thread.CurrentThread.ManagedThreadId) + throw new Exception("Child thread ran on same thread as parent"); + } + + [JSImport("globalThis.setTimeout")] + static partial void GlobalThisSetTimeout([JSMarshalAs] Action cb, int timeoutMs); + + [JSImport("globalThis.fetch")] + private static partial Task GlobalThisFetch(string url); + + [JSExport] + public static async Task TestCallSetTimeoutOnWorker() + { + var t = Task.Run(TimeOutThenComplete); + await t; + Console.WriteLine ($"XYZ: Main Thread caught task tid:{Thread.CurrentThread.ManagedThreadId}"); + } + + const string fetchhelper = "./fetchelper.js"; + + [JSImport("responseText", fetchhelper)] + private static partial Task FetchHelperResponseText(JSObject response); + + [JSExport] + public static async Task FetchBackground(string url) + { + var t = Task.Run(async () => + { + using var import = await JSHost.ImportAsync(fetchhelper, "./fetchhelper.js"); + var r = await GlobalThisFetch(url); + var ok = (bool)r.GetPropertyAsBoolean("ok"); + + Console.WriteLine($"XYZ: FetchBackground fetch returned to thread:{Thread.CurrentThread.ManagedThreadId}, ok: {ok}"); + if (ok) + { + var text = await FetchHelperResponseText(r); + Console.WriteLine($"XYZ: FetchBackground fetch returned to thread:{Thread.CurrentThread.ManagedThreadId}, text: {text}"); + return text; + } + return "not-ok"; + }); + var r = await t; + Console.WriteLine($"XYZ: FetchBackground thread:{Thread.CurrentThread.ManagedThreadId} background thread returned"); + return r; + } + + private static async Task TimeOutThenComplete() + { + var tcs = new TaskCompletionSource(); + Console.WriteLine ($"XYZ: Task running tid:{Thread.CurrentThread.ManagedThreadId}"); + GlobalThisSetTimeout(() => { + tcs.SetResult(); + Console.WriteLine ($"XYZ: Timeout fired tid:{Thread.CurrentThread.ManagedThreadId}"); + }, 250); + Console.WriteLine ($"XYZ: Task sleeping tid:{Thread.CurrentThread.ManagedThreadId}"); + await tcs.Task; + Console.WriteLine ($"XYZ: Task resumed tid:{Thread.CurrentThread.ManagedThreadId}"); + } + [JSExport] public static async Task RunBackgroundThreadCompute() { @@ -41,10 +112,27 @@ public static async Task RunBackgroundLongRunningTaskCompute() return await t; } + [JSExport] + public static async Task RunBackgroundTaskRunCompute() + { + var t1 = Task.Run (() => { + var n = CountingCollatzTest(); + return n; + }); + var t2 = Task.Run (() => { + var n = CountingCollatzTest(); + return n; + }); + var rs = await Task.WhenAll (new [] { t1, t2 }); + if (rs[0] != rs[1]) + throw new Exception ($"Results from two tasks {rs[0]}, {rs[1]}, differ"); + return rs[0]; + } + public static int CountingCollatzTest() { const int limit = 5000; - const int maxInput = 500_000; + const int maxInput = 200_000; int bigly = 0; int hugely = 0; int maxSteps = 0; @@ -60,7 +148,7 @@ public static int CountingCollatzTest() Console.WriteLine ($"Bigly: {bigly}, Hugely: {hugely}, maxSteps: {maxSteps}"); - if (bigly == 241677 && hugely == 0 && maxSteps == 448) + if (bigly == 86187 && hugely == 0 && maxSteps == 382) return 524; else return 0; diff --git a/src/mono/sample/wasm/browser-threads-minimal/Wasm.Browser.Threads.Minimal.Sample.csproj b/src/mono/sample/wasm/browser-threads-minimal/Wasm.Browser.Threads.Minimal.Sample.csproj index f9c81f4b40e714..defce7521ac7f5 100644 --- a/src/mono/sample/wasm/browser-threads-minimal/Wasm.Browser.Threads.Minimal.Sample.csproj +++ b/src/mono/sample/wasm/browser-threads-minimal/Wasm.Browser.Threads.Minimal.Sample.csproj @@ -6,6 +6,8 @@ + + diff --git a/src/mono/sample/wasm/browser-threads-minimal/blurst.txt b/src/mono/sample/wasm/browser-threads-minimal/blurst.txt new file mode 100644 index 00000000000000..6679d914da1c75 --- /dev/null +++ b/src/mono/sample/wasm/browser-threads-minimal/blurst.txt @@ -0,0 +1 @@ +It was the best of times, it was the blurst of times. diff --git a/src/mono/sample/wasm/browser-threads-minimal/fetchhelper.js b/src/mono/sample/wasm/browser-threads-minimal/fetchhelper.js new file mode 100644 index 00000000000000..928492378fc6c4 --- /dev/null +++ b/src/mono/sample/wasm/browser-threads-minimal/fetchhelper.js @@ -0,0 +1,11 @@ + +function delay(timeoutMs) { + return new Promise(resolve => setTimeout(resolve, timeoutMs)); +} + +export async function responseText(response) /* Promise */ { + console.log("artificially waiting for response for 25 seconds"); + await delay(25000); + console.log("artificial waiting done"); + return await response.text(); +} diff --git a/src/mono/sample/wasm/browser-threads-minimal/main.js b/src/mono/sample/wasm/browser-threads-minimal/main.js index f607d96c2846ab..3179fd5739e5b4 100644 --- a/src/mono/sample/wasm/browser-threads-minimal/main.js +++ b/src/mono/sample/wasm/browser-threads-minimal/main.js @@ -15,18 +15,41 @@ try { const exports = await getAssemblyExports(assemblyName); - const r1 = await exports.Sample.Test.RunBackgroundThreadCompute(); - if (r1 !== 524) { - const msg = `Unexpected result ${r1} from RunBackgroundThreadCompute()`; + console.log("smoke: running TestCanStartThread"); + await exports.Sample.Test.TestCanStartThread(); + console.log("smoke: TestCanStartThread done"); + + console.log ("smoke: running TestCallSetTimeoutOnWorker"); + await exports.Sample.Test.TestCallSetTimeoutOnWorker(); + console.log ("smoke: TestCallSetTimeoutOnWorker done"); + + console.log ("smoke: running FetchBackground(blurst.txt)"); + let s = await exports.Sample.Test.FetchBackground("./blurst.txt"); + console.log ("smoke: FetchBackground(blurst.txt) done"); + if (s !== "It was the best of times, it was the blurst of times.\n") { + const msg = `Unexpected FetchBackground result ${s}`; document.getElementById("out").innerHTML = msg; - throw new Error(msg); + throw new Error (msg); + } + + console.log ("smoke: running FetchBackground(missing)"); + s = await exports.Sample.Test.FetchBackground("./missing.txt"); + console.log ("smoke: FetchBackground(missing) done"); + if (s !== "not-ok") { + const msg = `Unexpected FetchBackground(missing) result ${s}`; + document.getElementById("out").innerHTML = msg; + throw new Error (msg); } - const r2 = await exports.Sample.Test.RunBackgroundLongRunningTaskCompute(); - if (r2 !== 524) { - const msg = `Unexpected result ${r2} from RunBackgorundLongRunningTaskCompute()`; + + console.log ("smoke: running TaskRunCompute"); + const r1 = await exports.Sample.Test.RunBackgroundTaskRunCompute(); + if (r1 !== 524) { + const msg = `Unexpected result ${r1} from RunBackgorundTaskRunCompute()`; document.getElementById("out").innerHTML = msg; throw new Error(msg); } + console.log ("smoke: TaskRunCompute done"); + let exit_code = await runMain(assemblyName, []); exit(exit_code); diff --git a/src/mono/sample/wasm/console-node/main.mjs b/src/mono/sample/wasm/console-node/main.mjs index 4b1898c0335b93..3b9741a5398a73 100644 --- a/src/mono/sample/wasm/console-node/main.mjs +++ b/src/mono/sample/wasm/console-node/main.mjs @@ -3,7 +3,7 @@ import { dotnet } from './dotnet.js' -dotnet +await dotnet .withDiagnosticTracing(false) .withApplicationArguments("dotnet", "is", "great!") .run() \ No newline at end of file diff --git a/src/mono/sample/wasm/console-v8/main.mjs b/src/mono/sample/wasm/console-v8/main.mjs index f989302af6037b..b336fe2884fd53 100644 --- a/src/mono/sample/wasm/console-v8/main.mjs +++ b/src/mono/sample/wasm/console-v8/main.mjs @@ -3,7 +3,7 @@ import { dotnet } from './dotnet.js' -dotnet +await dotnet .withDiagnosticTracing(false) .withApplicationArguments(...arguments) .run() \ No newline at end of file diff --git a/src/mono/sample/wasm/wasm.mk b/src/mono/sample/wasm/wasm.mk index 67c4fa36207724..6984136c15d266 100644 --- a/src/mono/sample/wasm/wasm.mk +++ b/src/mono/sample/wasm/wasm.mk @@ -42,7 +42,7 @@ run-browser: fi run-console: - cd bin/$(CONFIG)/AppBundle && $(V8_PATH) --stack-trace-limit=1000 --single-threaded --expose_wasm $(MAIN_JS) -- $(ARGS) + cd bin/$(CONFIG)/AppBundle && $(V8_PATH) --stack-trace-limit=1000 --single-threaded --expose_wasm --module $(MAIN_JS) -- $(ARGS) run-console-node: cd bin/$(CONFIG)/AppBundle && node --stack-trace-limit=1000 --single-threaded --expose_wasm $(MAIN_JS) $(ARGS) diff --git a/src/mono/wasi/Wasi.Build.Tests/Wasi.Build.Tests.csproj b/src/mono/wasi/Wasi.Build.Tests/Wasi.Build.Tests.csproj index dde5b3a169beac..eda5dcba5c7827 100644 --- a/src/mono/wasi/Wasi.Build.Tests/Wasi.Build.Tests.csproj +++ b/src/mono/wasi/Wasi.Build.Tests/Wasi.Build.Tests.csproj @@ -17,7 +17,7 @@ true - false + false true false diff --git a/src/mono/wasi/build/WasiApp.Native.targets b/src/mono/wasi/build/WasiApp.Native.targets index 03a62b781b7399..75016fede60e73 100644 --- a/src/mono/wasi/build/WasiApp.Native.targets +++ b/src/mono/wasi/build/WasiApp.Native.targets @@ -94,7 +94,7 @@ - + <_WasmCommonCFlags Include="-DGEN_PINVOKE=1" /> - <_WasmCommonCFlags Condition="'$(WasmSingleFileBundle)' == 'true'" Include="-DBUNDLED_ASSEMBLIES=1" /> + <_WasmCommonCFlags Condition="'$(WasmSingleFileBundle)' == 'true'" Include="-DWASM_SINGLE_FILE=1" /> + <_WasmCommonCFlags Condition="'$(InvariantGlobalization)' == 'true'" Include="-DINVARIANT_GLOBALIZATION=1" /> @@ -178,7 +179,6 @@ - @@ -342,19 +342,28 @@ - + <_WasmAssembliesBundleObjectFile>$(_WasmIntermediateOutputPath)wasi_bundled_assemblies.o + <_WasmIcuBundleObjectFile>$(_WasmIntermediateOutputPath)wasi_bundled_icu.o + + + $(_WasmIntermediateOutputPath)%(WasmBundleAssembliesWithHashes.Filename)%(WasmBundleAssembliesWithHashes.Extension).$([System.String]::Copy(%(WasmBundleAssembliesWithHashes.FileHash)).Substring(0, 8)).o + + $(_WasmIntermediateOutputPath)%(WasmBundleIcuWithHashes.Filename)%(WasmBundleIcuWithHashes.Extension).$([System.String]::Copy(%(WasmBundleIcuWithHashes.FileHash)).Substring(0, 8)).o + + + + + + <_WasiObjectFilesForBundle Include="$(_WasmIcuBundleObjectFile)" /> + <_WasiObjectFilesForBundle Include="%(WasmBundleIcuWithHashes.DestinationFile)" /> + + + + + + + @@ -390,8 +419,14 @@ + @@ -411,8 +446,8 @@ <_WasiFilePathForFixup Include="@(_WasmNativeFileForLinking)" /> <_WasiFilePathForFixup Include="@(_WasmRuntimePackSrcFile)" /> - <_WasiSdkClangArgs Condition="'$(OS)' == 'Windows_NT'" Include="$([System.String]::new(%(_WasiFilePathForFixup.Identity)).Replace('\', '/'))" /> - <_WasiSdkClangArgs Condition="'$(OS)' != 'Windows_NT'" Include="@(_WasiFilePathForFixup)" /> + <_WasiSdkClangArgs Condition="'$(OS)' == 'Windows_NT'" Include=""$([System.String]::new(%(_WasiFilePathForFixup.Identity)).Replace('\', '/'))"" /> + <_WasiSdkClangArgs Condition="'$(OS)' != 'Windows_NT'" Include="@(_WasiFilePathForFixup -> '"%(Identity)"')" /> <_WasiSdkClangArgs Include="@(_WasmCommonCFlags)" /> @@ -435,9 +470,9 @@ - + - + diff --git a/src/mono/wasi/build/WasiApp.props b/src/mono/wasi/build/WasiApp.props index 9a063a4d5e92f9..727196d4b246f8 100644 --- a/src/mono/wasi/build/WasiApp.props +++ b/src/mono/wasi/build/WasiApp.props @@ -7,13 +7,11 @@ wasi-wasm true partial - _WasiBuildNativeCore <_WasmBuildCoreDependsOn> _InitializeCommonProperties; _PrepareForAfterBuild; _BeforeWasmBuildApp; - $(WasmBuildNativeTarget); _WasiGenerateAppBundle; diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets index 81b5b8ab1eeec3..190f89f786ab4c 100644 --- a/src/mono/wasi/build/WasiApp.targets +++ b/src/mono/wasi/build/WasiApp.targets @@ -118,6 +118,7 @@ false true + true true wasmtime @@ -165,7 +166,7 @@ + Condition="'$(IsWasiProject)' == 'true' and '$(WasmBuildingForNestedPublish)' != 'true' and '$(IsCrossTargetingBuild)' != 'true'"> + Condition="'$(IsWasiProject)' == 'true' and '$(WasmBuildingForNestedPublish)' == '' and '$(WasmBuildOnlyAfterPublish)' != 'true' and '$(IsCrossTargetingBuild)' != 'true'" /> true - - - + + + + + + + + + - + @@ -378,7 +385,7 @@ - + diff --git a/src/mono/wasi/runtime/CMakeLists.txt b/src/mono/wasi/runtime/CMakeLists.txt index 8f1bc6679c47c3..08bb59b06684a5 100644 --- a/src/mono/wasi/runtime/CMakeLists.txt +++ b/src/mono/wasi/runtime/CMakeLists.txt @@ -6,7 +6,7 @@ option(DISABLE_THREADS "defined if the build does NOT support multithreading" ON option(DISABLE_WASM_USER_THREADS "defined if the build does not allow user threads to be created in a multithreaded build" OFF) set(CMAKE_EXECUTABLE_SUFFIX ".wasm") -add_executable(dotnet driver.c pinvoke.c stubs.c synthetic-pthread.c) +add_executable(dotnet driver.c main.c pinvoke.c stubs.c synthetic-pthread.c) target_include_directories(dotnet PUBLIC ${MONO_INCLUDES} ${MONO_OBJ_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}/include/wasm) target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/wasi-default.rsp @${NATIVE_BIN_DIR}/src/wasi-compile.rsp -DGEN_PINVOKE=1) @@ -29,6 +29,7 @@ target_link_libraries(dotnet ${MONO_ARTIFACTS_DIR}/libmono-icall-table.a ${NATIVE_BIN_DIR}/wasm-bundled-timezones.a ${NATIVE_BIN_DIR}/libSystem.Native.a + ${NATIVE_BIN_DIR}/libSystem.Globalization.Native.a ${NATIVE_BIN_DIR}/libSystem.IO.Compression.Native.a ) diff --git a/src/mono/wasi/runtime/driver.c b/src/mono/wasi/runtime/driver.c index 9c9118c3da478c..52457c50692776 100644 --- a/src/mono/wasi/runtime/driver.c +++ b/src/mono/wasi/runtime/driver.c @@ -63,9 +63,13 @@ void mono_free (void*); int32_t mini_parse_debug_option (const char *option); char *mono_method_get_full_name (MonoMethod *method); extern void mono_wasm_register_timezones_bundle(); -#ifdef BUNDLED_ASSEMBLIES +#ifdef WASM_SINGLE_FILE extern void mono_wasm_register_assemblies_bundle(); -#endif +#ifndef INVARIANT_GLOBALIZATION +extern void mono_wasm_register_icu_bundle(); +#endif /* INVARIANT_GLOBALIZATION */ +extern const unsigned char* mono_wasm_get_bundled_file (const char *name, int* out_length); +#endif /* WASM_SINGLE_FILE */ extern const char* dotnet_wasi_getentrypointassemblyname(); int32_t mono_wasi_load_icu_data(const void* pData); @@ -336,8 +340,19 @@ mono_wasm_register_bundled_satellite_assemblies (void) } } +#ifndef INVARIANT_GLOBALIZATION void load_icu_data (void) { +#ifdef WASM_SINGLE_FILE + mono_wasm_register_icu_bundle(); + + int length = -1; + const unsigned char* buffer = mono_wasm_get_bundled_file("icudt.dat", &length); + if (!buffer) { + printf("Could not load icudt.dat from the bundle"); + assert(buffer); + } +#else /* WASM_SINGLE_FILE */ FILE *fileptr; unsigned char *buffer; long filelen; @@ -360,9 +375,11 @@ void load_icu_data (void) fflush(stdout); } fclose(fileptr); +#endif /* WASM_SINGLE_FILE */ assert(mono_wasi_load_icu_data(buffer)); } +#endif /* INVARIANT_GLOBALIZATION */ void cleanup_runtime_config (MonovmRuntimeConfigArguments *args, void *user_data) @@ -376,18 +393,12 @@ mono_wasm_load_runtime (const char *unused, int debug_level) { const char *interp_opts = ""; - char* invariant_globalization = monoeg_g_getenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); - if (strcmp(invariant_globalization, "true") != 0 && strcmp(invariant_globalization, "1") != 0) - load_icu_data(); - -#ifdef DEBUG - monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); - monoeg_g_setenv ("MONO_LOG_MASK", "all", 0); - // Setting this env var allows Diagnostic.Debug to write to stderr. In a browser environment this - // output will be sent to the console. Right now this is the only way to emit debug logging from - // corlib assemblies. - // monoeg_g_setenv ("DOTNET_DebugWriteToStdErr", "1", 0); -#endif +#ifndef INVARIANT_GLOBALIZATION + char* invariant_globalization = monoeg_g_getenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); + if (strcmp(invariant_globalization, "true") != 0 && strcmp(invariant_globalization, "1") != 0) + load_icu_data(); +#endif /* INVARIANT_GLOBALIZATION */ + char* debugger_fd = monoeg_g_getenv ("DEBUGGER_FD"); if (debugger_fd != 0) @@ -433,7 +444,7 @@ mono_wasm_load_runtime (const char *unused, int debug_level) mini_parse_debug_option ("top-runtime-invoke-unhandled"); mono_wasm_register_timezones_bundle(); -#ifdef BUNDLED_ASSEMBLIES +#ifdef WASM_SINGLE_FILE mono_wasm_register_assemblies_bundle(); #endif mono_dl_fallback_register (wasm_dl_load, wasm_dl_symbol, NULL, NULL); @@ -709,46 +720,3 @@ mono_wasm_string_array_new (int size) { return mono_array_new (root_domain, mono_get_string_class (), size); } - -#ifdef _WASI_DEFAULT_MAIN -/* - * with wasmtime, this is run as: - * $ wasmtime run--dir . dotnet.wasm MainAssembly [args] - * - * - * arg0: dotnet.wasm - * arg1: MainAssembly - * arg2-..: args - */ -int main(int argc, char * argv[]) { - if (argc < 2) { - printf("Error: First argument must be the name of the main assembly\n"); - return 1; - } - - mono_set_assemblies_path("managed"); - mono_wasm_load_runtime("", 0); - - const char *assembly_name = argv[1]; - MonoAssembly* assembly = mono_wasm_assembly_load (assembly_name); - if (!assembly) { - printf("Could not load assembly %s\n", assembly_name); - return 1; - } - MonoMethod* entry_method = mono_wasi_assembly_get_entry_point (assembly); - if (!entry_method) { - fprintf(stderr, "Could not find entrypoint in the assembly.\n"); - exit(1); - } - - MonoObject* out_exc; - MonoObject* out_res; - // Managed app will see: arg0: MainAssembly, arg1-.. [args] - int ret = mono_runtime_run_main(entry_method, argc - 1, &argv[1], &out_exc); - if (out_exc) { - mono_print_unhandled_exception(out_exc); - exit(1); - } - return ret < 0 ? -ret : ret; -} -#endif diff --git a/src/mono/wasi/runtime/main.c b/src/mono/wasi/runtime/main.c index ff0a25e4144064..84ff11517eedb0 100644 --- a/src/mono/wasi/runtime/main.c +++ b/src/mono/wasi/runtime/main.c @@ -15,11 +15,44 @@ int main(int argc, char * argv[]) { #ifdef WASI_AFTER_RUNTIME_LOADED_CALLS // This is supplied from the MSBuild itemgroup @(WasiAfterRuntimeLoaded) WASI_AFTER_RUNTIME_LOADED_CALLS +#endif +#ifndef WASM_SINGLE_FILE + mono_set_assemblies_path("managed"); #endif mono_wasm_load_runtime("", 0); + int arg_ofs = 0; +#ifdef WASM_SINGLE_FILE + /* + * For single-file bundle, running with wasmtime: + * + * $ wasmtime run --dir . MainAssembly.wasm [args] + * + * arg0: MainAssembly + * arg1-..: args + */ const char* assembly_name = dotnet_wasi_getentrypointassemblyname(); MonoAssembly* assembly = mono_assembly_open(assembly_name, NULL); +#else + /* + * For default case which uses dotnet.wasm, running with wasmtime: + * + * $ wasmtime run --dir . dotnet.wasm MainAssembly [args] + * + * arg0: dotnet.wasm + * arg1: MainAssembly + * arg2-..: args + */ + + const char *assembly_name = argv[1]; + arg_ofs = 1; + MonoAssembly* assembly = mono_wasm_assembly_load (assembly_name); + if (!assembly) { + printf("Could not load assembly %s\n", assembly_name); + return 1; + } +#endif + MonoMethod* entry_method = mono_wasi_assembly_get_entry_point (assembly); if (!entry_method) { fprintf(stderr, "Could not find entrypoint in assembly %s\n", assembly_name); @@ -28,7 +61,8 @@ int main(int argc, char * argv[]) { MonoObject* out_exc; MonoObject* out_res; - int ret = mono_runtime_run_main(entry_method, argc, argv, &out_exc); + // Managed app will see: arg0: MainAssembly, arg1-.. [args] + int ret = mono_runtime_run_main(entry_method, argc - arg_ofs, &argv[arg_ofs], &out_exc); if (out_exc) { mono_print_unhandled_exception(out_exc); diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index ea89bec7d5dda7..69aad8fae6825e 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -144,7 +144,6 @@ <_WasiCompileFlags Include="-D_WASI_EMULATED_PROCESS_CLOCKS"/> <_WasiCompileFlags Include="-D_WASI_EMULATED_SIGNAL"/> <_WasiCompileFlags Include="-D_WASI_EMULATED_MMAN"/> - <_WasiCompileFlags Include="-D_WASI_DEFAULT_MAIN"/> <_WasiLinkFlags Include="-Wl,-z,stack-size=8388608,--initial-memory=52428800,-lwasi-emulated-process-clocks,-lwasi-emulated-signal,-lwasi-emulated-mman"/> diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BuildPublishTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BuildPublishTests.cs index c75f008b33210a..463ddae5d58343 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BuildPublishTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BuildPublishTests.cs @@ -197,9 +197,10 @@ public void BugRegression_60479_WithRazorClassLib() .ExecuteWithCapturedOutput("new razorclasslib") .EnsureSuccessful(); - AddItemsPropertiesToProject(wasmProjectFile, extraItems:@" - - + string razorClassLibraryFileName = UseWebcil ? "RazorClassLibrary.webcil" : "RazorClassLibrary.dll"; + AddItemsPropertiesToProject(wasmProjectFile, extraItems: @$" + + "); _projectDir = wasmProjectDir; @@ -222,7 +223,7 @@ public void BugRegression_60479_WithRazorClassLib() throw new XunitException($"Could not find resources.lazyAssembly object in {bootJson}"); } - Assert.Contains("RazorClassLibrary.dll", lazyVal.EnumerateObject().Select(jp => jp.Name)); + Assert.Contains(razorClassLibraryFileName, lazyVal.EnumerateObject().Select(jp => jp.Name)); } [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 0dcbdc6bc1c11a..0d50ada7ad3a20 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -424,7 +424,7 @@ diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index f63ef19eacbc62..9e4538ff4d7c15 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -359,7 +359,7 @@ internal enum StepFilter { internal enum StepSize { Minimal, - Line + LineColumn } internal sealed record ArrayDimensions @@ -1431,7 +1431,7 @@ public async Task Step(int thread_id, StepKind kind, CancellationToken tok commandParamsWriter.Write((byte)1); commandParamsWriter.Write((byte)ModifierKind.Step); commandParamsWriter.Write(thread_id); - commandParamsWriter.Write((int)StepSize.Line); + commandParamsWriter.Write((int)StepSize.LineColumn); commandParamsWriter.Write((int)kind); commandParamsWriter.Write((int)(StepFilter.StaticCtor)); //filter using var retDebuggerCmdReader = await SendDebuggerAgentCommand(CmdEventRequest.Set, commandParamsWriter, token, throwOnError: false); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj index a3ea94f627cfad..913421bc9a748a 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj @@ -23,6 +23,10 @@ + + diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests2.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs similarity index 99% rename from src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests2.cs rename to src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs index 0453341bfd15b6..6d8f0db87111f2 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests2.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs @@ -12,9 +12,9 @@ namespace DebuggerTests { // TODO: static async, static method args - public class EvaluateOnCallFrameTests2 : DebuggerTests + public class EvaluateOnCallFrame2Tests : DebuggerTests { - public EvaluateOnCallFrameTests2(ITestOutputHelper testOutput) : base(testOutput) + public EvaluateOnCallFrame2Tests(ITestOutputHelper testOutput) : base(testOutput) {} public static IEnumerable InstanceMethodsTestData(string type_name) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs index 7778d31eb42e1a..e04639e8e420aa 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs @@ -139,7 +139,7 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn2(bool use_cfo) await CheckString(props, "B", "xx"); await CheckString(props, "c", "20_xx"); - pause_location = await StepAndCheck(StepKind.Over, dep_cs_loc, 25, 8, "Simple.Complex.DoStuff", times: 2); + pause_location = await StepAndCheck(StepKind.Over, dep_cs_loc, 25, 8, "Simple.Complex.DoStuff", times: 4); // Check UseComplex frame again locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][1], debugger_test_loc, 23, 8, "Math.UseComplex"); Assert.Equal(7, locals_m1.Count()); @@ -207,7 +207,7 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) await CheckObject(locals_m1, "nim", "Math.NestedInMath"); // step back into OuterMethod - await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "Math.OuterMethod", times: 6, + await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "Math.OuterMethod", times: 7, locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -247,7 +247,7 @@ await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", } ); - await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "Math.OuterMethod", times: 1, + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "Math.OuterMethod", times: 2, locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -310,7 +310,7 @@ await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", ); // Step back to OuterMethod - await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 90, 8, "Math.OuterMethod", times: 6, + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 90, 8, "Math.OuterMethod", times: 7, locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -483,7 +483,7 @@ public async Task InspectValueTypeMethodArgsWhileStepping(bool use_cfo) // ----------- Step back to the caller --------- pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 30, 12, "DebuggerTests.ValueTypesTest.TestStructsAsMethodArgs", - times: 1, locals_fn: async (l) => { /* non-null to make sure that locals get fetched */ await Task.CompletedTask; }); + times: 2, locals_fn: async (l) => { /* non-null to make sure that locals get fetched */ await Task.CompletedTask; }); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await CheckProps(locals, new { @@ -850,7 +850,7 @@ await EvaluateAndCheck( "dotnet://debugger-test.dll/debugger-test.cs", 552, 8, "HiddenSequencePointTest.MethodWithHiddenLinesAtTheEnd"); - await StepAndCheck(StepKind.Over, source_loc, 544, 4, "HiddenSequencePointTest.StepOverHiddenSP"); + await StepAndCheck(StepKind.Over, source_loc, 544, 4, "HiddenSequencePointTest.StepOverHiddenSP", times:2); } [ConditionalTheory(nameof(RunningOnChrome))] diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-main.js b/src/mono/wasm/debugger/tests/debugger-test/debugger-main.js index eb86874b2144e3..6f39603f1dcffe 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-main.js +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-main.js @@ -3,26 +3,23 @@ "use strict"; -import createDotnetRuntime from './dotnet.js' +import { dotnet, exit } from './dotnet.js' try { - const runtime = await createDotnetRuntime(({ INTERNAL }) => ({ - configSrc: "./mono-config.json", - onConfigLoaded: (config) => { - config.environmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug"; - /* For custom logging patch the functions below - config.diagnosticTracing = true; - config.environmentVariables["MONO_LOG_LEVEL"] = "debug"; - config.environmentVariables["MONO_LOG_MASK"] = "all"; - INTERNAL.logging = { - trace: (domain, log_level, message, isFatal, dataPtr) => console.log({ domain, log_level, message, isFatal, dataPtr }), - debugger: (level, message) => console.log({ level, message }), - }; - */ - }, - })); + const runtime = await dotnet + .withEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES", "debug") + // For custom logging patch the functions below + //.withDiagnosticTracing(true) + //.withEnvironmentVariable("MONO_LOG_LEVEL", "debug") + //.withEnvironmentVariable("MONO_LOG_MASK", "all") + .create(); + /*runtime.INTERNAL.logging = { + trace: (domain, log_level, message, isFatal, dataPtr) => console.log({ domain, log_level, message, isFatal, dataPtr }), + debugger: (level, message) => console.log({ level, message }), + };*/ App.runtime = runtime; await App.init(); -} catch (err) { - console.log(`WASM ERROR ${err}`); } +catch (err) { + exit(2, err); +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index 4fcf86852c715a..4d3781bb924f68 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -30,11 +30,12 @@ target_link_libraries(dotnet ${MONO_ARTIFACTS_DIR}/libmono-profiler-browser.a ${NATIVE_BIN_DIR}/wasm-bundled-timezones.a ${NATIVE_BIN_DIR}/libSystem.Native.a + ${NATIVE_BIN_DIR}/libSystem.Globalization.Native.a ${NATIVE_BIN_DIR}/libSystem.IO.Compression.Native.a) set_target_properties(dotnet PROPERTIES - LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js;${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js;${NATIVE_BIN_DIR}/src/pal_random.lib.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.post.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.extpost.js;" - LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-link.rsp ${CONFIGURATION_LINK_FLAGS} --extern-pre-js ${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js --js-library ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.post.js --extern-post-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.extpost.js " + LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js;${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js;${NATIVE_BIN_DIR}/src/pal_random.lib.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.extpost.js;" + LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-link.rsp ${CONFIGURATION_LINK_FLAGS} --extern-pre-js ${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js --js-library ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --extern-post-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.extpost.js " RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}") set(ignoreMeWasmOptFlags "${CONFIGURATION_WASM_OPT_FLAGS}") diff --git a/src/mono/wasm/runtime/assets.ts b/src/mono/wasm/runtime/assets.ts index b829f03bd32d97..37977538ed3a01 100644 --- a/src/mono/wasm/runtime/assets.ts +++ b/src/mono/wasm/runtime/assets.ts @@ -3,14 +3,15 @@ import cwraps from "./cwraps"; import { mono_wasm_load_icu_data } from "./icu"; -import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./imports"; +import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./globals"; import { parseSymbolMapFile } from "./logging"; import { mono_wasm_load_bytes_into_heap } from "./memory"; import { endMeasure, MeasuredBlock, startMeasure } from "./profiler"; import { createPromiseController, PromiseAndController } from "./promise-controller"; import { delay } from "./promise-utils"; import { abort_startup, beforeOnRuntimeInitialized, memorySnapshotSkippedOrDone } from "./startup"; -import { AssetBehaviours, AssetEntry, AssetEntryInternal, LoadingResource, mono_assert, ResourceRequest } from "./types"; +import { AssetEntryInternal, mono_assert } from "./types"; +import { AssetBehaviours, AssetEntry, LoadingResource, ResourceRequest } from "./types-api"; import { InstantiateWasmSuccessCallback, VoidPtr } from "./types/emscripten"; const allAssetsInMemory = createPromiseController(); @@ -314,7 +315,7 @@ async function start_asset_download_sources(asset: AssetEntryInternal): Promise< const loadingResource = download_resource(asset); asset.pendingDownloadInternal = loadingResource; response = await loadingResource.response; - if (!response.ok) { + if (!response || !response.ok) { continue;// next source } return response; @@ -513,9 +514,15 @@ export async function instantiate_wasm_asset( } const arrayBuffer = await response.arrayBuffer(); if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: instantiate_wasm_module buffered"); - const arrayBufferResult = await WebAssembly.instantiate(arrayBuffer, wasmModuleImports!); - compiledInstance = arrayBufferResult.instance; - compiledModule = arrayBufferResult.module; + if (ENVIRONMENT_IS_SHELL) { + // workaround for old versions of V8 with https://bugs.chromium.org/p/v8/issues/detail?id=13823 + compiledModule = new WebAssembly.Module(arrayBuffer); + compiledInstance = new WebAssembly.Instance(compiledModule, wasmModuleImports); + } else { + const arrayBufferResult = await WebAssembly.instantiate(arrayBuffer, wasmModuleImports!); + compiledInstance = arrayBufferResult.instance; + compiledModule = arrayBufferResult.module; + } } successCallback(compiledInstance, compiledModule); } diff --git a/src/mono/wasm/runtime/blazor/BootConfig.ts b/src/mono/wasm/runtime/blazor/BootConfig.ts index 5100603f64c928..48c033b7368b38 100644 --- a/src/mono/wasm/runtime/blazor/BootConfig.ts +++ b/src/mono/wasm/runtime/blazor/BootConfig.ts @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { Module } from "../imports"; -import { WebAssemblyBootResourceType } from "./WebAssemblyStartOptions"; +import { Module } from "../globals"; +import { WebAssemblyBootResourceType } from "../types-api"; type LoadBootResourceCallback = (type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string) => string | Promise | null | undefined; diff --git a/src/mono/wasm/runtime/blazor/WebAssemblyResourceLoader.ts b/src/mono/wasm/runtime/blazor/WebAssemblyResourceLoader.ts index 73e363693cd7e7..c0840f6edb1ad9 100644 --- a/src/mono/wasm/runtime/blazor/WebAssemblyResourceLoader.ts +++ b/src/mono/wasm/runtime/blazor/WebAssemblyResourceLoader.ts @@ -1,9 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +import { WebAssemblyBootResourceType, WebAssemblyStartOptions } from "../types-api"; import { toAbsoluteUri } from "./_Polyfill"; import { BootJsonData, ResourceList } from "./BootConfig"; -import { WebAssemblyStartOptions, WebAssemblyBootResourceType } from "./WebAssemblyStartOptions"; const networkFetchCacheMode = "no-cache"; export class WebAssemblyResourceLoader { diff --git a/src/mono/wasm/runtime/blazor/WebAssemblyStartOptions.ts b/src/mono/wasm/runtime/blazor/WebAssemblyStartOptions.ts deleted file mode 100644 index 3f8c0fc4b811fa..00000000000000 --- a/src/mono/wasm/runtime/blazor/WebAssemblyStartOptions.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -export interface WebAssemblyStartOptions { - /** - * Overrides the built-in boot resource loading mechanism so that boot resources can be fetched - * from a custom source, such as an external CDN. - * @param type The type of the resource to be loaded. - * @param name The name of the resource to be loaded. - * @param defaultUri The URI from which the framework would fetch the resource by default. The URI may be relative or absolute. - * @param integrity The integrity string representing the expected content in the response. - * @returns A URI string or a Response promise to override the loading process, or null/undefined to allow the default loading behavior. - */ - loadBootResource(type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string): string | Promise | null | undefined; - - /** - * Override built-in environment setting on start. - */ - environment?: string; - - /** - * Gets the application culture. This is a name specified in the BCP 47 format. See https://tools.ietf.org/html/bcp47 - */ - applicationCulture?: string; -} - -// This type doesn't have to align with anything in BootConfig. -// Instead, this represents the public API through which certain aspects -// of boot resource loading can be customized. -export type WebAssemblyBootResourceType = "assembly" | "pdb" | "dotnetjs" | "dotnetwasm" | "globalization" | "manifest" | "configuration"; diff --git a/src/mono/wasm/runtime/blazor/_Integration.ts b/src/mono/wasm/runtime/blazor/_Integration.ts index 7518796505091c..64896bfaa013c8 100644 --- a/src/mono/wasm/runtime/blazor/_Integration.ts +++ b/src/mono/wasm/runtime/blazor/_Integration.ts @@ -1,8 +1,8 @@ -import { INTERNAL, Module } from "../imports"; -import { AssetEntry, LoadingResource, MonoConfigInternal } from "../types"; +import { INTERNAL, Module } from "../globals"; +import { MonoConfigInternal } from "../types"; +import { AssetEntry, LoadingResource, WebAssemblyBootResourceType } from "../types-api"; import { BootConfigResult, BootJsonData, ICUDataMode } from "./BootConfig"; import { WebAssemblyResourceLoader } from "./WebAssemblyResourceLoader"; -import { WebAssemblyBootResourceType } from "./WebAssemblyStartOptions"; import { hasDebuggingEnabled } from "./_Polyfill"; export async function loadBootConfig(config: MonoConfigInternal,) { diff --git a/src/mono/wasm/runtime/config.ts b/src/mono/wasm/runtime/config.ts new file mode 100644 index 00000000000000..34e92f032cbaa2 --- /dev/null +++ b/src/mono/wasm/runtime/config.ts @@ -0,0 +1,28 @@ +import type { DotnetModuleInternal, MonoConfigInternal } from "./types"; +import { DotnetModuleConfig } from "./types-api"; + +export function deep_merge_config(target: MonoConfigInternal, source: MonoConfigInternal): MonoConfigInternal { + const providedConfig: MonoConfigInternal = { ...source }; + if (providedConfig.assets) { + providedConfig.assets = [...(target.assets || []), ...(providedConfig.assets || [])]; + } + if (providedConfig.environmentVariables) { + providedConfig.environmentVariables = { ...(target.environmentVariables || {}), ...(providedConfig.environmentVariables || {}) }; + } + if (providedConfig.startupOptions) { + providedConfig.startupOptions = { ...(target.startupOptions || {}), ...(providedConfig.startupOptions || {}) }; + } + if (providedConfig.runtimeOptions) { + providedConfig.runtimeOptions = [...(target.runtimeOptions || []), ...(providedConfig.runtimeOptions || [])]; + } + return Object.assign(target, providedConfig); +} + +export function deep_merge_module(target: DotnetModuleInternal, source: DotnetModuleConfig): DotnetModuleInternal { + const providedConfig: DotnetModuleConfig = { ...source }; + if (providedConfig.config) { + if (!target.config) target.config = {}; + providedConfig.config = deep_merge_config(target.config, providedConfig.config); + } + return Object.assign(target, providedConfig); +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index ded8b022d7ddff..0b196d087ea8b4 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -46,6 +46,8 @@ extern void* mono_wasm_invoke_js_blazor (MonoString **exceptionMessage, void *ca extern void mono_wasm_change_case_invariant(MonoString **exceptionMessage, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper); extern void mono_wasm_change_case(MonoString **exceptionMessage, MonoString **culture, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper); extern int mono_wasm_compare_string(MonoString **exceptionMessage, MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options); +extern mono_bool mono_wasm_starts_with(MonoString **exceptionMessage, MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options); +extern mono_bool mono_wasm_ends_with(MonoString **exceptionMessage, MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options); void bindings_initialize_internals (void) { @@ -77,4 +79,6 @@ void bindings_initialize_internals (void) mono_add_internal_call ("Interop/JsGlobalization::ChangeCaseInvariant", mono_wasm_change_case_invariant); mono_add_internal_call ("Interop/JsGlobalization::ChangeCase", mono_wasm_change_case); mono_add_internal_call ("Interop/JsGlobalization::CompareString", mono_wasm_compare_string); + mono_add_internal_call ("Interop/JsGlobalization::StartsWith", mono_wasm_starts_with); + mono_add_internal_call ("Interop/JsGlobalization::EndsWith", mono_wasm_ends_with); } diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index c7f73b34db5282..6c6912fd6b6c99 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -8,7 +8,7 @@ import type { } from "./types"; import type { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten"; import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; -import { disableLegacyJsInterop, Module } from "./imports"; +import { disableLegacyJsInterop, Module } from "./globals"; type SigLine = [lazy: boolean, name: string, returnType: string | null, argTypes?: string[], opts?: any]; diff --git a/src/mono/wasm/runtime/debug.ts b/src/mono/wasm/runtime/debug.ts index bb856bf45aa33b..7dcc132ff4518d 100644 --- a/src/mono/wasm/runtime/debug.ts +++ b/src/mono/wasm/runtime/debug.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import BuildConfiguration from "consts:configuration"; -import { INTERNAL, Module, runtimeHelpers } from "./imports"; +import { INTERNAL, Module, runtimeHelpers } from "./globals"; import { toBase64StringImpl } from "./base64"; import cwraps from "./cwraps"; import { VoidPtr, CharPtr } from "./types/emscripten"; diff --git a/src/mono/wasm/runtime/diagnostics/browser/controller.ts b/src/mono/wasm/runtime/diagnostics/browser/controller.ts index 35ccb1d64207d4..9eedcdd80aaeff 100644 --- a/src/mono/wasm/runtime/diagnostics/browser/controller.ts +++ b/src/mono/wasm/runtime/diagnostics/browser/controller.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import cwraps from "../../cwraps"; -import { INTERNAL } from "../../imports"; +import { INTERNAL } from "../../globals"; import { withStackAlloc, getI32 } from "../../memory"; import { Thread, waitForThread } from "../../pthreads/browser"; import { isDiagnosticMessage, makeDiagnosticServerControlCommand } from "../shared/controller-commands"; diff --git a/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts b/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts index 4f757d092970c6..9d55897033a652 100644 --- a/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts +++ b/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts @@ -6,7 +6,7 @@ import monoDiagnosticsMock from "consts:monoDiagnosticsMock"; import { assertNever } from "../../types"; import { pthread_self } from "../../pthreads/worker"; -import { Module } from "../../imports"; +import { Module } from "../../globals"; import cwraps from "../../cwraps"; import { EventPipeSessionIDImpl } from "../shared/types"; import { CharPtr } from "../../types/emscripten"; diff --git a/src/mono/wasm/runtime/diagnostics/server_pthread/mock-remote.ts b/src/mono/wasm/runtime/diagnostics/server_pthread/mock-remote.ts index 47e98e29b36b57..f30b99175de857 100644 --- a/src/mono/wasm/runtime/diagnostics/server_pthread/mock-remote.ts +++ b/src/mono/wasm/runtime/diagnostics/server_pthread/mock-remote.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import monoDiagnosticsMock from "consts:monoDiagnosticsMock"; -import { runtimeHelpers } from "../../imports"; +import { runtimeHelpers } from "../../globals"; import type { Mock } from "../mock"; import { mock } from "../mock"; diff --git a/src/mono/wasm/runtime/diagnostics/server_pthread/socket-connection.ts b/src/mono/wasm/runtime/diagnostics/server_pthread/socket-connection.ts index 47e216f1a7060c..cc3a8d838524dc 100644 --- a/src/mono/wasm/runtime/diagnostics/server_pthread/socket-connection.ts +++ b/src/mono/wasm/runtime/diagnostics/server_pthread/socket-connection.ts @@ -3,7 +3,7 @@ import { assertNever } from "../../types"; import { VoidPtr } from "../../types/emscripten"; -import { Module } from "../../imports"; +import { Module } from "../../globals"; import type { CommonSocket } from "./common-socket"; enum ListenerState { Sending, diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index 111491048da668..8b8f2e9d4d01e6 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -5,69 +5,6 @@ //! This is not considered public API with backward compatibility guarantees. -interface BootJsonData { - readonly entryAssembly: string; - readonly resources: ResourceGroups; - /** Gets a value that determines if this boot config was produced from a non-published build (i.e. dotnet build or dotnet run) */ - readonly debugBuild: boolean; - readonly linkerEnabled: boolean; - readonly cacheBootResources: boolean; - readonly config: string[]; - readonly icuDataMode: ICUDataMode; - readonly startupMemoryCache: boolean | undefined; - readonly runtimeOptions: string[] | undefined; - modifiableAssemblies: string | null; - aspnetCoreBrowserTools: string | null; -} -type BootJsonDataExtension = { - [extensionName: string]: ResourceList; -}; -interface ResourceGroups { - readonly assembly: ResourceList; - readonly lazyAssembly: ResourceList; - readonly pdb?: ResourceList; - readonly runtime: ResourceList; - readonly satelliteResources?: { - [cultureName: string]: ResourceList; - }; - readonly libraryInitializers?: ResourceList; - readonly extensions?: BootJsonDataExtension; - readonly runtimeAssets: ExtendedResourceList; -} -type ResourceList = { - [name: string]: string; -}; -type ExtendedResourceList = { - [name: string]: { - hash: string; - behavior: string; - }; -}; -declare enum ICUDataMode { - Sharded = 0, - All = 1, - Invariant = 2, - Custom = 3 -} - -interface DotnetHostBuilder { - withConfig(config: MonoConfig): DotnetHostBuilder; - withConfigSrc(configSrc: string): DotnetHostBuilder; - withApplicationArguments(...args: string[]): DotnetHostBuilder; - withEnvironmentVariable(name: string, value: string): DotnetHostBuilder; - withEnvironmentVariables(variables: { - [i: string]: string; - }): DotnetHostBuilder; - withVirtualWorkingDirectory(vfsPath: string): DotnetHostBuilder; - withDiagnosticTracing(enabled: boolean): DotnetHostBuilder; - withDebugging(level: number): DotnetHostBuilder; - withMainAssembly(mainAssemblyName: string): DotnetHostBuilder; - withApplicationArgumentsFromQuery(): DotnetHostBuilder; - withStartupMemoryCache(value: boolean): DotnetHostBuilder; - create(): Promise; - run(): Promise; -} - declare interface NativePointer { __brandNativePointer: "NativePointer"; } @@ -121,6 +58,22 @@ type InstantiateWasmSuccessCallback = (instance: WebAssembly.Instance, module: W type InstantiateWasmCallBack = (imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback) => any; declare type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; +interface DotnetHostBuilder { + withConfig(config: MonoConfig): DotnetHostBuilder; + withConfigSrc(configSrc: string): DotnetHostBuilder; + withApplicationArguments(...args: string[]): DotnetHostBuilder; + withEnvironmentVariable(name: string, value: string): DotnetHostBuilder; + withEnvironmentVariables(variables: { + [i: string]: string; + }): DotnetHostBuilder; + withVirtualWorkingDirectory(vfsPath: string): DotnetHostBuilder; + withDiagnosticTracing(enabled: boolean): DotnetHostBuilder; + withDebugging(level: number): DotnetHostBuilder; + withMainAssembly(mainAssemblyName: string): DotnetHostBuilder; + withApplicationArgumentsFromQuery(): DotnetHostBuilder; + create(): Promise; + run(): Promise; +} type MonoConfig = { /** * The subfolder containing managed assemblies and pdbs. This is relative to dotnet.js script. @@ -297,8 +250,52 @@ type ModuleAPI = { dotnet: DotnetHostBuilder; exit: (code: number, reason?: any) => void; }; -declare function createDotnetRuntime(moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)): Promise; -type CreateDotnetRuntimeType = typeof createDotnetRuntime; +type CreateDotnetRuntimeType = (moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)) => Promise; + +interface BootJsonData { + readonly entryAssembly: string; + readonly resources: ResourceGroups; + /** Gets a value that determines if this boot config was produced from a non-published build (i.e. dotnet build or dotnet run) */ + readonly debugBuild: boolean; + readonly linkerEnabled: boolean; + readonly cacheBootResources: boolean; + readonly config: string[]; + readonly icuDataMode: ICUDataMode; + readonly startupMemoryCache: boolean | undefined; + readonly runtimeOptions: string[] | undefined; + modifiableAssemblies: string | null; + aspnetCoreBrowserTools: string | null; +} +type BootJsonDataExtension = { + [extensionName: string]: ResourceList; +}; +interface ResourceGroups { + readonly assembly: ResourceList; + readonly lazyAssembly: ResourceList; + readonly pdb?: ResourceList; + readonly runtime: ResourceList; + readonly satelliteResources?: { + [cultureName: string]: ResourceList; + }; + readonly libraryInitializers?: ResourceList; + readonly extensions?: BootJsonDataExtension; + readonly runtimeAssets: ExtendedResourceList; +} +type ResourceList = { + [name: string]: string; +}; +type ExtendedResourceList = { + [name: string]: { + hash: string; + behavior: string; + }; +}; +declare enum ICUDataMode { + Sharded = 0, + All = 1, + Invariant = 2, + Custom = 3 +} interface IDisposable { dispose(): void; @@ -324,11 +321,14 @@ interface IMemoryView extends IDisposable { get byteLength(): number; } +declare function mono_exit(exit_code: number, reason?: any): void; + +declare const dotnet: DotnetHostBuilder; +declare const exit: typeof mono_exit; + declare global { function getDotnetRuntime(runtimeId: number): RuntimeAPI | undefined; } - -declare const dotnet: ModuleAPI["dotnet"]; -declare const exit: ModuleAPI["exit"]; +declare const createDotnetRuntime: CreateDotnetRuntimeType; export { AssetEntry, BootJsonData, CreateDotnetRuntimeType, DotnetModuleConfig, EmscriptenModule, ICUDataMode, IMemoryView, ModuleAPI, MonoConfig, ResourceRequest, RuntimeAPI, createDotnetRuntime as default, dotnet, exit }; diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.extpost.js b/src/mono/wasm/runtime/es6/dotnet.es6.extpost.js index f852ad05419b2c..7c42d93dd9c138 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.extpost.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.extpost.js @@ -1,10 +1,6 @@ -const ENVIRONMENT_IS_WEB = typeof window == "object"; -const ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string"; -const MONO = {}, BINDING = {}, INTERNAL = {}, IMPORTS = {}; + var fetch = fetch || undefined; var require = require || undefined; var __dirname = __dirname || ''; -__dotnet_runtime.__setEmscriptenEntrypoint(createDotnetRuntime); -const __initializeImportsAndExports = __dotnet_runtime.__initializeImportsAndExports; -const __requirePromise = ENVIRONMENT_IS_NODE ? import(/* webpackIgnore: true */'module').then(mod => mod.createRequire(import.meta.url)) : undefined; -const dotnet = __dotnet_runtime.moduleExports.dotnet; -const exit = __dotnet_runtime.moduleExports.exit; -export { dotnet, exit, INTERNAL }; +var createEmscripten = createDotnetRuntime; +var unifyModuleConfig = __dotnet_runtime.unifyModuleConfig; +export const dotnet = __dotnet_runtime.dotnet; +export const exit = __dotnet_runtime.exit; \ No newline at end of file diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 2403db26b3205b..b23d1981049550 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -4,58 +4,75 @@ "use strict"; -// USE_PTHREADS is emscripten's define symbol, which is passed to acorn optimizer, so we could use it here -#if USE_PTHREADS -const monoWasmThreads = true; -const isPThread = `ENVIRONMENT_IS_PTHREAD`; -#else -const monoWasmThreads = false; -const isPThread = "false"; -#endif // because we can't pass custom define symbols to acorn optimizer, we use environment variables to pass other build options const DISABLE_LEGACY_JS_INTEROP = process.env.DISABLE_LEGACY_JS_INTEROP === "1"; -const disableLegacyJsInterop = DISABLE_LEGACY_JS_INTEROP ? "true" : "false"; -const DotnetSupportLib = { - $DOTNET: {}, - // this line will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IIFE - // Emscripten uses require function for nodeJS even in ES6 module. We need https://nodejs.org/api/module.html#modulecreaterequirefilename - // We use dynamic import because there is no "module" module in the browser. - // This is async init of it, note it would become available only after first tick. - // Also fix of scriptDirectory would be delayed - // Emscripten's getBinaryPromise is not async for NodeJs, but we would like to have it async, so we replace it. - // We also replace implementation of fetch - $DOTNET__postset: ` -let __dotnet_replacement_PThread = ${monoWasmThreads} ? {} : undefined; -${monoWasmThreads ? ` -__dotnet_replacement_PThread.loadWasmModuleToWorker = PThread.loadWasmModuleToWorker; -__dotnet_replacement_PThread.threadInitTLS = PThread.threadInitTLS; -__dotnet_replacement_PThread.allocateUnusedWorker = PThread.allocateUnusedWorker; -` : ''} -let __dotnet_replacements = {scriptUrl: import.meta.url, fetch: globalThis.fetch, require, updateMemoryViews, pthreadReplacements: __dotnet_replacement_PThread}; -if (ENVIRONMENT_IS_NODE) { - __dotnet_replacements.requirePromise = __requirePromise; -} -let __dotnet_exportedAPI = __initializeImportsAndExports( - { isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isWorker:ENVIRONMENT_IS_WORKER, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, isPThread:${isPThread}, disableLegacyJsInterop:${disableLegacyJsInterop}, quit_, ExitStatus, requirePromise:__dotnet_replacements.requirePromise }, - { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module, marshaled_imports: IMPORTS }, - __dotnet_replacements, __callbackAPI); -updateMemoryViews = __dotnet_replacements.updateMemoryViews; -fetch = __dotnet_replacements.fetch; -_scriptDir = __dirname = scriptDirectory = __dotnet_replacements.scriptDirectory; -if (ENVIRONMENT_IS_NODE) { - __dotnet_replacements.requirePromise.then(someRequire => { - require = someRequire; +function setup(disableLegacyJsInterop) { + const pthreadReplacements = {}; + const dotnet_replacements = { + scriptUrl: import.meta.url, + fetch: globalThis.fetch, + require, + updateMemoryViews, + pthreadReplacements, + scriptDirectory, + noExitRuntime + }; + // USE_PTHREADS is emscripten's define symbol, which is passed to acorn optimizer, so we could use it here + #if USE_PTHREADS + pthreadReplacements.loadWasmModuleToWorker = PThread.loadWasmModuleToWorker; + pthreadReplacements.threadInitTLS = PThread.threadInitTLS; + pthreadReplacements.allocateUnusedWorker = PThread.allocateUnusedWorker; + #else + const ENVIRONMENT_IS_PTHREAD = false; + #endif + if (ENVIRONMENT_IS_NODE) { + dotnet_replacements.requirePromise = import(/* webpackIgnore: true */'module').then(mod => mod.createRequire(import.meta.url)); + dotnet_replacements.requirePromise.then(someRequire => { + require = someRequire; + }); + } + + __dotnet_runtime.passEmscriptenInternals({ + isWorker: ENVIRONMENT_IS_WORKER, + isShell: ENVIRONMENT_IS_SHELL, + isPThread: ENVIRONMENT_IS_PTHREAD, + disableLegacyJsInterop, + quit_, ExitStatus }); + + #if USE_PTHREADS + if (ENVIRONMENT_IS_PTHREAD) { + Module.config = {}; + __dotnet_runtime.initializeReplacements(dotnet_replacements); + __dotnet_runtime.configureWorkerStartup(Module); + } else { + #endif + __dotnet_runtime.initializeReplacements(dotnet_replacements); + __dotnet_runtime.configureEmscriptenStartup(Module); + #if USE_PTHREADS + } + #endif + + updateMemoryViews = dotnet_replacements.updateMemoryViews; + noExitRuntime = dotnet_replacements.noExitRuntime; + fetch = dotnet_replacements.fetch; + _scriptDir = __dirname = scriptDirectory = dotnet_replacements.scriptDirectory; + #if USE_PTHREADS + PThread.loadWasmModuleToWorker = pthreadReplacements.loadWasmModuleToWorker; + PThread.threadInitTLS = pthreadReplacements.threadInitTLS; + PThread.allocateUnusedWorker = pthreadReplacements.allocateUnusedWorker; + #endif } -var noExitRuntime = __dotnet_replacements.noExitRuntime; -${monoWasmThreads ? ` -PThread.loadWasmModuleToWorker = __dotnet_replacements.pthreadReplacements.loadWasmModuleToWorker; -PThread.threadInitTLS = __dotnet_replacements.pthreadReplacements.threadInitTLS; -PThread.allocateUnusedWorker = __dotnet_replacements.pthreadReplacements.allocateUnusedWorker; -` : ''} -`, + +const postset = ` + DOTNET.setup(${DISABLE_LEGACY_JS_INTEROP ? "true" : "false"}); +`; + +const DotnetSupportLib = { + $DOTNET: { setup }, + $DOTNET__postset: postset }; // the methods would be visible to EMCC linker @@ -101,22 +118,24 @@ let linked_functions = [ "mono_wasm_change_case_invariant", "mono_wasm_change_case", "mono_wasm_compare_string", + "mono_wasm_starts_with", + "mono_wasm_ends_with", "icudt68_dat", ]; -if (monoWasmThreads) { - linked_functions = [...linked_functions, - /// mono-threads-wasm.c - "mono_wasm_pthread_on_pthread_attached", - // threads.c - "mono_wasm_eventloop_has_unsettled_interop_promises", - // diagnostics_server.c - "mono_wasm_diagnostic_server_on_server_thread_created", - "mono_wasm_diagnostic_server_on_runtime_server_init", - "mono_wasm_diagnostic_server_stream_signal_work_available", - ] -} +#if USE_PTHREADS +linked_functions = [...linked_functions, + /// mono-threads-wasm.c + "mono_wasm_pthread_on_pthread_attached", + // threads.c + "mono_wasm_eventloop_has_unsettled_interop_promises", + // diagnostics_server.c + "mono_wasm_diagnostic_server_on_server_thread_created", + "mono_wasm_diagnostic_server_on_runtime_server_init", + "mono_wasm_diagnostic_server_stream_signal_work_available", +] +#endif if (!DISABLE_LEGACY_JS_INTEROP) { linked_functions = [...linked_functions, "mono_wasm_invoke_js_with_args_ref", diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.post.js b/src/mono/wasm/runtime/es6/dotnet.es6.post.js deleted file mode 100644 index f39dd3f847f80f..00000000000000 --- a/src/mono/wasm/runtime/es6/dotnet.es6.post.js +++ /dev/null @@ -1 +0,0 @@ -createDotnetRuntime.ready = createDotnetRuntime.ready.then(() => { return __dotnet_exportedAPI; }); \ No newline at end of file diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.pre.js b/src/mono/wasm/runtime/es6/dotnet.es6.pre.js index 67102e3458d41f..3ecc1bcdc9be79 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.pre.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.pre.js @@ -1,20 +1 @@ -var __callbackAPI = { MONO, BINDING, INTERNAL, IMPORTS }; -if (typeof createDotnetRuntime === "function") { - __callbackAPI.Module = Module = { ready: Module.ready }; - const extension = createDotnetRuntime(__callbackAPI) - if (extension.ready) { - throw new Error("MONO_WASM: Module.ready couldn't be redefined.") - } - Object.assign(Module, extension); - createDotnetRuntime = Module; - if (!createDotnetRuntime.locateFile) createDotnetRuntime.locateFile = createDotnetRuntime.__locateFile = (path) => scriptDirectory + path; -} -else if (typeof createDotnetRuntime === "object") { - __callbackAPI.Module = Module = { ready: Module.ready, __undefinedConfig: Object.keys(createDotnetRuntime).length === 1 }; - Object.assign(Module, createDotnetRuntime); - createDotnetRuntime = Module; - if (!createDotnetRuntime.locateFile) createDotnetRuntime.locateFile = createDotnetRuntime.__locateFile = (path) => scriptDirectory + path; -} -else { - throw new Error("MONO_WASM: Can't use moduleFactory callback of createDotnetRuntime function.") -} \ No newline at end of file +createDotnetRuntime = Module = unifyModuleConfig(Module, createDotnetRuntime); \ No newline at end of file diff --git a/src/mono/wasm/runtime/export-api.ts b/src/mono/wasm/runtime/export-api.ts index 63d081087380e0..e258beaa3801bc 100644 --- a/src/mono/wasm/runtime/export-api.ts +++ b/src/mono/wasm/runtime/export-api.ts @@ -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. -import { runtimeHelpers } from "./imports"; +import type { MonoConfig, APIType } from "./types-api"; + +import { runtimeHelpers } from "./globals"; import { mono_wasm_get_assembly_exports } from "./invoke-cs"; import { mono_wasm_set_module_imports } from "./invoke-js"; import { getB32, getF32, getF64, getI16, getI32, getI52, getI64Big, getI8, getU16, getU32, getU52, getU8, setB32, setF32, setF64, setI16, setI32, setI52, setI64Big, setI8, setU16, setU32, setU52, setU8 } from "./memory"; -import { mono_run_main, mono_run_main_and_exit, mono_exit } from "./run"; -import { dotnet } from "./run-outer"; +import { mono_run_main, mono_run_main_and_exit } from "./run"; import { mono_wasm_setenv } from "./startup"; -import { APIType, ModuleAPI, MonoConfig } from "./types"; export function export_api(): any { const api: APIType = { @@ -47,11 +47,3 @@ export function export_api(): any { }; return api; } - -export function export_module(): ModuleAPI { - const exports: ModuleAPI = { - dotnet, - exit: mono_exit - }; - return exports; -} \ No newline at end of file diff --git a/src/mono/wasm/runtime/export-types.ts b/src/mono/wasm/runtime/export-types.ts index 1221d3f2fc0bba..f81661e365e1f7 100644 --- a/src/mono/wasm/runtime/export-types.ts +++ b/src/mono/wasm/runtime/export-types.ts @@ -1,25 +1,24 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { BootJsonData, ICUDataMode } from "./blazor/BootConfig"; -import { IMemoryView } from "./marshal"; -import { createDotnetRuntime, CreateDotnetRuntimeType, DotnetModuleConfig, RuntimeAPI, MonoConfig, ModuleAPI, AssetEntry, ResourceRequest } from "./types"; -import { EmscriptenModule } from "./types/emscripten"; +import type { BootJsonData, ICUDataMode } from "./blazor/BootConfig"; +import type { IMemoryView } from "./marshal"; +import type { CreateDotnetRuntimeType, DotnetModuleConfig, RuntimeAPI, MonoConfig, ModuleAPI, AssetEntry, ResourceRequest } from "./types-api"; +import type { EmscriptenModule } from "./types/emscripten"; +import type { dotnet, exit } from "./exports"; // ----------------------------------------------------------- // this files has all public exports from the dotnet.js module // ----------------------------------------------------------- - // Here, declare things that go in the global namespace, or augment existing declarations in the global namespace declare global { function getDotnetRuntime(runtimeId: number): RuntimeAPI | undefined; } -export default createDotnetRuntime; +declare const createDotnetRuntime: CreateDotnetRuntimeType; -declare const dotnet: ModuleAPI["dotnet"]; -declare const exit: ModuleAPI["exit"]; +export default createDotnetRuntime; export { EmscriptenModule, diff --git a/src/mono/wasm/runtime/exports-internal.ts b/src/mono/wasm/runtime/exports-internal.ts index fdd68c0f830a01..14f5709555576d 100644 --- a/src/mono/wasm/runtime/exports-internal.ts +++ b/src/mono/wasm/runtime/exports-internal.ts @@ -5,7 +5,7 @@ import { mono_wasm_cancel_promise } from "./cancelable-promise"; import cwraps from "./cwraps"; import { mono_wasm_send_dbg_command_with_parms, mono_wasm_send_dbg_command, mono_wasm_get_dbg_command_info, mono_wasm_get_details, mono_wasm_release_object, mono_wasm_call_function_on, mono_wasm_debugger_resume, mono_wasm_detach_debugger, mono_wasm_raise_debug_event, mono_wasm_change_debugger_log_level, mono_wasm_debugger_attached } from "./debug"; import { http_wasm_supports_streaming_response, http_wasm_create_abort_controler, http_wasm_abort_request, http_wasm_abort_response, http_wasm_fetch, http_wasm_fetch_bytes, http_wasm_get_response_header_names, http_wasm_get_response_header_values, http_wasm_get_response_bytes, http_wasm_get_response_length, http_wasm_get_streamed_response_bytes } from "./http"; -import { exportedRuntimeAPI, Module, runtimeHelpers } from "./imports"; +import { exportedRuntimeAPI, Module, runtimeHelpers } from "./globals"; import { get_property, set_property, has_property, get_typeof_property, get_global_this, dynamic_import } from "./invoke-js"; import { mono_intern_string } from "./strings"; import { mono_wasm_stringify_as_error_with_stack } from "./logging"; diff --git a/src/mono/wasm/runtime/exports-linker.ts b/src/mono/wasm/runtime/exports-linker.ts index ed75ea9df9a667..417cb51e478446 100644 --- a/src/mono/wasm/runtime/exports-linker.ts +++ b/src/mono/wasm/runtime/exports-linker.ts @@ -27,7 +27,7 @@ import { mono_wasm_invoke_js_blazor, mono_wasm_invoke_js_with_args_ref, mono_wasm_get_object_property_ref, mono_wasm_set_object_property_ref, mono_wasm_get_by_index_ref, mono_wasm_set_by_index_ref, mono_wasm_get_global_object_ref } from "./net6-legacy/method-calls"; -import { mono_wasm_change_case, mono_wasm_change_case_invariant, mono_wasm_compare_string } from "./net6-legacy/hybrid-globalization"; +import { mono_wasm_change_case, mono_wasm_change_case_invariant, mono_wasm_compare_string, mono_wasm_ends_with, mono_wasm_starts_with } from "./hybrid-globalization"; // the methods would be visible to EMCC linker // --- keep in sync with dotnet.cjs.lib.js --- @@ -100,6 +100,8 @@ export function export_linker(): any { mono_wasm_change_case_invariant, mono_wasm_change_case, mono_wasm_compare_string, + mono_wasm_starts_with, + mono_wasm_ends_with, // threading exports, if threading is enabled ...mono_wasm_threads_exports, diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 02641068889c15..c7ea64155b8e54 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -3,62 +3,47 @@ import ProductVersion from "consts:productVersion"; import GitHash from "consts:gitHash"; -import MonoWasmThreads from "consts:monoWasmThreads"; import BuildConfiguration from "consts:configuration"; import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; +import type { DotnetHostBuilder, RuntimeAPI } from "./types-api"; -import { ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, disableLegacyJsInterop, moduleExports, set_emscripten_entrypoint, set_imports_exports } from "./imports"; -import { is_nullish, EarlyImports, EarlyExports, EarlyReplacements, RuntimeAPI, CreateDotnetRuntimeType, DotnetModuleInternal } from "./types"; -import { configure_emscripten_startup, mono_wasm_pthread_worker_init } from "./startup"; +import { Module, disableLegacyJsInterop, exportedRuntimeAPI, passEmscriptenInternals, } from "./globals"; +import { is_nullish } from "./types"; +import { configureEmscriptenStartup, configureWorkerStartup } from "./startup"; import { create_weak_ref } from "./weak-ref"; import { export_internal } from "./exports-internal"; -import { export_linker } from "./exports-linker"; -import { init_polyfills } from "./polyfills"; -import { export_api, export_module } from "./export-api"; +import { export_api } from "./export-api"; +import { mono_exit } from "./run"; +import { globalObjectsRoot, unifyModuleConfig } from "./run-outer"; +import { HostBuilder } from "./run-outer"; +import { initializeReplacements, init_polyfills } from "./polyfills"; // legacy import { mono_bind_static_method } from "./net6-legacy/method-calls"; import { export_binding_api, export_internal_api, export_mono_api } from "./net6-legacy/exports-legacy"; -import { set_legacy_exports } from "./net6-legacy/imports"; - -const __initializeImportsAndExports: any = initializeImportsAndExports; // don't want to export the type -const __setEmscriptenEntrypoint: any = setEmscriptenEntrypoint; // don't want to export the type -let __linker_exports: any = null; - - -// this is executed early during load of emscripten runtime -// it exports methods to global objects MONO, BINDING and Module in backward compatible way -// At runtime this will be referred to as 'createDotnetRuntime' -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -function initializeImportsAndExports( - imports: EarlyImports, - exports: EarlyExports, - replacements: EarlyReplacements, - callbackAPI: any -): RuntimeAPI { - const module = exports.module as DotnetModuleInternal; +import { initializeLegacyExports } from "./net6-legacy/globals"; + +function initializeExports(): RuntimeAPI { + const module = Module; + const globals = globalObjectsRoot; const globalThisAny = globalThis as any; - // we want to have same instance of MONO, BINDING and Module in dotnet iife - set_imports_exports(imports, exports); if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { - set_legacy_exports(exports); + initializeLegacyExports(globals); } - init_polyfills(replacements); + init_polyfills(); // here we merge methods from the local objects into exported objects if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { - Object.assign(exports.mono, export_mono_api()); - Object.assign(exports.binding, export_binding_api()); - Object.assign(exports.internal, export_internal_api()); + Object.assign(globals.mono, export_mono_api()); + Object.assign(globals.binding, export_binding_api()); + Object.assign(globals.internal, export_internal_api()); } - Object.assign(exports.internal, export_internal()); + Object.assign(globals.internal, export_internal()); const API = export_api(); - __linker_exports = export_linker(); Object.assign(exportedRuntimeAPI, { - INTERNAL: exports.internal, - IMPORTS: exports.marshaled_imports, + INTERNAL: globals.internal, Module: module, runtimeBuildInfo: { productVersion: ProductVersion, @@ -69,29 +54,16 @@ function initializeImportsAndExports( }); if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { Object.assign(exportedRuntimeAPI, { - MONO: exports.mono, - BINDING: exports.binding, + MONO: globals.mono, + BINDING: globals.binding, }); } - Object.assign(callbackAPI, API); - if (exports.module.__undefinedConfig) { - module.disableDotnet6Compatibility = true; - module.configSrc = "./mono-config.json"; - } - - if (!module.out) { - module.out = console.log.bind(console); - } - if (!module.err) { - module.err = console.error.bind(console); - } - if (typeof module.disableDotnet6Compatibility === "undefined") { module.disableDotnet6Compatibility = true; } // here we expose objects global namespace for tests and backward compatibility - if (imports.isGlobal || !module.disableDotnet6Compatibility) { + if (!module.disableDotnet6Compatibility) { Object.assign(module, exportedRuntimeAPI); if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { @@ -122,12 +94,10 @@ function initializeImportsAndExports( } }); }; - globalThisAny.MONO = exports.mono; - globalThisAny.BINDING = exports.binding; - globalThisAny.INTERNAL = exports.internal; - if (!imports.isGlobal) { - globalThisAny.Module = module; - } + globalThisAny.MONO = globals.mono; + globalThisAny.BINDING = globals.binding; + globalThisAny.INTERNAL = globals.internal; + globalThisAny.Module = module; // Blazor back compat warnWrap("cwrap", () => module.cwrap); @@ -146,16 +116,9 @@ function initializeImportsAndExports( } list.registerRuntime(exportedRuntimeAPI); - if (MonoWasmThreads && ENVIRONMENT_IS_PTHREAD) { - return mono_wasm_pthread_worker_init(module, exportedRuntimeAPI); - } - - configure_emscripten_startup(module, exportedRuntimeAPI); - return exportedRuntimeAPI; } - class RuntimeList { private list: { [runtimeId: number]: WeakRef } = {}; @@ -171,10 +134,10 @@ class RuntimeList { } } -function setEmscriptenEntrypoint(emscriptenEntrypoint: CreateDotnetRuntimeType) { - Object.assign(moduleExports, export_module()); - set_emscripten_entrypoint(emscriptenEntrypoint); -} - -export { __initializeImportsAndExports, __setEmscriptenEntrypoint, __linker_exports, moduleExports }; - +// export external API +const dotnet: DotnetHostBuilder = new HostBuilder(); +const exit = mono_exit; +export { + dotnet, exit, + globalObjectsRoot as earlyExports, passEmscriptenInternals, initializeExports, initializeReplacements, unifyModuleConfig, configureEmscriptenStartup, configureWorkerStartup +}; \ No newline at end of file diff --git a/src/mono/wasm/runtime/gc-handles.ts b/src/mono/wasm/runtime/gc-handles.ts index ce83039e4e3669..b1bc580d931b36 100644 --- a/src/mono/wasm/runtime/gc-handles.ts +++ b/src/mono/wasm/runtime/gc-handles.ts @@ -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. -import { runtimeHelpers } from "./imports"; +import { runtimeHelpers } from "./globals"; import { GCHandle, GCHandleNull, JSHandle, JSHandleDisposed, JSHandleNull, mono_assert } from "./types"; import { create_weak_ref } from "./weak-ref"; diff --git a/src/mono/wasm/runtime/gc-lock.ts b/src/mono/wasm/runtime/gc-lock.ts index 35c6be03b7ca6f..31b2db200c5b39 100644 --- a/src/mono/wasm/runtime/gc-lock.ts +++ b/src/mono/wasm/runtime/gc-lock.ts @@ -1,5 +1,5 @@ import MonoWasmThreads from "consts:monoWasmThreads"; -import { ENVIRONMENT_IS_PTHREAD } from "./imports"; +import { ENVIRONMENT_IS_PTHREAD } from "./globals"; import cwraps from "./cwraps"; let locked = false; diff --git a/src/mono/wasm/runtime/globals.ts b/src/mono/wasm/runtime/globals.ts new file mode 100644 index 00000000000000..1f032e37c966ab --- /dev/null +++ b/src/mono/wasm/runtime/globals.ts @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/* eslint-disable @typescript-eslint/triple-slash-reference */ +/// +/// + +import { RuntimeAPI } from "./types-api"; +import type { DotnetModule, GlobalObjects, EmscriptenInternals, EmscriptenModuleInternal, RuntimeHelpers } from "./types"; +import type { EmscriptenModule } from "./types/emscripten"; + +// these are our public API (except internal) +export let Module: EmscriptenModule & DotnetModule & EmscriptenModuleInternal; +export let INTERNAL: any; + +// these are imported and re-exported from emscripten internals +export const ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string"; +export const ENVIRONMENT_IS_WEB = typeof window == "object"; +export let ENVIRONMENT_IS_SHELL: boolean; +export let ENVIRONMENT_IS_WORKER: boolean; +export let ENVIRONMENT_IS_PTHREAD: boolean; +export let exportedRuntimeAPI: RuntimeAPI = null as any; +export let runtimeHelpers: RuntimeHelpers = null as any; +// this is when we link with workload tools. The consts:WasmEnableLegacyJsInterop is when we compile with rollup. +export let disableLegacyJsInterop = false; +export let earlyExports: GlobalObjects; + +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export function passEmscriptenInternals( + internals: EmscriptenInternals, +): void { + ENVIRONMENT_IS_SHELL = internals.isShell; + ENVIRONMENT_IS_WORKER = internals.isWorker; + ENVIRONMENT_IS_PTHREAD = internals.isPThread; + disableLegacyJsInterop = internals.disableLegacyJsInterop; + runtimeHelpers.quit = internals.quit_; + runtimeHelpers.ExitStatus = internals.ExitStatus; +} + +export function setGlobalObjects( + globalObjects: GlobalObjects, +) { + earlyExports = globalObjects; + Module = globalObjects.module; + INTERNAL = globalObjects.internal; + runtimeHelpers = globalObjects.helpers; + exportedRuntimeAPI = globalObjects.api; + + Object.assign(globalObjects.module, { + disableDotnet6Compatibility: true, + config: { environmentVariables: {} } + }); + Object.assign(globalObjects.module.config!, {}) as any; + Object.assign(earlyExports.api, { + Module: globalObjects.module, ...globalObjects.module + }); + Object.assign(earlyExports.api, { + INTERNAL: earlyExports.internal, + }); + Object.assign(runtimeHelpers, { + javaScriptExports: {} as any, + mono_wasm_bindings_is_ready: false, + maxParallelDownloads: 16, + enableDownloadRetry: true, + config: globalObjects.module.config, + diagnosticTracing: false, + enablePerfMeasure: true, + loadedFiles: [] + } as Partial); +} diff --git a/src/mono/wasm/runtime/http.ts b/src/mono/wasm/runtime/http.ts index 62a1f4b61cc2c6..a3d676e91a90dc 100644 --- a/src/mono/wasm/runtime/http.ts +++ b/src/mono/wasm/runtime/http.ts @@ -2,11 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. import { wrap_as_cancelable_promise } from "./cancelable-promise"; -import { Module } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { MemoryViewType, Span } from "./marshal"; -import { fetch_like } from "./polyfills"; import { mono_assert } from "./types"; -import { VoidPtr } from "./types/emscripten"; +import type { VoidPtr } from "./types/emscripten"; export function http_wasm_supports_streaming_response(): boolean { return typeof Response !== "undefined" && "body" in Response.prototype && typeof ReadableStream === "function"; @@ -57,7 +56,7 @@ export function http_wasm_fetch(url: string, header_names: string[], header_valu } return wrap_as_cancelable_promise(async () => { - const res = await fetch_like(url, options) as ResponseExtension; + const res = await runtimeHelpers.fetch_like(url, options) as ResponseExtension; res.__abort_controller = abort_controller; return res; }); diff --git a/src/mono/wasm/runtime/net6-legacy/hybrid-globalization.ts b/src/mono/wasm/runtime/hybrid-globalization.ts similarity index 63% rename from src/mono/wasm/runtime/net6-legacy/hybrid-globalization.ts rename to src/mono/wasm/runtime/hybrid-globalization.ts index ae3ee2ac648f66..66cc3ebafb371a 100644 --- a/src/mono/wasm/runtime/net6-legacy/hybrid-globalization.ts +++ b/src/mono/wasm/runtime/hybrid-globalization.ts @@ -1,43 +1,42 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { Module } from "../imports"; -import { mono_wasm_new_external_root } from "../roots"; -import {MonoString, MonoStringRef } from "../types"; -import { Int32Ptr } from "../types/emscripten"; -import { conv_string_root, js_string_to_mono_string_root } from "../strings"; -import { setU16 } from "../memory"; +import { mono_wasm_new_external_root } from "./roots"; +import { MonoString, MonoStringRef } from "./types"; +import { Int32Ptr } from "./types/emscripten"; +import { conv_string_root, js_string_to_mono_string_root, string_decoder } from "./strings"; +import { setU16_unchecked } from "./memory"; export function mono_wasm_change_case_invariant(exceptionMessage: Int32Ptr, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number) : void{ try{ - const input = get_utf16_string(src, srcLength); + const input = string_decoder.decode(src, (src + 2*srcLength)); let result = toUpper ? input.toUpperCase() : input.toLowerCase(); // Unicode defines some codepoints which expand into multiple codepoints, // originally we do not support this expansion if (result.length > dstLength) result = input; - for (let i = 0; i < result.length; i++) - setU16(dst + i*2, result.charCodeAt(i)); + for (let i = 0, j = dst; i < result.length; i++, j += 2) + setU16_unchecked(j, result.charCodeAt(i)); } catch (ex: any) { pass_exception_details(ex, exceptionMessage); } } -export function mono_wasm_change_case(exceptionMessage: Int32Ptr, culture: MonoStringRef, src: number, srcLength: number, dst: number, destLength: number, toUpper: number) : void{ +export function mono_wasm_change_case(exceptionMessage: Int32Ptr, culture: MonoStringRef, src: number, srcLength: number, dst: number, destLength: number, toUpper: number): void { const cultureRoot = mono_wasm_new_external_root(culture); - try{ + try { const cultureName = conv_string_root(cultureRoot); if (!cultureName) throw new Error("Cannot change case, the culture name is null."); - const input = get_utf16_string(src, srcLength); + const input = string_decoder.decode(src, (src + 2*srcLength)); let result = toUpper ? input.toLocaleUpperCase(cultureName) : input.toLocaleLowerCase(cultureName); if (result.length > destLength) result = input; - for (let i = 0; i < destLength; i++) - setU16(dst + i*2, result.charCodeAt(i)); + for (let i = 0, j = dst; i < result.length; i++, j += 2) + setU16_unchecked(j, result.charCodeAt(i)); } catch (ex: any) { pass_exception_details(ex, exceptionMessage); @@ -47,12 +46,12 @@ export function mono_wasm_change_case(exceptionMessage: Int32Ptr, culture: MonoS } } -export function mono_wasm_compare_string(exceptionMessage: Int32Ptr, culture: MonoStringRef, str1: number, str1Length: number, str2: number, str2Length: number, options: number) : number{ +export function mono_wasm_compare_string(exceptionMessage: Int32Ptr, culture: MonoStringRef, str1: number, str1Length: number, str2: number, str2Length: number, options: number): number { const cultureRoot = mono_wasm_new_external_root(culture); - try{ + try { const cultureName = conv_string_root(cultureRoot); - const string1 = get_utf16_string(str1, str1Length); - const string2 = get_utf16_string(str2, str2Length); + const string1 = string_decoder.decode(str1, (str1 + 2 * str1Length)); + const string2 = string_decoder.decode(str2, (str2 + 2 * str2Length)); const casePicker = (options & 0x1f); const locale = cultureName ? cultureName : undefined; const result = compare_strings(string1, string2, locale, casePicker); @@ -69,24 +68,81 @@ export function mono_wasm_compare_string(exceptionMessage: Int32Ptr, culture: Mo } } -export function get_utf16_string(ptr: number, length: number): string{ - const view = new Uint16Array(Module.HEAPU16.buffer, ptr, length); - let string = ""; - for (let i = 0; i < length; i++) - string += String.fromCharCode(view[i]); - return string; -} - -export function pass_exception_details(ex: any, exceptionMessage: Int32Ptr){ +function pass_exception_details(ex: any, exceptionMessage: Int32Ptr) { const exceptionJsString = ex.message + "\n" + ex.stack; const exceptionRoot = mono_wasm_new_external_root(exceptionMessage); js_string_to_mono_string_root(exceptionJsString, exceptionRoot); exceptionRoot.release(); } -export function compare_strings(string1: string, string2: string, locale: string | undefined, casePicker: number) : number{ - switch (casePicker) - { +export function mono_wasm_starts_with(exceptionMessage: Int32Ptr, culture: MonoStringRef, str1: number, str1Length: number, str2: number, str2Length: number, options: number): number { + const cultureRoot = mono_wasm_new_external_root(culture); + try { + const cultureName = conv_string_root(cultureRoot); + const prefix = get_clean_string(str2, str2Length); + // no need to look for an empty string + if (prefix.length == 0) + return 1; // true + + const source = get_clean_string(str1, str1Length); + if (source.length < prefix.length) + return 0; //false + const sourceOfPrefixLength = source.slice(0, prefix.length); + + const casePicker = (options & 0x1f); + const locale = cultureName ? cultureName : undefined; + const result = compare_strings(sourceOfPrefixLength, prefix, locale, casePicker); + if (result == -2) + throw new Error("$Invalid comparison option."); + return result === 0 ? 1 : 0; // equals ? true : false + } + catch (ex: any) { + pass_exception_details(ex, exceptionMessage); + return -1; + } + finally { + cultureRoot.release(); + } +} + +export function mono_wasm_ends_with(exceptionMessage: Int32Ptr, culture: MonoStringRef, str1: number, str1Length: number, str2: number, str2Length: number, options: number): number { + const cultureRoot = mono_wasm_new_external_root(culture); + try { + const cultureName = conv_string_root(cultureRoot); + const suffix = get_clean_string(str2, str2Length); + if (suffix.length == 0) + return 1; // true + + const source = get_clean_string(str1, str1Length); + const diff = source.length - suffix.length; + if (diff < 0) + return 0; //false + const sourceOfSuffixLength = source.slice(diff, source.length); + + const casePicker = (options & 0x1f); + const locale = cultureName ? cultureName : undefined; + const result = compare_strings(sourceOfSuffixLength, suffix, locale, casePicker); + if (result == -2) + throw new Error("$Invalid comparison option."); + return result === 0 ? 1 : 0; // equals ? true : false + } + catch (ex: any) { + pass_exception_details(ex, exceptionMessage); + return -1; + } + finally { + cultureRoot.release(); + } +} + +function get_clean_string(strPtr: number, strLen: number) { + const str = string_decoder.decode(strPtr, (strPtr + 2 * strLen)); + const nStr = str.normalize(); + return nStr.replace(/[\u200B-\u200D\uFEFF\0]/g, ""); +} + +export function compare_strings(string1: string, string2: string, locale: string | undefined, casePicker: number): number { + switch (casePicker) { case 0: // 0: None - default algorithm for the platform OR // StringSort - since .Net 5 StringSort gives the same result as None, even for hyphen etc. diff --git a/src/mono/wasm/runtime/icu.ts b/src/mono/wasm/runtime/icu.ts index dfed61e8b475ad..f3b5b4586b164e 100644 --- a/src/mono/wasm/runtime/icu.ts +++ b/src/mono/wasm/runtime/icu.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import cwraps from "./cwraps"; -import { Module, runtimeHelpers } from "./imports"; +import { ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./globals"; import { VoidPtr } from "./types/emscripten"; // @offset must be the address of an ICU data archive in the native heap. diff --git a/src/mono/wasm/runtime/imports.ts b/src/mono/wasm/runtime/imports.ts deleted file mode 100644 index cab9189477d356..00000000000000 --- a/src/mono/wasm/runtime/imports.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/* eslint-disable @typescript-eslint/triple-slash-reference */ -/// -/// - -import type { CreateDotnetRuntimeType, DotnetModule, RuntimeAPI, EarlyExports, EarlyImports, ModuleAPI, RuntimeHelpers } from "./types"; -import type { EmscriptenModule, EmscriptenModuleInternal } from "./types/emscripten"; - -// these are our public API (except internal) -export let Module: EmscriptenModule & DotnetModule & EmscriptenModuleInternal; -export let INTERNAL: any; -export let IMPORTS: any; - -// these are imported and re-exported from emscripten internals -export let ENVIRONMENT_IS_NODE: boolean; -export let ENVIRONMENT_IS_SHELL: boolean; -export let ENVIRONMENT_IS_WEB: boolean; -export let ENVIRONMENT_IS_WORKER: boolean; -export let ENVIRONMENT_IS_PTHREAD: boolean; -export const exportedRuntimeAPI: RuntimeAPI = {} as any; -export const moduleExports: ModuleAPI = {} as any; -export let emscriptenEntrypoint: CreateDotnetRuntimeType; - -// this is when we link with workload tools. The consts:WasmEnableLegacyJsInterop is when we compile with rollup. -export let disableLegacyJsInterop = false; - -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function set_imports_exports( - imports: EarlyImports, - exports: EarlyExports, -): void { - INTERNAL = exports.internal; - IMPORTS = exports.marshaled_imports; - Module = exports.module; - - ENVIRONMENT_IS_NODE = imports.isNode; - ENVIRONMENT_IS_SHELL = imports.isShell; - ENVIRONMENT_IS_WEB = imports.isWeb; - ENVIRONMENT_IS_WORKER = imports.isWorker; - ENVIRONMENT_IS_PTHREAD = imports.isPThread; - disableLegacyJsInterop = imports.disableLegacyJsInterop; - runtimeHelpers.quit = imports.quit_; - runtimeHelpers.ExitStatus = imports.ExitStatus; - runtimeHelpers.requirePromise = imports.requirePromise; -} - -export function set_emscripten_entrypoint( - entrypoint: CreateDotnetRuntimeType -): void { - emscriptenEntrypoint = entrypoint; -} - - -const initialRuntimeHelpers: Partial = -{ - javaScriptExports: {} as any, - mono_wasm_bindings_is_ready: false, - maxParallelDownloads: 16, - enableDownloadRetry: true, - config: { - environmentVariables: {}, - }, - diagnosticTracing: false, - enablePerfMeasure: true, - loadedFiles: [] -}; -export const runtimeHelpers: RuntimeHelpers = initialRuntimeHelpers as any; diff --git a/src/mono/wasm/runtime/invoke-cs.ts b/src/mono/wasm/runtime/invoke-cs.ts index f55810af6eab23..340b3afa414052 100644 --- a/src/mono/wasm/runtime/invoke-cs.ts +++ b/src/mono/wasm/runtime/invoke-cs.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import { Module, runtimeHelpers } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { bind_arg_marshal_to_cs } from "./marshal-to-cs"; import { marshal_exception_to_js, bind_arg_marshal_to_js } from "./marshal-to-js"; import { diff --git a/src/mono/wasm/runtime/invoke-js.ts b/src/mono/wasm/runtime/invoke-js.ts index 53882278e4aba8..6cb566f024aa15 100644 --- a/src/mono/wasm/runtime/invoke-js.ts +++ b/src/mono/wasm/runtime/invoke-js.ts @@ -7,7 +7,7 @@ import { setI32_unchecked } from "./memory"; import { conv_string_root, js_string_to_mono_string_root } from "./strings"; import { mono_assert, MonoObject, MonoObjectRef, MonoString, MonoStringRef, JSFunctionSignature, JSMarshalerArguments, WasmRoot, BoundMarshalerToJs, JSFnHandle, BoundMarshalerToCs, JSHandle, MarshalerType } from "./types"; import { Int32Ptr } from "./types/emscripten"; -import { IMPORTS, INTERNAL, Module, runtimeHelpers } from "./imports"; +import { INTERNAL, Module, runtimeHelpers } from "./globals"; import { bind_arg_marshal_to_js } from "./marshal-to-js"; import { mono_wasm_new_external_root } from "./roots"; import { mono_wasm_symbolicate_string } from "./logging"; @@ -256,7 +256,7 @@ export function mono_wasm_set_module_imports(module_name: string, moduleImports: function mono_wasm_lookup_function(function_name: string, js_module_name: string): Function { mono_assert(function_name && typeof function_name === "string", "function_name must be string"); - let scope: any = IMPORTS; + let scope: any = {}; const parts = function_name.split("."); if (js_module_name) { scope = importedModules.get(js_module_name); diff --git a/src/mono/wasm/runtime/jiterpreter-interp-entry.ts b/src/mono/wasm/runtime/jiterpreter-interp-entry.ts index 964bd1316d202d..aad65e7ad4841c 100644 --- a/src/mono/wasm/runtime/jiterpreter-interp-entry.ts +++ b/src/mono/wasm/runtime/jiterpreter-interp-entry.ts @@ -3,7 +3,7 @@ import { mono_assert, MonoMethod, MonoType } from "./types"; import { NativePointer } from "./types/emscripten"; -import { Module } from "./imports"; +import { Module } from "./globals"; import { getU32_unaligned, _zero_region } from "./memory"; @@ -24,18 +24,18 @@ const /* typedef struct { - InterpMethod *rmethod; - gpointer this_arg; - gpointer res; - gpointer args [16]; - gpointer *many_args; + InterpMethod *rmethod; + gpointer this_arg; + gpointer res; + gpointer args [16]; + gpointer *many_args; } InterpEntryData; typedef struct { - InterpMethod *rmethod; // 0 - ThreadContext *context; // 4 - gpointer orig_domain; // 8 - gpointer attach_cookie; // 12 + InterpMethod *rmethod; // 0 + ThreadContext *context; // 4 + gpointer orig_domain; // 8 + gpointer attach_cookie; // 12 } JiterpEntryDataHeader; */ @@ -47,12 +47,12 @@ const const maxJitQueueLength = 4, queueFlushDelayMs = 10; -let trampBuilder : WasmBuilder; -let trampImports : Array<[string, string, Function]> | undefined; -let fnTable : WebAssembly.Table; +let trampBuilder: WasmBuilder; +let trampImports: Array<[string, string, Function]> | undefined; +let fnTable: WebAssembly.Table; let jitQueueTimeout = 0; -const jitQueue : TrampolineInfo[] = []; -const infoTable : { [ptr: number] : TrampolineInfo } = {}; +const jitQueue: TrampolineInfo[] = []; +const infoTable: { [ptr: number]: TrampolineInfo } = {}; /* const enum WasmReftype { @@ -61,7 +61,7 @@ const enum WasmReftype { } */ -function getTrampImports () { +function getTrampImports() { if (trampImports) return trampImports; @@ -91,7 +91,7 @@ class TrampolineInfo { result: number; hitCount: number; - constructor ( + constructor( imethod: number, method: MonoMethod, argumentCount: number, pParamTypes: NativePointer, unbox: boolean, hasThisReference: boolean, hasReturnValue: boolean, name: string, defaultImplementation: number @@ -125,9 +125,9 @@ class TrampolineInfo { } } -let mostRecentOptions : JiterpreterOptions | undefined = undefined; +let mostRecentOptions: JiterpreterOptions | undefined = undefined; -export function mono_interp_record_interp_entry (imethod: number) { +export function mono_interp_record_interp_entry(imethod: number) { // clear the unbox bit imethod = imethod & ~0x1; @@ -153,11 +153,11 @@ export function mono_interp_record_interp_entry (imethod: number) { } // returns function pointer -export function mono_interp_jit_wasm_entry_trampoline ( +export function mono_interp_jit_wasm_entry_trampoline( imethod: number, method: MonoMethod, argumentCount: number, pParamTypes: NativePointer, unbox: boolean, hasThisReference: boolean, hasReturnValue: boolean, name: NativePointer, defaultImplementation: number -) : number { +): number { // HACK if (argumentCount > maxInlineArgs) return 0; @@ -182,7 +182,7 @@ export function mono_interp_jit_wasm_entry_trampoline ( return info.result; } -function ensure_jit_is_scheduled () { +function ensure_jit_is_scheduled() { if (jitQueueTimeout > 0) return; @@ -201,7 +201,7 @@ function ensure_jit_is_scheduled () { }, queueFlushDelayMs); } -function flush_wasm_entry_trampoline_jit_queue () { +function flush_wasm_entry_trampoline_jit_queue() { if (jitQueue.length <= 0) return; @@ -213,29 +213,37 @@ function flush_wasm_entry_trampoline_jit_queue () { trampBuilder = builder = new WasmBuilder(constantSlots); builder.defineType( - "unbox", { + "unbox", + { "pMonoObject": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "interp_entry_prologue", { + "interp_entry_prologue", + { "pData": WasmValtype.i32, "this_arg": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "interp_entry", { + "interp_entry", + { "pData": WasmValtype.i32, "sp_args": WasmValtype.i32, "res": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "stackval_from_data", { + "stackval_from_data", + { "type": WasmValtype.i32, "result": WasmValtype.i32, "value": WasmValtype.i32 - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); } else builder.clear(constantSlots); @@ -257,7 +265,7 @@ function flush_wasm_entry_trampoline_jit_queue () { for (let i = 0; i < jitQueue.length; i++) { const info = jitQueue[i]; - const sig : any = {}; + const sig: any = {}; if (info.hasThisReference) sig["this_arg"] = WasmValtype.i32; if (info.hasReturnValue) @@ -405,7 +413,7 @@ function flush_wasm_entry_trampoline_jit_queue () { } } -function append_stackval_from_data ( +function append_stackval_from_data( builder: WasmBuilder, type: MonoType, valueName: string ) { const stackvalSize = cwraps.mono_jiterp_get_size_of_stackval(); @@ -486,9 +494,9 @@ function append_stackval_from_data ( builder.local("sp_args", WasmOpcode.set_local); } -function generate_wasm_body ( +function generate_wasm_body( builder: WasmBuilder, info: TrampolineInfo -) : boolean { +): boolean { // FIXME: This is not thread-safe, but the alternative of alloca makes the trampoline // more expensive // The solution is likely to put the address of the scratch buffer in a global that we provide @@ -558,15 +566,15 @@ function generate_wasm_body ( } /* - for (i = 0; i < sig->param_count; ++i) { - if (m_type_is_byref (sig->params [i])) { - sp_args->data.p = params [i]; - sp_args++; - } else { - int size = stackval_from_data (sig->params [i], sp_args, params [i], FALSE); - sp_args = STACK_ADD_BYTES (sp_args, size); - } - } + for (i = 0; i < sig->param_count; ++i) { + if (m_type_is_byref (sig->params [i])) { + sp_args->data.p = params [i]; + sp_args++; + } else { + int size = stackval_from_data (sig->params [i], sp_args, params [i], FALSE); + sp_args = STACK_ADD_BYTES (sp_args, size); + } + } */ for (let i = 0; i < info.paramTypes.length; i++) { diff --git a/src/mono/wasm/runtime/jiterpreter-jit-call.ts b/src/mono/wasm/runtime/jiterpreter-jit-call.ts index b5734380b360b1..3f016adc005108 100644 --- a/src/mono/wasm/runtime/jiterpreter-jit-call.ts +++ b/src/mono/wasm/runtime/jiterpreter-jit-call.ts @@ -3,7 +3,7 @@ import { mono_assert, MonoType, MonoMethod } from "./types"; import { NativePointer, Int32Ptr, VoidPtr } from "./types/emscripten"; -import { Module, runtimeHelpers } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { getU8, getI32_unaligned, getU32_unaligned, setU32_unchecked } from "./memory"; @@ -26,17 +26,17 @@ const /* struct _JitCallInfo { - gpointer addr; // 0 - gpointer extra_arg; // 4 - gpointer wrapper; // 8 - MonoMethodSignature *sig; // 12 - guint8 *arginfo; // 16 - gint32 res_size; // 20 - int ret_mt; // 24 - gboolean no_wrapper; // 28 + gpointer addr; // 0 + gpointer extra_arg; // 4 + gpointer wrapper; // 8 + MonoMethodSignature *sig; // 12 + guint8 *arginfo; // 16 + gint32 res_size; // 20 + int ret_mt; // 24 + gboolean no_wrapper; // 28 #if HOST_BROWSER - int hit_count; - WasmJitCallThunk jiterp_thunk; + int hit_count; + WasmJitCallThunk jiterp_thunk; #endif }; */ @@ -52,15 +52,15 @@ const offsetOfAddr = 0, const maxJitQueueLength = 6, maxSharedQueueLength = 12; - // sizeOfStackval = 8; +// sizeOfStackval = 8; -let trampBuilder : WasmBuilder; -let fnTable : WebAssembly.Table; -let wasmEhSupported : boolean | undefined = undefined; +let trampBuilder: WasmBuilder; +let fnTable: WebAssembly.Table; +let wasmEhSupported: boolean | undefined = undefined; let nextDisambiguateIndex = 0; -const fnCache : Array = []; -const targetCache : { [target: number] : TrampolineInfo } = {}; -const jitQueue : TrampolineInfo[] = []; +const fnCache: Array = []; +const targetCache: { [target: number]: TrampolineInfo } = {}; +const jitQueue: TrampolineInfo[] = []; class TrampolineInfo { method: MonoMethod; @@ -90,7 +90,7 @@ class TrampolineInfo { wasmNativeSignature: WasmValtype[]; enableDirect: boolean; - constructor ( + constructor( method: MonoMethod, rmethod: VoidPtr, cinfo: VoidPtr, arg_offsets: VoidPtr, catch_exceptions: boolean ) { @@ -159,7 +159,7 @@ class TrampolineInfo { // this is cached replacements for Module.getWasmTableEntry(); // we could add and // if we need to export the original -function getWasmTableEntry (index: number) { +function getWasmTableEntry(index: number) { let result = fnCache[index]; if (!result) { if (index >= fnCache.length) @@ -172,7 +172,7 @@ function getWasmTableEntry (index: number) { return result; } -export function mono_interp_invoke_wasm_jit_call_trampoline ( +export function mono_interp_invoke_wasm_jit_call_trampoline( thunkIndex: number, ret_sp: number, sp: number, ftndesc: number, thrown: NativePointer ) { const thunk = getWasmTableEntry(thunkIndex); @@ -183,10 +183,10 @@ export function mono_interp_invoke_wasm_jit_call_trampoline ( } } -export function mono_interp_jit_wasm_jit_call_trampoline ( +export function mono_interp_jit_wasm_jit_call_trampoline( method: MonoMethod, rmethod: VoidPtr, cinfo: VoidPtr, arg_offsets: VoidPtr, catch_exceptions: number -) : void { +): void { // multiple cinfos can share the same target function, so for that scenario we want to // use the same TrampolineInfo for all of them. if that info has already been jitted // we want to immediately store its pointer into the cinfo, otherwise we add it to @@ -227,9 +227,9 @@ export function mono_interp_jit_wasm_jit_call_trampoline ( // pure wasm implementation of do_jit_call_indirect (using wasm EH). see do-jit-call.wat / do-jit-call.wasm const doJitCall16 = "0061736d01000000010b0260017f0060037f7f7f00021d020169066d656d6f727902000001690b6a69745f63616c6c5f636200000302010107180114646f5f6a69745f63616c6c5f696e64697265637400010a1301110006402001100019200241013602000b0b"; -let doJitCallModule : WebAssembly.Module | undefined = undefined; +let doJitCallModule: WebAssembly.Module | undefined = undefined; -function getIsWasmEhSupported () : boolean { +function getIsWasmEhSupported(): boolean { if (wasmEhSupported !== undefined) return wasmEhSupported; @@ -254,9 +254,9 @@ function getIsWasmEhSupported () : boolean { // this is the generic entry point for do_jit_call that is registered by default at runtime startup. // its job is to do initialization for the optimized do_jit_call path, which will either use a jitted // wasm trampoline or will use a specialized JS function. -export function mono_jiterp_do_jit_call_indirect ( +export function mono_jiterp_do_jit_call_indirect( jit_call_cb: number, cb_data: VoidPtr, thrown: Int32Ptr -) : void { +): void { mono_assert(!runtimeHelpers.storeMemorySnapshotPending, "Attempting to set function into table during creation of memory snapshot"); const table = getWasmFunctionTable(); const jitCallCb = table.get(jit_call_cb); @@ -311,7 +311,7 @@ export function mono_jiterp_do_jit_call_indirect ( do_jit_call_indirect_js(jit_call_cb, cb_data, thrown); } -export function mono_interp_flush_jitcall_queue () : void { +export function mono_interp_flush_jitcall_queue(): void { if (jitQueue.length === 0) return; @@ -320,7 +320,8 @@ export function mono_interp_flush_jitcall_queue () : void { trampBuilder = builder = new WasmBuilder(0); // Function type for compiled trampolines builder.defineType( - "trampoline", { + "trampoline", + { "ret_sp": WasmValtype.i32, "sp": WasmValtype.i32, "ftndesc": WasmValtype.i32, @@ -338,7 +339,7 @@ export function mono_interp_flush_jitcall_queue () : void { if (builder.options.enableWasmEh) { if (!getIsWasmEhSupported()) { // The user requested to enable wasm EH but it's not supported, so turn the option back off - applyOptions({enableWasmEh: false}); + applyOptions({ enableWasmEh: false }); builder.options.enableWasmEh = false; } } @@ -347,7 +348,7 @@ export function mono_interp_flush_jitcall_queue () : void { let compileStarted = 0; let rejected = true, threw = false; - const trampImports : Array<[string, string, Function | number]> = [ + const trampImports: Array<[string, string, Function | number]> = [ ]; try { @@ -361,7 +362,7 @@ export function mono_interp_flush_jitcall_queue () : void { for (let i = 0; i < jitQueue.length; i++) { const info = jitQueue[i]; - const sig : any = {}; + const sig: any = {}; if (info.enableDirect) { if (info.hasThisReference) @@ -425,7 +426,7 @@ export function mono_interp_flush_jitcall_queue () : void { builder.appendULeb(jitQueue.length); for (let i = 0; i < jitQueue.length; i++) { const info = jitQueue[i]; - builder.beginFunction("trampoline", {"old_sp": WasmValtype.i32}); + builder.beginFunction("trampoline", { "old_sp": WasmValtype.i32 }); const ok = generate_wasm_body(builder, info); // FIXME @@ -572,66 +573,66 @@ const enum CilOpcodes { const wasmTypeFromCilOpcode = { [CilOpcodes.DUMMY_BYREF]: WasmValtype.i32, - [CilOpcodes.LDIND_I1]: WasmValtype.i32, - [CilOpcodes.LDIND_U1]: WasmValtype.i32, - [CilOpcodes.LDIND_I2]: WasmValtype.i32, - [CilOpcodes.LDIND_U2]: WasmValtype.i32, - [CilOpcodes.LDIND_I4]: WasmValtype.i32, - [CilOpcodes.LDIND_U4]: WasmValtype.i32, - [CilOpcodes.LDIND_I8]: WasmValtype.i64, - [CilOpcodes.LDIND_I]: WasmValtype.i32, - [CilOpcodes.LDIND_R4]: WasmValtype.f32, - [CilOpcodes.LDIND_R8]: WasmValtype.f64, + [CilOpcodes.LDIND_I1]: WasmValtype.i32, + [CilOpcodes.LDIND_U1]: WasmValtype.i32, + [CilOpcodes.LDIND_I2]: WasmValtype.i32, + [CilOpcodes.LDIND_U2]: WasmValtype.i32, + [CilOpcodes.LDIND_I4]: WasmValtype.i32, + [CilOpcodes.LDIND_U4]: WasmValtype.i32, + [CilOpcodes.LDIND_I8]: WasmValtype.i64, + [CilOpcodes.LDIND_I]: WasmValtype.i32, + [CilOpcodes.LDIND_R4]: WasmValtype.f32, + [CilOpcodes.LDIND_R8]: WasmValtype.f64, [CilOpcodes.LDIND_REF]: WasmValtype.i32, [CilOpcodes.STIND_REF]: WasmValtype.i32, - [CilOpcodes.STIND_I1]: WasmValtype.i32, - [CilOpcodes.STIND_I2]: WasmValtype.i32, - [CilOpcodes.STIND_I4]: WasmValtype.i32, - [CilOpcodes.STIND_I8]: WasmValtype.i64, - [CilOpcodes.STIND_R4]: WasmValtype.f32, - [CilOpcodes.STIND_R8]: WasmValtype.f64, - [CilOpcodes.STIND_I]: WasmValtype.i32, + [CilOpcodes.STIND_I1]: WasmValtype.i32, + [CilOpcodes.STIND_I2]: WasmValtype.i32, + [CilOpcodes.STIND_I4]: WasmValtype.i32, + [CilOpcodes.STIND_I8]: WasmValtype.i64, + [CilOpcodes.STIND_R4]: WasmValtype.f32, + [CilOpcodes.STIND_R8]: WasmValtype.f64, + [CilOpcodes.STIND_I]: WasmValtype.i32, }; // Maps a CIL ld/st opcode to the wasm opcode to perform it, if any const wasmOpcodeFromCilOpcode = { - [CilOpcodes.LDIND_I1]: WasmOpcode.i32_load8_s, - [CilOpcodes.LDIND_U1]: WasmOpcode.i32_load8_u, - [CilOpcodes.LDIND_I2]: WasmOpcode.i32_load16_s, - [CilOpcodes.LDIND_U2]: WasmOpcode.i32_load16_u, - [CilOpcodes.LDIND_I4]: WasmOpcode.i32_load, - [CilOpcodes.LDIND_U4]: WasmOpcode.i32_load, - [CilOpcodes.LDIND_I8]: WasmOpcode.i64_load, - [CilOpcodes.LDIND_I]: WasmOpcode.i32_load, - [CilOpcodes.LDIND_R4]: WasmOpcode.f32_load, - [CilOpcodes.LDIND_R8]: WasmOpcode.f64_load, + [CilOpcodes.LDIND_I1]: WasmOpcode.i32_load8_s, + [CilOpcodes.LDIND_U1]: WasmOpcode.i32_load8_u, + [CilOpcodes.LDIND_I2]: WasmOpcode.i32_load16_s, + [CilOpcodes.LDIND_U2]: WasmOpcode.i32_load16_u, + [CilOpcodes.LDIND_I4]: WasmOpcode.i32_load, + [CilOpcodes.LDIND_U4]: WasmOpcode.i32_load, + [CilOpcodes.LDIND_I8]: WasmOpcode.i64_load, + [CilOpcodes.LDIND_I]: WasmOpcode.i32_load, + [CilOpcodes.LDIND_R4]: WasmOpcode.f32_load, + [CilOpcodes.LDIND_R8]: WasmOpcode.f64_load, [CilOpcodes.LDIND_REF]: WasmOpcode.i32_load, // TODO: Memory barrier? [CilOpcodes.STIND_REF]: WasmOpcode.i32_store, // Memory barrier not needed - [CilOpcodes.STIND_I1]: WasmOpcode.i32_store8, - [CilOpcodes.STIND_I2]: WasmOpcode.i32_store16, - [CilOpcodes.STIND_I4]: WasmOpcode.i32_store, - [CilOpcodes.STIND_I8]: WasmOpcode.i64_store, - [CilOpcodes.STIND_R4]: WasmOpcode.f32_store, - [CilOpcodes.STIND_R8]: WasmOpcode.f64_store, - [CilOpcodes.STIND_I]: WasmOpcode.i32_store, + [CilOpcodes.STIND_I1]: WasmOpcode.i32_store8, + [CilOpcodes.STIND_I2]: WasmOpcode.i32_store16, + [CilOpcodes.STIND_I4]: WasmOpcode.i32_store, + [CilOpcodes.STIND_I8]: WasmOpcode.i64_store, + [CilOpcodes.STIND_R4]: WasmOpcode.f32_store, + [CilOpcodes.STIND_R8]: WasmOpcode.f64_store, + [CilOpcodes.STIND_I]: WasmOpcode.i32_store, }; -function append_ldloc (builder: WasmBuilder, offsetBytes: number, opcode: WasmOpcode) { +function append_ldloc(builder: WasmBuilder, offsetBytes: number, opcode: WasmOpcode) { builder.local("sp"); builder.appendU8(opcode); builder.appendMemarg(offsetBytes, 0); } -function append_ldloca (builder: WasmBuilder, offsetBytes: number) { +function append_ldloca(builder: WasmBuilder, offsetBytes: number) { builder.local("sp"); builder.i32_const(offsetBytes); builder.appendU8(WasmOpcode.i32_add); } -function generate_wasm_body ( +function generate_wasm_body( builder: WasmBuilder, info: TrampolineInfo -) : boolean { +): boolean { let stack_index = 0; // If wasm EH is enabled we will perform the call inside a catch-all block and set a flag @@ -744,18 +745,18 @@ function generate_wasm_body ( builder.callImport(info.name); /* - if (sig->ret->type != MONO_TYPE_VOID) { - // Store return value - stind_op = mono_type_to_stind (sig->ret); - // FIXME: - if (stind_op == CEE_STOBJ) - mono_mb_emit_op (mb, CEE_STOBJ, mono_class_from_mono_type_internal (sig->ret)); - else if (stind_op == CEE_STIND_REF) - // Avoid write barriers, the vret arg points to the stack - mono_mb_emit_byte (mb, CEE_STIND_I); - else - mono_mb_emit_byte (mb, stind_op); - } + if (sig->ret->type != MONO_TYPE_VOID) { + // Store return value + stind_op = mono_type_to_stind (sig->ret); + // FIXME: + if (stind_op == CEE_STOBJ) + mono_mb_emit_op (mb, CEE_STOBJ, mono_class_from_mono_type_internal (sig->ret)); + else if (stind_op == CEE_STIND_REF) + // Avoid write barriers, the vret arg points to the stack + mono_mb_emit_byte (mb, CEE_STIND_I); + else + mono_mb_emit_byte (mb, stind_op); + } */ // The stack should now contain [ret_sp, retval], so write retval through the return address diff --git a/src/mono/wasm/runtime/jiterpreter-support.ts b/src/mono/wasm/runtime/jiterpreter-support.ts index 9c4fdc3de0d22b..010e67496b19b5 100644 --- a/src/mono/wasm/runtime/jiterpreter-support.ts +++ b/src/mono/wasm/runtime/jiterpreter-support.ts @@ -3,7 +3,7 @@ import { mono_assert } from "./types"; import { NativePointer, ManagedPointer, VoidPtr } from "./types/emscripten"; -import { Module, runtimeHelpers } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { WasmOpcode } from "./jiterpreter-opcodes"; import { MintOpcode } from "./mintops"; import cwraps from "./cwraps"; @@ -122,7 +122,7 @@ type ImportedFunctionInfo = { func: Function; } -const compressedNameCache : { [number: number] : string } = {}; +const compressedNameCache: { [number: number]: string } = {}; export class WasmBuilder { cfg: Cfg; @@ -134,20 +134,20 @@ export class WasmBuilder { locals = new Map(); permanentFunctionTypeCount = 0; - permanentFunctionTypes: { [name: string] : FunctionType } = {}; - permanentFunctionTypesByShape: { [shape: string] : FunctionTypeIndex } = {}; - permanentFunctionTypesByIndex: { [index: number] : FunctionTypeByIndex } = {}; + permanentFunctionTypes: { [name: string]: FunctionType } = {}; + permanentFunctionTypesByShape: { [shape: string]: FunctionTypeIndex } = {}; + permanentFunctionTypesByIndex: { [index: number]: FunctionTypeByIndex } = {}; functionTypeCount!: number; - functionTypes!: { [name: string] : FunctionType }; - functionTypesByShape!: { [shape: string] : FunctionTypeIndex }; - functionTypesByIndex: { [index: number] : FunctionTypeByIndex } = {}; + functionTypes!: { [name: string]: FunctionType }; + functionTypesByShape!: { [shape: string]: FunctionTypeIndex }; + functionTypesByIndex: { [index: number]: FunctionTypeByIndex } = {}; permanentImportedFunctionCount = 0; - permanentImportedFunctions: { [name: string] : ImportedFunctionInfo } = {}; + permanentImportedFunctions: { [name: string]: ImportedFunctionInfo } = {}; importedFunctionCount!: number; - importedFunctions!: { [name: string] : ImportedFunctionInfo }; + importedFunctions!: { [name: string]: ImportedFunctionInfo }; nextImportIndex = 0; functions: Array = []; @@ -167,13 +167,13 @@ export class WasmBuilder { compressImportNames = false; - constructor (constantSlotCount: number) { + constructor(constantSlotCount: number) { this.stack = [new BlobBuilder()]; this.clear(constantSlotCount); this.cfg = new Cfg(this); } - clear (constantSlotCount: number) { + clear(constantSlotCount: number) { this.options = getOptions(); this.stackSize = 1; this.inSection = false; @@ -213,14 +213,14 @@ export class WasmBuilder { this.allowNullCheckOptimization = this.options.eliminateNullChecks; } - _push () { + _push() { this.stackSize++; if (this.stackSize >= this.stack.length) this.stack.push(new BlobBuilder()); this.current.clear(); } - _pop (writeToOutput: boolean) { + _pop(writeToOutput: boolean) { if (this.stackSize <= 1) throw new Error("Stack empty"); @@ -238,7 +238,7 @@ export class WasmBuilder { // HACK: Approximate amount of space we need to generate the full module at present // FIXME: This does not take into account any other functions already generated if they weren't // emitted into the module immediately - get bytesGeneratedSoFar () { + get bytesGeneratedSoFar() { return this.stack[0].size + // HACK: A random constant for section headers and padding 32 + @@ -258,59 +258,59 @@ export class WasmBuilder { return this.current.size; } - appendU8 (value: number | WasmOpcode) { + appendU8(value: number | WasmOpcode) { if ((value != value >>> 0) || (value > 255)) throw new Error(`Byte out of range: ${value}`); return this.current.appendU8(value); } - appendU32 (value: number) { + appendU32(value: number) { return this.current.appendU32(value); } - appendF32 (value: number) { + appendF32(value: number) { return this.current.appendF32(value); } - appendF64 (value: number) { + appendF64(value: number) { return this.current.appendF64(value); } - appendBoundaryValue (bits: number, sign: number) { + appendBoundaryValue(bits: number, sign: number) { return this.current.appendBoundaryValue(bits, sign); } - appendULeb (value: number | MintOpcodePtr) { + appendULeb(value: number | MintOpcodePtr) { return this.current.appendULeb(value); } - appendLeb (value: number) { + appendLeb(value: number) { return this.current.appendLeb(value); } - appendLebRef (sourceAddress: VoidPtr, signed: boolean) { + appendLebRef(sourceAddress: VoidPtr, signed: boolean) { return this.current.appendLebRef(sourceAddress, signed); } - appendBytes (bytes: Uint8Array) { + appendBytes(bytes: Uint8Array) { return this.current.appendBytes(bytes); } - appendName (text: string) { + appendName(text: string) { return this.current.appendName(text); } - ret (ip: MintOpcodePtr) { + ret(ip: MintOpcodePtr) { this.ip_const(ip); this.appendU8(WasmOpcode.return_); } - i32_const (value: number | ManagedPointer | NativePointer) { + i32_const(value: number | ManagedPointer | NativePointer) { this.appendU8(WasmOpcode.i32_const); this.appendLeb(value); } - ptr_const (pointer: number | ManagedPointer | NativePointer) { + ptr_const(pointer: number | ManagedPointer | NativePointer) { let idx = this.options.useConstants ? this.constantSlots.indexOf(pointer) : -1; if ( this.options.useConstants && @@ -329,17 +329,17 @@ export class WasmBuilder { } } - ip_const (value: MintOpcodePtr) { + ip_const(value: MintOpcodePtr) { this.appendU8(WasmOpcode.i32_const); this.appendLeb(value - this.base); } - i52_const (value: number) { + i52_const(value: number) { this.appendU8(WasmOpcode.i64_const); this.appendLeb(value); } - defineType ( + defineType( name: string, parameters: { [name: string]: WasmValtype }, returnType: WasmValtype, permanent: boolean ) { @@ -376,7 +376,7 @@ export class WasmBuilder { } } - const tup : FunctionType = [ + const tup: FunctionType = [ index, parameters, returnType, `(${JSON.stringify(parameters)}) -> ${returnType}`, permanent ]; @@ -388,7 +388,7 @@ export class WasmBuilder { return index; } - generateTypeSection () { + generateTypeSection() { this.beginSection(1); this.appendULeb(this.functionTypeCount); /* @@ -414,8 +414,8 @@ export class WasmBuilder { this.endSection(); } - getImportedFunctionTable () : any { - const imports : any = {}; + getImportedFunctionTable(): any { + const imports: any = {}; for (const k in this.importedFunctions) { const f = this.importedFunctions[k]; const name = this.getCompressedName(f); @@ -424,8 +424,8 @@ export class WasmBuilder { return imports; } - getCompressedName (ifi: ImportedFunctionInfo) { - if (!this.compressImportNames || typeof(ifi.index) !== "number") + getCompressedName(ifi: ImportedFunctionInfo) { + if (!this.compressImportNames || typeof (ifi.index) !== "number") return ifi.name; let result = compressedNameCache[ifi.index!]; @@ -434,7 +434,7 @@ export class WasmBuilder { return result; } - _generateImportSection () { + _generateImportSection() { const importsToEmit = []; for (const k in this.importedFunctions) { const f = this.importedFunctions[k]; @@ -474,10 +474,10 @@ export class WasmBuilder { this.appendULeb(0x01); } - defineImportedFunction ( + defineImportedFunction( module: string, name: string, functionTypeName: string, assumeUsed: boolean, permanent: boolean, func: Function | number - ) : ImportedFunctionInfo { + ): ImportedFunctionInfo { if (permanent && (this.importedFunctionCount > this.permanentImportedFunctionCount)) throw new Error("New permanent imports cannot be defined after non-permanent ones"); const type = this.functionTypes[functionTypeName]; @@ -509,7 +509,7 @@ export class WasmBuilder { return result; } - defineFunction ( + defineFunction( options: { type: string, name: string, @@ -517,7 +517,7 @@ export class WasmBuilder { locals: { [name: string]: WasmValtype }, }, generator: Function ) { - const rec : FunctionInfo = { + const rec: FunctionInfo = { index: this.functions.length, name: options.name, typeName: options.type, @@ -534,7 +534,7 @@ export class WasmBuilder { return rec; } - emitImportsAndFunctions () { + emitImportsAndFunctions() { let exportCount = 0; for (let i = 0; i < this.functions.length; i++) { const func = this.functions[i]; @@ -581,7 +581,7 @@ export class WasmBuilder { this.endSection(); } - callImport (name: string) { + callImport(name: string) { const func = this.importedFunctions[name]; if (!func) throw new Error("No imported function named " + name); @@ -591,7 +591,7 @@ export class WasmBuilder { this.appendULeb(func.index); } - beginSection (type: number) { + beginSection(type: number) { if (this.inSection) this._pop(true); this.appendU8(type); @@ -599,7 +599,7 @@ export class WasmBuilder { this.inSection = true; } - endSection () { + endSection() { if (!this.inSection) throw new Error("Not in section"); if (this.inFunction) @@ -608,7 +608,7 @@ export class WasmBuilder { this.inSection = false; } - _assignParameterIndices = (parms: {[name: string] : WasmValtype}) => { + _assignParameterIndices = (parms: { [name: string]: WasmValtype }) => { let result = 0; for (const k in parms) { this.locals.set(k, result); @@ -618,8 +618,8 @@ export class WasmBuilder { return result; }; - _assignLocalIndices ( - counts: any, locals: {[name: string] : WasmValtype}, + _assignLocalIndices( + counts: any, locals: { [name: string]: WasmValtype }, base: number, localGroupCount: number ) { counts[WasmValtype.i32] = 0; @@ -671,9 +671,9 @@ export class WasmBuilder { return localGroupCount; } - beginFunction ( + beginFunction( type: string, - locals?: {[name: string]: WasmValtype} + locals?: { [name: string]: WasmValtype } ) { if (this.inFunction) throw new Error("Already in function"); @@ -715,7 +715,7 @@ export class WasmBuilder { this.inFunction = true; } - endFunction (writeToOutput: boolean) { + endFunction(writeToOutput: boolean) { if (!this.inFunction) throw new Error("Not in function"); if (this.activeBlocks > 0) @@ -725,7 +725,7 @@ export class WasmBuilder { return result; } - block (type?: WasmValtype, opcode?: WasmOpcode) { + block(type?: WasmValtype, opcode?: WasmOpcode) { const result = this.appendU8(opcode || WasmOpcode.block); if (type) this.appendU8(type); @@ -735,15 +735,15 @@ export class WasmBuilder { return result; } - endBlock () { + endBlock() { if (this.activeBlocks <= 0) throw new Error("No blocks active"); this.activeBlocks--; this.appendU8(WasmOpcode.end); } - arg (name: string | number, opcode?: WasmOpcode) { - const index = typeof(name) === "string" + arg(name: string | number, opcode?: WasmOpcode) { + const index = typeof (name) === "string" ? (this.locals.has(name) ? this.locals.get(name)! : undefined) : name; if (typeof (index) !== "number") @@ -753,8 +753,8 @@ export class WasmBuilder { this.appendULeb(index); } - local (name: string | number, opcode?: WasmOpcode) { - const index = typeof(name) === "string" + local(name: string | number, opcode?: WasmOpcode) { + const index = typeof (name) === "string" ? (this.locals.has(name) ? this.locals.get(name)! : undefined) : name + this.argumentCount; if (typeof (index) !== "number") @@ -766,7 +766,7 @@ export class WasmBuilder { this.appendULeb(index); } - appendMemarg (offset: number, alignPower: number) { + appendMemarg(offset: number, alignPower: number) { this.appendULeb(alignPower); this.appendULeb(offset); } @@ -774,7 +774,7 @@ export class WasmBuilder { /* generates either (u32)get_local(ptr) + offset or (u32)ptr1 + offset */ - lea (ptr1: string | number, offset: number) { + lea(ptr1: string | number, offset: number) { if (typeof (ptr1) === "string") this.local(ptr1); else @@ -785,14 +785,14 @@ export class WasmBuilder { this.appendU8(WasmOpcode.i32_add); } - getArrayView (fullCapacity?: boolean) { + getArrayView(fullCapacity?: boolean) { if (this.stackSize > 1) throw new Error("Jiterpreter block stack not empty"); return this.stack[0].getArrayView(fullCapacity); } - getConstants () { - const result : { [key: string]: number } = {}; + getConstants() { + const result: { [key: string]: number } = {}; for (let i = 0; i < this.constantSlots.length; i++) result[i.toString(shortNameBase)] = this.constantSlots[i]; return result; @@ -806,7 +806,7 @@ export class BlobBuilder { encoder?: TextEncoder; textBuf = new Uint8Array(1024); - constructor () { + constructor() { this.capacity = 16 * 1024; this.buffer = Module._malloc(this.capacity); Module.HEAPU8.fill(0, this.buffer, this.buffer + this.capacity); @@ -816,11 +816,11 @@ export class BlobBuilder { this.encoder = new TextEncoder(); } - clear () { + clear() { this.size = 0; } - appendU8 (value: number | WasmOpcode) { + appendU8(value: number | WasmOpcode) { if (this.size >= this.capacity) throw new Error("Buffer full"); @@ -829,35 +829,35 @@ export class BlobBuilder { return result; } - appendU32 (value: number) { + appendU32(value: number) { const result = this.size; cwraps.mono_jiterp_write_number_unaligned(this.buffer + this.size, value, JiterpNumberMode.U32); this.size += 4; return result; } - appendI32 (value: number) { + appendI32(value: number) { const result = this.size; cwraps.mono_jiterp_write_number_unaligned(this.buffer + this.size, value, JiterpNumberMode.I32); this.size += 4; return result; } - appendF32 (value: number) { + appendF32(value: number) { const result = this.size; cwraps.mono_jiterp_write_number_unaligned(this.buffer + this.size, value, JiterpNumberMode.F32); this.size += 4; return result; } - appendF64 (value: number) { + appendF64(value: number) { const result = this.size; cwraps.mono_jiterp_write_number_unaligned(this.buffer + this.size, value, JiterpNumberMode.F64); this.size += 8; return result; } - appendBoundaryValue (bits: number, sign: number) { + appendBoundaryValue(bits: number, sign: number) { if (this.size + 8 >= this.capacity) throw new Error("Buffer full"); @@ -868,7 +868,7 @@ export class BlobBuilder { return bytesWritten; } - appendULeb (value: number) { + appendULeb(value: number) { mono_assert(value >= 0, "cannot pass negative value to appendULeb"); if (value < 0x7F) { if (this.size + 1 >= this.capacity) @@ -888,7 +888,7 @@ export class BlobBuilder { return bytesWritten; } - appendLeb (value: number) { + appendLeb(value: number) { if (this.size + 8 >= this.capacity) throw new Error("Buffer full"); @@ -899,7 +899,7 @@ export class BlobBuilder { return bytesWritten; } - appendLebRef (sourceAddress: VoidPtr, signed: boolean) { + appendLebRef(sourceAddress: VoidPtr, signed: boolean) { if (this.size + 8 >= this.capacity) throw new Error("Buffer full"); @@ -910,7 +910,7 @@ export class BlobBuilder { return bytesWritten; } - copyTo (destination: BlobBuilder, count?: number) { + copyTo(destination: BlobBuilder, count?: number) { if (typeof (count) !== "number") count = this.size; @@ -918,7 +918,7 @@ export class BlobBuilder { destination.size += count; } - appendBytes (bytes: Uint8Array, count?: number) { + appendBytes(bytes: Uint8Array, count?: number) { const result = this.size; if (bytes.buffer === Module.HEAPU8.buffer) { if (typeof (count) !== "number") @@ -937,7 +937,7 @@ export class BlobBuilder { return result; } - appendName (text: string) { + appendName(text: string) { let count = text.length; // TextEncoder overhead is significant for short strings, and lots of our strings // are single-character import names, so add a fast path for single characters @@ -972,7 +972,7 @@ export class BlobBuilder { this.appendBytes(this.textBuf, count); } - getArrayView (fullCapacity?: boolean) { + getArrayView(fullCapacity?: boolean) { return new Uint8Array(Module.HEAPU8.buffer, this.buffer, fullCapacity ? this.capacity : this.size); } } @@ -1019,11 +1019,11 @@ class Cfg { observedBranchTargets = new Set(); trace = 0; - constructor (builder: WasmBuilder) { + constructor(builder: WasmBuilder) { this.builder = builder; } - initialize (startOfBody: MintOpcodePtr, backBranchTargets: Uint16Array | null, trace: number) { + initialize(startOfBody: MintOpcodePtr, backBranchTargets: Uint16Array | null, trace: number) { this.segments.length = 0; this.blockStack.length = 0; this.startOfBody = startOfBody; @@ -1039,7 +1039,7 @@ class Cfg { } // We have a header containing the table of locals and we need to preserve it - entry (ip: MintOpcodePtr) { + entry(ip: MintOpcodePtr) { this.entryIp = ip; this.appendBlob(); mono_assert(this.segments.length === 1, "expected 1 segment"); @@ -1053,7 +1053,7 @@ class Cfg { } } - appendBlob () { + appendBlob() { if (this.builder.current.size === this.lastSegmentEnd) return; @@ -1069,7 +1069,7 @@ class Cfg { this.overheadBytes += 2; } - startBranchBlock (ip: MintOpcodePtr, isBackBranchTarget: boolean) { + startBranchBlock(ip: MintOpcodePtr, isBackBranchTarget: boolean) { this.appendBlob(); this.segments.push({ type: "branch-block-header", @@ -1079,7 +1079,7 @@ class Cfg { this.overheadBytes += 1; // each branch block just costs us an end } - branch (target: MintOpcodePtr, isBackward: boolean, isConditional: boolean) { + branch(target: MintOpcodePtr, isBackward: boolean, isConditional: boolean) { this.observedBranchTargets.add(target); this.appendBlob(); this.segments.push({ @@ -1102,13 +1102,13 @@ class Cfg { } } - emitBlob (segment: CfgBlob, source: Uint8Array) { + emitBlob(segment: CfgBlob, source: Uint8Array) { // console.log(`segment @${(segment.ip).toString(16)} ${segment.start}-${segment.start + segment.length}`); const view = source.subarray(segment.start, segment.start + segment.length); this.builder.appendBytes(view); } - generate (): Uint8Array { + generate(): Uint8Array { // HACK: Make sure any remaining bytes are inserted into a trailing segment this.appendBlob(); @@ -1316,7 +1316,7 @@ export const enum WasmValtype { f64 = 0x7C, } -let wasmTable : WebAssembly.Table | undefined; +let wasmTable: WebAssembly.Table | undefined; let wasmNextFunctionIndex = -1, wasmFunctionIndicesFree = 0; // eslint-disable-next-line prefer-const @@ -1342,9 +1342,9 @@ export const _now = (globalThis.performance && globalThis.performance.now) ? globalThis.performance.now.bind(globalThis.performance) : Date.now; -let scratchBuffer : NativePointer = 0; +let scratchBuffer: NativePointer = 0; -export function append_bailout (builder: WasmBuilder, ip: MintOpcodePtr, reason: BailoutReason) { +export function append_bailout(builder: WasmBuilder, ip: MintOpcodePtr, reason: BailoutReason) { builder.ip_const(ip); if (builder.options.countBailouts) { builder.i32_const(builder.base); @@ -1355,7 +1355,7 @@ export function append_bailout (builder: WasmBuilder, ip: MintOpcodePtr, reason: } // generate a bailout that is recorded for the monitoring phase as a possible early exit. -export function append_exit (builder: WasmBuilder, ip: MintOpcodePtr, opcodeCounter: number, reason: BailoutReason) { +export function append_exit(builder: WasmBuilder, ip: MintOpcodePtr, opcodeCounter: number, reason: BailoutReason) { if (opcodeCounter <= (builder.options.monitoringLongDistance + 2)) { builder.local("cinfo"); builder.i32_const(opcodeCounter); @@ -1379,7 +1379,7 @@ export function append_exit (builder: WasmBuilder, ip: MintOpcodePtr, opcodeCoun builder.appendU8(WasmOpcode.return_); } -export function copyIntoScratchBuffer (src: NativePointer, size: number) : NativePointer { +export function copyIntoScratchBuffer(src: NativePointer, size: number): NativePointer { if (!scratchBuffer) scratchBuffer = Module._malloc(64); if (size > 64) @@ -1389,7 +1389,7 @@ export function copyIntoScratchBuffer (src: NativePointer, size: number) : Nativ return scratchBuffer; } -export function getWasmFunctionTable () { +export function getWasmFunctionTable() { if (!wasmTable) wasmTable = (Module)["asm"]["__indirect_function_table"]; if (!wasmTable) @@ -1397,8 +1397,8 @@ export function getWasmFunctionTable () { return wasmTable; } -export function addWasmFunctionPointer (f: Function) { - mono_assert(f,"Attempting to set null function into table"); +export function addWasmFunctionPointer(f: Function) { + mono_assert(f, "Attempting to set null function into table"); mono_assert(!runtimeHelpers.storeMemorySnapshotPending, "Attempting to set function into table during creation of memory snapshot"); const table = getWasmFunctionTable(); @@ -1414,7 +1414,7 @@ export function addWasmFunctionPointer (f: Function) { return index; } -export function try_append_memset_fast (builder: WasmBuilder, localOffset: number, value: number, count: number, destOnStack: boolean) { +export function try_append_memset_fast(builder: WasmBuilder, localOffset: number, value: number, count: number, destOnStack: boolean) { if (count <= 0) { if (destOnStack) builder.appendU8(WasmOpcode.drop); @@ -1468,7 +1468,7 @@ export function try_append_memset_fast (builder: WasmBuilder, localOffset: numbe return true; } -export function append_memset_dest (builder: WasmBuilder, value: number, count: number) { +export function append_memset_dest(builder: WasmBuilder, value: number, count: number) { // spec: pop n, pop val, pop d, fill from d[0] to d[n] with value val if (try_append_memset_fast(builder, 0, value, count, true)) return; @@ -1480,7 +1480,7 @@ export function append_memset_dest (builder: WasmBuilder, value: number, count: builder.appendU8(0); } -export function try_append_memmove_fast ( +export function try_append_memmove_fast( builder: WasmBuilder, destLocalOffset: number, srcLocalOffset: number, count: number, addressesOnStack: boolean, destLocal?: string, srcLocal?: string ) { @@ -1524,7 +1524,7 @@ export function try_append_memmove_fast ( // Then copy the remaining 0-7 bytes while (count >= 1) { - let loadOp : WasmOpcode, storeOp : WasmOpcode; + let loadOp: WasmOpcode, storeOp: WasmOpcode; let localCount = count % 4; switch (localCount) { case 0: @@ -1564,7 +1564,7 @@ export function try_append_memmove_fast ( } // expects dest then source to have been pushed onto wasm stack -export function append_memmove_dest_src (builder: WasmBuilder, count: number) { +export function append_memmove_dest_src(builder: WasmBuilder, count: number) { if (try_append_memmove_fast(builder, 0, 0, count, true)) return true; @@ -1578,7 +1578,7 @@ export function append_memmove_dest_src (builder: WasmBuilder, count: number) { return true; } -export function recordFailure () : void { +export function recordFailure(): void { counters.failures++; if (counters.failures >= maxFailures) { console.log(`MONO_WASM: Disabling jiterpreter after ${counters.failures} failures`); @@ -1606,9 +1606,9 @@ export const enum JiterpMember { ClauseDataOffsets = 12, } -const memberOffsets : { [index: number] : number } = {}; +const memberOffsets: { [index: number]: number } = {}; -export function getMemberOffset (member: JiterpMember) { +export function getMemberOffset(member: JiterpMember) { const cached = memberOffsets[member]; if (cached === undefined) return memberOffsets[member] = cwraps.mono_jiterp_get_member_offset(member); @@ -1616,23 +1616,23 @@ export function getMemberOffset (member: JiterpMember) { return cached; } -export function getRawCwrap (name: string): Function { +export function getRawCwrap(name: string): Function { const result = (Module)["asm"][name]; if (typeof (result) !== "function") throw new Error(`raw cwrap ${name} not found`); return result; } -const opcodeTableCache : { [opcode: number] : number } = {}; +const opcodeTableCache: { [opcode: number]: number } = {}; -export function getOpcodeTableValue (opcode: MintOpcode) { +export function getOpcodeTableValue(opcode: MintOpcode) { let result = opcodeTableCache[opcode]; if (typeof (result) !== "number") result = opcodeTableCache[opcode] = cwraps.mono_jiterp_get_opcode_value_table_entry(opcode); return result; } -export function importDef (name: string, fn: Function): [string, string, Function] { +export function importDef(name: string, fn: Function): [string, string, Function] { return [name, name, fn]; } @@ -1678,7 +1678,7 @@ export type JiterpreterOptions = { wasmBytesLimit: number; } -const optionNames : { [jsName: string] : string } = { +const optionNames: { [jsName: string]: string } = { "enableTraces": "jiterpreter-traces-enabled", "enableInterpEntry": "jiterpreter-interp-entry-enabled", "enableJitCall": "jiterpreter-jit-call-enabled", @@ -1709,10 +1709,10 @@ const optionNames : { [jsName: string] : string } = { }; let optionsVersion = -1; -let optionTable : JiterpreterOptions = {}; +let optionTable: JiterpreterOptions = {}; // applies one or more jiterpreter options to change the current jiterpreter configuration. -export function applyOptions (options: JiterpreterOptions) { +export function applyOptions(options: JiterpreterOptions) { for (const k in options) { const info = optionNames[k]; if (!info) { @@ -1726,12 +1726,12 @@ export function applyOptions (options: JiterpreterOptions) { else if (typeof (v) === "number") cwraps.mono_jiterp_parse_option(`--${info}=${v}`); else - console.error(`Jiterpreter option must be a boolean or a number but was ${typeof(v)} '${v}'`); + console.error(`Jiterpreter option must be a boolean or a number but was ${typeof (v)} '${v}'`); } } // returns the current jiterpreter configuration. do not mutate the return value! -export function getOptions () { +export function getOptions() { const currentVersion = cwraps.mono_jiterp_get_options_version(); if (currentVersion !== optionsVersion) { updateOptions(); @@ -1740,7 +1740,7 @@ export function getOptions () { return optionTable; } -function updateOptions () { +function updateOptions() { const pJson = cwraps.mono_jiterp_get_options_as_json(); const json = Module.UTF8ToString(pJson); Module._free(pJson); diff --git a/src/mono/wasm/runtime/jiterpreter.ts b/src/mono/wasm/runtime/jiterpreter.ts index 004befc179cf29..1d355272ae85c3 100644 --- a/src/mono/wasm/runtime/jiterpreter.ts +++ b/src/mono/wasm/runtime/jiterpreter.ts @@ -3,7 +3,7 @@ import { mono_assert, MonoMethod } from "./types"; import { NativePointer } from "./types/emscripten"; -import { Module, runtimeHelpers } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { getU16, getU32_unaligned } from "./memory"; @@ -81,21 +81,21 @@ export const // Web browsers limit synchronous module compiles to 4KB maxModuleSize = 4080; -export const callTargetCounts : { [method: number] : number } = {}; +export const callTargetCounts: { [method: number]: number } = {}; -export let mostRecentTrace : InstrumentedTraceState | undefined; -export let mostRecentOptions : JiterpreterOptions | undefined = undefined; +export let mostRecentTrace: InstrumentedTraceState | undefined; +export let mostRecentOptions: JiterpreterOptions | undefined = undefined; // You can disable an opcode for debugging purposes by adding it to this list, // instead of aborting the trace it will insert a bailout instead. This means that you will // have trace code generated as if the opcode were otherwise enabled -export const disabledOpcodes : Array = [ +export const disabledOpcodes: Array = [ ]; // Detailed output and/or instrumentation will happen when a trace is jitted if the method fullname has a match // Having any items in this list will add some overhead to the jitting of *all* traces // These names can be substrings and instrumentation will happen if the substring is found in the full name -export const instrumentedMethodNames : Array = [ +export const instrumentedMethodNames: Array = [ ]; export class InstrumentedTraceState { @@ -104,7 +104,7 @@ export class InstrumentedTraceState { operand1: number | undefined; operand2: number | undefined; - constructor (name: string) { + constructor(name: string) { this.name = name; this.eip = 0; } @@ -116,24 +116,24 @@ export class TraceInfo { name: string | undefined; abortReason: string | undefined; fnPtr: number | undefined; - bailoutCounts: { [code: number] : number } | undefined; + bailoutCounts: { [code: number]: number } | undefined; bailoutCount: number | undefined; - constructor (ip: MintOpcodePtr, index: number) { + constructor(ip: MintOpcodePtr, index: number) { this.ip = ip; this.index = index; } - get hitCount () { + get hitCount() { return cwraps.mono_jiterp_get_trace_hit_count(this.index); } } -export const instrumentedTraces : { [key: number]: InstrumentedTraceState } = {}; +export const instrumentedTraces: { [key: number]: InstrumentedTraceState } = {}; export let nextInstrumentedTraceId = 1; export let countLimitedPrintCounter = 10; -export const abortCounts : { [key: string] : number } = {}; -export const traceInfo : { [key: string] : TraceInfo } = {}; +export const abortCounts: { [key: string]: number } = {}; +export const traceInfo: { [key: string]: TraceInfo } = {}; export const sizeOfDataItem = 4, @@ -144,25 +144,25 @@ export const /* struct MonoVTable { - MonoClass *klass; // 0 - MonoGCDescriptor gc_descr; // 4 - MonoDomain *domain; // 8 - gpointer type; // 12 - guint8 *interface_bitmap; // 16 - guint32 max_interface_id; // 20 - guint8 rank; // 21 - guint8 initialized; // 22 - guint8 flags; + MonoClass *klass; // 0 + MonoGCDescriptor gc_descr; // 4 + MonoDomain *domain; // 8 + gpointer type; // 12 + guint8 *interface_bitmap; // 16 + guint32 max_interface_id; // 20 + guint8 rank; // 21 + guint8 initialized; // 22 + guint8 flags; */ /* struct InterpFrame { - InterpFrame *parent; // 0 - InterpMethod *imethod; // 4 - stackval *retval; // 8 - stackval *stack; // 12 - InterpFrame *next_free; // 16 - InterpState state; // 20 + InterpFrame *parent; // 0 + InterpMethod *imethod; // 4 + stackval *retval; // 8 + stackval *stack; // 12 + InterpFrame *next_free; // 16 + InterpState state; // 20 }; struct InterpMethod { @@ -177,12 +177,13 @@ struct InterpMethod { void **data_items; */ -export let traceBuilder : WasmBuilder; -export let traceImports : Array<[string, string, Function]> | undefined; +export let traceBuilder: WasmBuilder; +export let traceImports: Array<[string, string, Function]> | undefined; export let _wrap_trace_function: Function; -const mathOps1d = [ +const mathOps1d = + [ "asin", "acos", "atan", @@ -228,7 +229,7 @@ const mathOps1d = [ "powf", ]; -function recordBailout (ip: number, base: MintOpcodePtr, reason: BailoutReason) { +function recordBailout(ip: number, base: MintOpcodePtr, reason: BailoutReason) { cwraps.mono_jiterp_trace_bailout(reason); // Counting these is not meaningful and messes up the end of run statistics if (reason === BailoutReason.Return) @@ -254,7 +255,7 @@ function recordBailout (ip: number, base: MintOpcodePtr, reason: BailoutReason) return ip; } -function getTraceImports () { +function getTraceImports() { if (traceImports) return traceImports; @@ -315,7 +316,7 @@ function getTraceImports () { return traceImports; } -function wrap_trace_function ( +function wrap_trace_function( f: Function, name: string, traceBuf: any, base: MintOpcodePtr, instrumentedTraceId: number ) { @@ -354,265 +355,343 @@ function wrap_trace_function ( ); } -function initialize_builder (builder: WasmBuilder) { +function initialize_builder(builder: WasmBuilder) { // Function type for compiled traces builder.defineType( - "trace", { + "trace", + { "frame": WasmValtype.i32, "pLocals": WasmValtype.i32, "cinfo": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "bailout", { + "bailout", + { "retval": WasmValtype.i32, "base": WasmValtype.i32, "reason": WasmValtype.i32 - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "copy_pointer", { + "copy_pointer", + { "dest": WasmValtype.i32, "src": WasmValtype.i32 - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "value_copy", { + "value_copy", + { "dest": WasmValtype.i32, "src": WasmValtype.i32, "klass": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "entry", { + "entry", + { "imethod": WasmValtype.i32 - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "strlen", { + "strlen", + { "ppString": WasmValtype.i32, "pResult": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "getchr", { + "getchr", + { "ppString": WasmValtype.i32, "pIndex": WasmValtype.i32, "pResult": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "getspan", { + "getspan", + { "destination": WasmValtype.i32, "span": WasmValtype.i32, "index": WasmValtype.i32, "element_size": WasmValtype.i32 - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "overflow_check_i4", { + "overflow_check_i4", + { "lhs": WasmValtype.i32, "rhs": WasmValtype.i32, "opcode": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "mathop_d_d", { + "mathop_d_d", + { "value": WasmValtype.f64, - }, WasmValtype.f64, true + }, + WasmValtype.f64, true ); builder.defineType( - "mathop_dd_d", { + "mathop_dd_d", + { "lhs": WasmValtype.f64, "rhs": WasmValtype.f64, - }, WasmValtype.f64, true + }, + WasmValtype.f64, true ); builder.defineType( - "mathop_f_f", { + "mathop_f_f", + { "value": WasmValtype.f32, - }, WasmValtype.f32, true + }, + WasmValtype.f32, true ); builder.defineType( - "mathop_ff_f", { + "mathop_ff_f", + { "lhs": WasmValtype.f32, "rhs": WasmValtype.f32, - }, WasmValtype.f32, true + }, + WasmValtype.f32, true ); builder.defineType( - "fmaf", { + "fmaf", + { "x": WasmValtype.f32, "y": WasmValtype.f32, "z": WasmValtype.f32, - }, WasmValtype.f32, true + }, + WasmValtype.f32, true ); builder.defineType( - "fma", { + "fma", + { "x": WasmValtype.f64, "y": WasmValtype.f64, "z": WasmValtype.f64, - }, WasmValtype.f64, true + }, + WasmValtype.f64, true ); builder.defineType( - "trace_eip", { + "trace_eip", + { "traceId": WasmValtype.i32, "eip": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "newobj_i", { + "newobj_i", + { "ppDestination": WasmValtype.i32, "vtable": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "newstr", { + "newstr", + { "ppDestination": WasmValtype.i32, "length": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "localloc", { + "localloc", + { "destination": WasmValtype.i32, "len": WasmValtype.i32, "frame": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "ld_del_ptr", { + "ld_del_ptr", + { "ppDestination": WasmValtype.i32, "ppSource": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "ldtsflda", { + "ldtsflda", + { "ppDestination": WasmValtype.i32, "offset": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "gettype", { + "gettype", + { "destination": WasmValtype.i32, "source": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "cast", { + "cast", + { "destination": WasmValtype.i32, "source": WasmValtype.i32, "klass": WasmValtype.i32, "opcode": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "try_unbox", { + "try_unbox", + { "klass": WasmValtype.i32, "destination": WasmValtype.i32, "source": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "box", { + "box", + { "vtable": WasmValtype.i32, "destination": WasmValtype.i32, "source": WasmValtype.i32, "vt": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "conv", { + "conv", + { "destination": WasmValtype.i32, "source": WasmValtype.i32, "opcode": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "relop_fp", { + "relop_fp", + { "lhs": WasmValtype.f64, "rhs": WasmValtype.f64, "opcode": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "safepoint", { + "safepoint", + { "frame": WasmValtype.i32, "ip": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "hashcode", { + "hashcode", + { "ppObj": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "try_hash", { + "try_hash", + { "ppObj": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "hascsize", { + "hascsize", + { "ppObj": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "hasflag", { + "hasflag", + { "klass": WasmValtype.i32, "dest": WasmValtype.i32, "sp1": WasmValtype.i32, "sp2": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "array_rank", { + "array_rank", + { "destination": WasmValtype.i32, "source": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "stfld_o", { + "stfld_o", + { "locals": WasmValtype.i32, "fieldOffsetBytes": WasmValtype.i32, "targetLocalOffsetBytes": WasmValtype.i32, "sourceLocalOffsetBytes": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "notnull", { + "notnull", + { "ptr": WasmValtype.i32, "expected": WasmValtype.i32, "traceIp": WasmValtype.i32, "ip": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "cmpxchg_i32", { + "cmpxchg_i32", + { "dest": WasmValtype.i32, "newVal": WasmValtype.i32, "expected": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "cmpxchg_i64", { + "cmpxchg_i64", + { "dest": WasmValtype.i32, "newVal": WasmValtype.i32, "expected": WasmValtype.i32, "oldVal": WasmValtype.i32, - }, WasmValtype.void, true + }, + WasmValtype.void, true ); builder.defineType( - "transfer", { + "transfer", + { "displacement": WasmValtype.i32, "trace": WasmValtype.i32, "frame": WasmValtype.i32, "locals": WasmValtype.i32, "cinfo": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); builder.defineType( - "stelem_ref", { + "stelem_ref", + { "o": WasmValtype.i32, "aindex": WasmValtype.i32, "ref": WasmValtype.i32, - }, WasmValtype.i32, true + }, + WasmValtype.i32, true ); const traceImports = getTraceImports(); @@ -624,7 +703,7 @@ function initialize_builder (builder: WasmBuilder) { } } -function assert_not_null ( +function assert_not_null( value: number, expectedValue: number, traceIp: MintOpcodePtr, ip: MintOpcodePtr ) { if (value && (value === expectedValue)) @@ -634,11 +713,11 @@ function assert_not_null ( } // returns function id -function generate_wasm ( +function generate_wasm( frame: NativePointer, methodName: string, ip: MintOpcodePtr, startOfBody: MintOpcodePtr, sizeOfBody: MintOpcodePtr, methodFullName: string | undefined, backwardBranchTable: Uint16Array | null -) : number { +): number { // Pre-allocate a decent number of constant slots - this adds fixed size bloat // to the trace but will make the actual pointer constants in the trace smaller // If we run out of constant slots it will transparently fall back to i32_const @@ -862,7 +941,7 @@ function generate_wasm ( } } -export function trace_current_ip (traceId: number, eip: MintOpcodePtr) { +export function trace_current_ip(traceId: number, eip: MintOpcodePtr) { const tup = instrumentedTraces[traceId]; if (!tup) throw new Error(`Unrecognized instrumented trace id ${traceId}`); @@ -870,14 +949,14 @@ export function trace_current_ip (traceId: number, eip: MintOpcodePtr) { mostRecentTrace = tup; } -export function trace_operands (a: number, b: number) { +export function trace_operands(a: number, b: number) { if (!mostRecentTrace) throw new Error("No trace active"); mostRecentTrace.operand1 = a >>> 0; mostRecentTrace.operand2 = b >>> 0; } -export function record_abort (traceIp: MintOpcodePtr, ip: MintOpcodePtr, traceName: string, reason: string | MintOpcode) { +export function record_abort(traceIp: MintOpcodePtr, ip: MintOpcodePtr, traceName: string, reason: string | MintOpcode) { if (typeof (reason) === "number") { cwraps.mono_jiterp_adjust_abort_count(reason, 1); reason = OpcodeInfo[reason][0]; @@ -900,10 +979,10 @@ export function record_abort (traceIp: MintOpcodePtr, ip: MintOpcodePtr, traceNa const JITERPRETER_TRAINING = 0; const JITERPRETER_NOT_JITTED = 1; -export function mono_interp_tier_prepare_jiterpreter ( +export function mono_interp_tier_prepare_jiterpreter( frame: NativePointer, method: MonoMethod, ip: MintOpcodePtr, index: number, startOfBody: MintOpcodePtr, sizeOfBody: MintOpcodePtr -) : number { +): number { mono_assert(ip, "expected instruction pointer"); if (!mostRecentOptions) mostRecentOptions = getOptions(); @@ -969,7 +1048,10 @@ export function mono_interp_tier_prepare_jiterpreter ( } } -export function jiterpreter_dump_stats (b?: boolean, concise?: boolean) { +export function jiterpreter_dump_stats(b?: boolean, concise?: boolean) { + if (!runtimeHelpers.runtimeReady) { + return; + } if (!mostRecentOptions || (b !== undefined)) mostRecentOptions = getOptions(); @@ -1004,7 +1086,7 @@ export function jiterpreter_dump_stats (b?: boolean, concise?: boolean) { } if (mostRecentOptions.estimateHeat) { - const counts : { [key: string] : number } = {}; + const counts: { [key: string]: number } = {}; const traces = Object.values(traceInfo); for (let i = 0; i < traces.length; i++) { @@ -1087,7 +1169,7 @@ export function jiterpreter_dump_stats (b?: boolean, concise?: boolean) { console.log(`${traces[i].name} @${traces[i].ip} (${traces[i].hitCount} hits) ${traces[i].abortReason}`); } - const tuples : Array<[string, number]> = []; + const tuples: Array<[string, number]> = []; for (const k in counts) tuples.push([k, counts[k]]); @@ -1112,7 +1194,7 @@ export function jiterpreter_dump_stats (b?: boolean, concise?: boolean) { console.log(`// ${keys[i]}: ${abortCounts[keys[i]]} abort(s)`); } - if ((typeof(globalThis.setTimeout) === "function") && (b !== undefined)) + if ((typeof (globalThis.setTimeout) === "function") && (b !== undefined)) setTimeout( () => jiterpreter_dump_stats(b), 15000 diff --git a/src/mono/wasm/runtime/logging.ts b/src/mono/wasm/runtime/logging.ts index a4420b01f57f5f..5f3910e30499f1 100644 --- a/src/mono/wasm/runtime/logging.ts +++ b/src/mono/wasm/runtime/logging.ts @@ -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. -import { INTERNAL, Module, runtimeHelpers } from "./imports"; +import { INTERNAL, Module, runtimeHelpers } from "./globals"; import { CharPtr, VoidPtr } from "./types/emscripten"; export const wasm_func_map = new Map(); @@ -131,8 +131,18 @@ export function setup_proxy_console(id: string, console: Console, origin: string } } - if (typeof payload === "string" && id !== "main") - payload = `[${id}] ${payload}`; + if (typeof payload === "string") { + if (payload[0] == "[") { + const now = new Date().toISOString(); + if (id !== "main") { + payload = `[${id}][${now}] ${payload}`; + } else { + payload = `[${now}] ${payload}`; + } + } else if (id !== "main") { + payload = `[${id}] ${payload}`; + } + } if (asJson) { func(JSON.stringify({ diff --git a/src/mono/wasm/runtime/managed-exports.ts b/src/mono/wasm/runtime/managed-exports.ts index f4af331a516ce5..4892052af57202 100644 --- a/src/mono/wasm/runtime/managed-exports.ts +++ b/src/mono/wasm/runtime/managed-exports.ts @@ -3,7 +3,7 @@ import { GCHandle, MarshalerToCs, MarshalerToJs, MarshalerType, MonoMethod, mono_assert } from "./types"; import cwraps from "./cwraps"; -import { runtimeHelpers, ENVIRONMENT_IS_PTHREAD, Module } from "./imports"; +import { runtimeHelpers, ENVIRONMENT_IS_PTHREAD, Module } from "./globals"; import { alloc_stack_frame, get_arg, get_arg_gc_handle, set_arg_type, set_gc_handle } from "./marshal"; import { invoke_method_and_handle_exception } from "./invoke-cs"; import { marshal_array_to_cs_impl, marshal_exception_to_cs, marshal_intptr_to_cs } from "./marshal-to-cs"; diff --git a/src/mono/wasm/runtime/marshal-to-cs.ts b/src/mono/wasm/runtime/marshal-to-cs.ts index 2e1ff002741a24..cc596738cd07f2 100644 --- a/src/mono/wasm/runtime/marshal-to-cs.ts +++ b/src/mono/wasm/runtime/marshal-to-cs.ts @@ -5,7 +5,7 @@ import monoWasmThreads from "consts:monoWasmThreads"; import { isThenable } from "./cancelable-promise"; import cwraps from "./cwraps"; import { assert_not_disposed, cs_owned_js_handle_symbol, js_owned_gc_handle_symbol, mono_wasm_get_js_handle, setup_managed_proxy, teardown_managed_proxy } from "./gc-handles"; -import { Module, runtimeHelpers } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { ManagedError, set_gc_handle, set_js_handle, set_arg_type, set_arg_i32, set_arg_f64, set_arg_i52, set_arg_f32, set_arg_i16, set_arg_u8, set_arg_b8, set_arg_date, diff --git a/src/mono/wasm/runtime/marshal-to-js.ts b/src/mono/wasm/runtime/marshal-to-js.ts index 36f1dcd6bcd1fe..6590bacd12cefe 100644 --- a/src/mono/wasm/runtime/marshal-to-js.ts +++ b/src/mono/wasm/runtime/marshal-to-js.ts @@ -4,7 +4,7 @@ import { createPromiseController, assertIsControllablePromise, getPromiseController } from "./promise-controller"; import cwraps from "./cwraps"; import { _lookup_js_owned_object, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, setup_managed_proxy } from "./gc-handles"; -import { Module, runtimeHelpers } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { ManagedObject, ManagedError, get_arg_gc_handle, get_arg_js_handle, get_arg_type, get_arg_i32, get_arg_f64, get_arg_i52, get_arg_i16, get_arg_u8, get_arg_f32, diff --git a/src/mono/wasm/runtime/marshal.ts b/src/mono/wasm/runtime/marshal.ts index 51032095d1414d..5cc7a9eab5cad7 100644 --- a/src/mono/wasm/runtime/marshal.ts +++ b/src/mono/wasm/runtime/marshal.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import { js_owned_gc_handle_symbol, teardown_managed_proxy } from "./gc-handles"; -import { Module, runtimeHelpers } from "./imports"; +import { Module, runtimeHelpers } from "./globals"; import { getF32, getF64, getI16, getI32, getI64Big, getU16, getU32, getU8, setF32, setF64, setI16, setI32, setI64Big, setU16, setU32, setU8 } from "./memory"; import { mono_wasm_new_external_root } from "./roots"; import { mono_assert, GCHandle, JSHandle, MonoObject, MonoString, GCHandleNull, JSMarshalerArguments, JSFunctionSignature, JSMarshalerType, JSMarshalerArgument, MarshalerToJs, MarshalerToCs, WasmRoot, MarshalerType } from "./types"; diff --git a/src/mono/wasm/runtime/memory.ts b/src/mono/wasm/runtime/memory.ts index 2a5cf9592921b5..5ab35b8a12b763 100644 --- a/src/mono/wasm/runtime/memory.ts +++ b/src/mono/wasm/runtime/memory.ts @@ -2,10 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. import monoWasmThreads from "consts:monoWasmThreads"; -import { Module, runtimeHelpers } from "./imports"; import { mono_assert, MemOffset, NumberOrPointer } from "./types"; import { VoidPtr, CharPtr } from "./types/emscripten"; import cwraps, { I52Error } from "./cwraps"; +import { Module, runtimeHelpers } from "./globals"; const alloca_stack: Array = []; const alloca_buffer_size = 32 * 1024; @@ -73,6 +73,10 @@ export function setU16(offset: MemOffset, value: number): void { Module.HEAPU16[offset >>> 1] = value; } +export function setU16_unchecked(offset: MemOffset, value: number): void { + Module.HEAPU16[offset >>> 1] = value; +} + export function setU32_unchecked(offset: MemOffset, value: NumberOrPointer): void { Module.HEAPU32[offset >>> 2] = value; } diff --git a/src/mono/wasm/runtime/modularize-dotnet.md b/src/mono/wasm/runtime/modularize-dotnet.md index cbf5233773c102..63f4122f4e7fa0 100644 --- a/src/mono/wasm/runtime/modularize-dotnet.md +++ b/src/mono/wasm/runtime/modularize-dotnet.md @@ -5,37 +5,4 @@ See https://emscripten.org/docs/tools_reference/emcc.html#emcc-pre-js There are `-extern-pre-js`,`-pre-js`, `-post-js`, `-extern-post-js`. In `src\mono\wasm\build\WasmApp.Native.targets` we apply them by file naming convention as: `*.extpre.js`,`*.pre.js`, `*.post.js`, `*.extpost.js` -In `src\mono\wasm\runtime\CMakeLists.txt` which links only in-tree, we use same mapping explicitly. Right now CommonJS is default. - -# dotnet.es6.pre.js -- Executed second (2) -- Applied only when linking ES6 -- Will check that it was passed `moduleFactory` callback. Because of emscripten reasons it has confusing `createDotnetRuntime` name here. -- Will validate `Module.ready` is left un-overridden. - -# runtime.*.iffe.js -- Executed third (3) -- this is produced from `*.ts` files in this directory by rollupJS. - -# dotnet.*.post.js -- Executed last (4) -- When `onRuntimeInitialized` is overridden it would wait for emscriptens `Module.ready` -- Otherwise it would wait for MonoVM to load all assets and assemblies. -- It would pass on the API exports - -# About new API -The signature is -``` -function createDotnetRuntime(module: DotnetModuleConfig): Promise -``` - -Simplest intended usage looks like this in ES6: -``` -import createDotnetRuntime from './dotnet.js' - -await createDotnetRuntime({ - configSrc: "./mono-config.json", -}); -``` - -For more complex scenario with using APIs see `src\mono\sample\wasm` +In `src\mono\wasm\runtime\CMakeLists.txt` which links only in-tree, we use same mapping explicitly. diff --git a/src/mono/wasm/runtime/net6-legacy/buffers.ts b/src/mono/wasm/runtime/net6-legacy/buffers.ts index b82e36a5b69ff4..0a33b6991b0bdc 100644 --- a/src/mono/wasm/runtime/net6-legacy/buffers.ts +++ b/src/mono/wasm/runtime/net6-legacy/buffers.ts @@ -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. -import { Module } from "../imports"; +import { Module } from "../globals"; import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; import { mono_wasm_new_external_root } from "../roots"; import { MonoArray, MonoObjectRef, MonoObject } from "../types"; diff --git a/src/mono/wasm/runtime/net6-legacy/corebindings.ts b/src/mono/wasm/runtime/net6-legacy/corebindings.ts index 97f660910a5c23..489df81ece89af 100644 --- a/src/mono/wasm/runtime/net6-legacy/corebindings.ts +++ b/src/mono/wasm/runtime/net6-legacy/corebindings.ts @@ -4,10 +4,10 @@ import { JSHandle, GCHandle, MonoObjectRef, MonoMethod, MonoObject, WasmRoot } from "../types"; import { mono_bind_method, _create_primitive_converters } from "./method-binding"; import { mono_wasm_new_root } from "../roots"; -import { Module, runtimeHelpers } from "../imports"; +import { Module, runtimeHelpers } from "../globals"; import cwraps from "../cwraps"; import { PromiseController } from "../promise-controller"; -import { legacyHelpers, wasm_type_symbol } from "./imports"; +import { legacyHelpers, wasm_type_symbol } from "./globals"; import { find_corlib_class } from "../class-loader"; type SigLine = [lazy: boolean, jsname: string, csname: string, signature: string/*ArgsMarshalString*/]; const fn_signatures: SigLine[] = [ diff --git a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts index c19744f11c3507..2aefab4afb7a72 100644 --- a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts +++ b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts @@ -13,7 +13,7 @@ import { conv_string_root } from "../strings"; import { MarshalType, MonoType, MarshalError, MonoTypeNull, MonoArray, MonoArrayNull, MonoObject, MonoObjectNull, GCHandle, MonoStringRef, MonoObjectRef, MonoString, JSHandleDisposed, is_nullish, WasmRoot } from "../types"; import { Int32Ptr, VoidPtr } from "../types/emscripten"; import { legacyManagedExports } from "./corebindings"; -import { legacyHelpers } from "./imports"; +import { legacyHelpers } from "./globals"; import { js_to_mono_obj_root } from "./js-to-cs"; import { mono_bind_method, mono_method_get_call_signature_ref } from "./method-binding"; diff --git a/src/mono/wasm/runtime/net6-legacy/export-types.ts b/src/mono/wasm/runtime/net6-legacy/export-types.ts index 2253784ae8b65a..921689525e34a7 100644 --- a/src/mono/wasm/runtime/net6-legacy/export-types.ts +++ b/src/mono/wasm/runtime/net6-legacy/export-types.ts @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { MemOffset, MonoArray, MonoObject, MonoObjectRef, MonoString, NumberOrPointer, WasmRoot, WasmRootBuffer } from "../types"; -import { VoidPtr } from "../types/emscripten"; +import type { MemOffset, MonoArray, MonoObject, MonoObjectRef, MonoString, NumberOrPointer, WasmRoot, WasmRootBuffer } from "../types"; +import type { VoidPtr } from "../types/emscripten"; /** * @deprecated Please use methods in top level API object instead diff --git a/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts index 3e93287282e8a2..0c45c2749357ab 100644 --- a/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts +++ b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts @@ -4,7 +4,7 @@ import { legacy_c_functions as cwraps } from "../cwraps"; import { mono_wasm_runtime_ready } from "../debug"; import { mono_wasm_load_icu_data } from "../icu"; -import { runtimeHelpers } from "../imports"; +import { runtimeHelpers } from "../globals"; import { mono_wasm_load_bytes_into_heap, setB32, setI8, setI16, setI32, setI52, setU52, setI64Big, setU8, setU16, setU32, setF32, setF64, getB32, getI8, getI16, getI32, getI52, getU52, getI64Big, getU8, getU16, getU32, getF32, getF64 } from "../memory"; import { mono_wasm_new_root_buffer, mono_wasm_new_root, mono_wasm_new_external_root, mono_wasm_release_roots } from "../roots"; import { mono_run_main, mono_run_main_and_exit } from "../run"; diff --git a/src/mono/wasm/runtime/net6-legacy/imports.ts b/src/mono/wasm/runtime/net6-legacy/globals.ts similarity index 82% rename from src/mono/wasm/runtime/net6-legacy/imports.ts rename to src/mono/wasm/runtime/net6-legacy/globals.ts index d62ebf7806e7d1..cf69addeaee4ac 100644 --- a/src/mono/wasm/runtime/net6-legacy/imports.ts +++ b/src/mono/wasm/runtime/net6-legacy/globals.ts @@ -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. -import type { EarlyExports, MonoClass } from "../types"; +import type { GlobalObjects, MonoClass } from "../types"; import type { VoidPtr } from "../types/emscripten"; import type { BINDINGType, MONOType } from "./export-types"; @@ -11,11 +11,11 @@ export let BINDING: BINDINGType; export const legacyHelpers: LegacyHelpers = { }; -export function set_legacy_exports( - exports: EarlyExports, +export function initializeLegacyExports( + globals: GlobalObjects, ): void { - MONO = exports.mono; - BINDING = exports.binding; + MONO = globals.mono; + BINDING = globals.binding; } export type LegacyHelpers = { diff --git a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts index 2ccf51d09759ba..f4f81ef5615d7e 100644 --- a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts +++ b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts @@ -4,7 +4,7 @@ import { isThenable } from "../cancelable-promise"; import { legacy_c_functions as cwraps } from "../cwraps"; import { js_owned_gc_handle_symbol, assert_not_disposed, cs_owned_js_handle_symbol, mono_wasm_get_js_handle, setup_managed_proxy, mono_wasm_release_cs_owned_object, teardown_managed_proxy, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles"; -import { Module } from "../imports"; +import { Module } from "../globals"; import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; import { setI32_unchecked, setU32_unchecked, setF64, setB32 } from "../memory"; import { mono_wasm_new_root, mono_wasm_release_roots, mono_wasm_new_external_root } from "../roots"; @@ -14,7 +14,7 @@ import { TypedArray, Int32Ptr } from "../types/emscripten"; import { has_backing_array_buffer } from "./buffers"; import { legacyManagedExports } from "./corebindings"; import { get_js_owned_object_by_gc_handle_ref } from "./cs-to-js"; -import { legacyHelpers, wasm_type_symbol } from "./imports"; +import { legacyHelpers, wasm_type_symbol } from "./globals"; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function _js_to_mono_uri_root(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { diff --git a/src/mono/wasm/runtime/net6-legacy/method-binding.ts b/src/mono/wasm/runtime/net6-legacy/method-binding.ts index a5614e2e82dc7b..780301959061f6 100644 --- a/src/mono/wasm/runtime/net6-legacy/method-binding.ts +++ b/src/mono/wasm/runtime/net6-legacy/method-binding.ts @@ -3,7 +3,7 @@ import MonoWasmThreads from "consts:monoWasmThreads"; import { legacy_c_functions as cwraps } from "../cwraps"; -import { ENVIRONMENT_IS_PTHREAD, Module } from "../imports"; +import { ENVIRONMENT_IS_PTHREAD, Module } from "../globals"; import { parseFQN } from "../invoke-cs"; import { setI32, setU32, setF32, setF64, setU52, setI52, setB32, setI32_unchecked, setU32_unchecked, _zero_region, _create_temp_frame, getB32, getI32, getU32, getF32, getF64 } from "../memory"; import { mono_wasm_new_external_root, mono_wasm_new_root } from "../roots"; @@ -12,7 +12,7 @@ import { MonoMethod, MonoObject, MonoType, MonoClass, mono_assert, VoidPtrNull, import { VoidPtr } from "../types/emscripten"; import { legacyManagedExports } from "./corebindings"; import { get_js_owned_object_by_gc_handle_ref, _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js"; -import { BINDING, legacyHelpers } from "./imports"; +import { legacyHelpers } from "./globals"; import { js_to_mono_obj_root, _js_to_mono_uri_root, js_to_mono_enum } from "./js-to-cs"; import { _teardown_after_call } from "./method-calls"; @@ -99,18 +99,18 @@ export function _create_rebindable_named_function(name: string, argumentNames: s export function _create_primitive_converters(): void { const result = primitiveConverters; result.set("m", { steps: [{}], size: 0 }); - result.set("s", { steps: [{ convert_root: js_string_to_mono_string_root.bind(BINDING) }], size: 0, needs_root: true }); - result.set("S", { steps: [{ convert_root: js_string_to_mono_string_interned_root.bind(BINDING) }], size: 0, needs_root: true }); + result.set("s", { steps: [{ convert_root: js_string_to_mono_string_root.bind(Module) }], size: 0, needs_root: true }); + result.set("S", { steps: [{ convert_root: js_string_to_mono_string_interned_root.bind(Module) }], size: 0, needs_root: true }); // note we also bind first argument to false for both _js_to_mono_obj and _js_to_mono_uri, // because we will root the reference, so we don't need in-flight reference // also as those are callback arguments and we don't have platform code which would release the in-flight reference on C# end - result.set("o", { steps: [{ convert_root: js_to_mono_obj_root.bind(BINDING) }], size: 0, needs_root: true }); - result.set("u", { steps: [{ convert_root: _js_to_mono_uri_root.bind(BINDING, false) }], size: 0, needs_root: true }); + result.set("o", { steps: [{ convert_root: js_to_mono_obj_root.bind(Module) }], size: 0, needs_root: true }); + result.set("u", { steps: [{ convert_root: _js_to_mono_uri_root.bind(Module, false) }], size: 0, needs_root: true }); // ref object aka T&& - result.set("R", { steps: [{ convert_root: js_to_mono_obj_root.bind(BINDING), byref: true }], size: 0, needs_root: true }); + result.set("R", { steps: [{ convert_root: js_to_mono_obj_root.bind(Module), byref: true }], size: 0, needs_root: true }); // result.set ('k', { steps: [{ convert: js_to_mono_enum.bind (this), indirect: 'i64'}], size: 8}); - result.set("j", { steps: [{ convert: js_to_mono_enum.bind(BINDING), indirect: "i32" }], size: 8 }); + result.set("j", { steps: [{ convert: js_to_mono_enum.bind(Module), indirect: "i32" }], size: 8 }); result.set("b", { steps: [{ indirect: "bool" }], size: 8 }); result.set("i", { steps: [{ indirect: "i32" }], size: 8 }); diff --git a/src/mono/wasm/runtime/net6-legacy/method-calls.ts b/src/mono/wasm/runtime/net6-legacy/method-calls.ts index fa50cb01d42416..cf9fee9430ebd1 100644 --- a/src/mono/wasm/runtime/net6-legacy/method-calls.ts +++ b/src/mono/wasm/runtime/net6-legacy/method-calls.ts @@ -3,7 +3,7 @@ import MonoWasmThreads from "consts:monoWasmThreads"; import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles"; -import { Module, runtimeHelpers, INTERNAL, ENVIRONMENT_IS_PTHREAD } from "../imports"; +import { Module, runtimeHelpers, INTERNAL, ENVIRONMENT_IS_PTHREAD } from "../globals"; import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; import { _release_temp_frame } from "../memory"; import { mono_wasm_new_external_root, mono_wasm_new_root } from "../roots"; diff --git a/src/mono/wasm/runtime/package-lock.json b/src/mono/wasm/runtime/package-lock.json index 4455b87ca645a2..5894b4ec3680c8 100644 --- a/src/mono/wasm/runtime/package-lock.json +++ b/src/mono/wasm/runtime/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha1-OyXTjIlgC6otzCGe36iKdOssQno=", + "version": "7.21.4", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha1-0PqeRBOsqB8rI7lEJ5e9oYJu2zk=", "dev": true, "optional": true, "requires": { @@ -98,16 +98,31 @@ } } }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha1-ojUU6Pua8SadX3eIqlVnmNYca1k=", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.5.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", + "integrity": "sha1-9vcpsC/u4sdJ9X4zS3obX0CoFyQ=", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha1-KwRKs5/fp1tGiBhPnlc848Ww/5U=", + "version": "2.0.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", + "integrity": "sha1-AVdeOHB63Wd89zyhWJq7qNqJmgI=", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.5.1", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -115,10 +130,16 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.39.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@eslint/js/-/js-8.39.0.tgz", + "integrity": "sha1-WLU2vMhD9M0eAqfmFx2lwED01Es=", + "dev": true + }, "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha1-OK7ARMbIKPbtUdXXrj2bn69tuw8=", + "version": "0.11.8", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha1-A1lawgdaTcDxkcwhMd4U+9fUELk=", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -139,9 +160,9 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha1-wa7cYehT8rufXf5tRELTtWWyU7k=", + "version": "0.3.3", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha1-fgLm6135AartsIUUIDsJZhQCQJg=", "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", @@ -162,9 +183,9 @@ "dev": true }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha1-9FNRqu1FJ6KYUS7HL4EEDJmFgPs=", + "version": "0.3.3", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha1-gQgmVlnUwz5y/+FOM9bMXrWfL9o=", "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", @@ -172,19 +193,27 @@ } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha1-rdTJjTQUcqKJGQtCTvvbCWmRuyQ=", + "version": "1.4.15", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha1-18bmdVx4VnqVHgSrUu8P0m3lnzI=", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha1-eTBBJ3r5BzsJUaf+Dw2MTJjDaYU=", + "version": "0.3.18", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha1-JXg7IIba9v8dy1PJJJrkgOTdTNY=", "dev": true, "requires": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha1-rdTJjTQUcqKJGQtCTvvbCWmRuyQ=", + "dev": true + } } }, "@nodelib/fs.scandir": { @@ -214,18 +243,20 @@ } }, "@rollup/plugin-terser": { - "version": "0.1.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@rollup/plugin-terser/-/plugin-terser-0.1.0.tgz", - "integrity": "sha1-dTDA8RZnY3QZ1xggRhZGxBhSYEE=", + "version": "0.4.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@rollup/plugin-terser/-/plugin-terser-0.4.1.tgz", + "integrity": "sha1-XDI/0GY1UFYiS2mT/LFMQJ0phz4=", "dev": true, "requires": { + "serialize-javascript": "^6.0.0", + "smob": "^0.0.6", "terser": "^5.15.1" } }, "@rollup/plugin-typescript": { - "version": "9.0.2", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@rollup/plugin-typescript/-/plugin-typescript-9.0.2.tgz", - "integrity": "sha1-wM36OeJn8wb/cxZAWjVAbVgh6qc=", + "version": "11.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz", + "integrity": "sha1-TdKphHWnkSANPk3RuCNAc62WxTU=", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", @@ -250,9 +281,9 @@ } }, "@types/estree": { - "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha1-X7LlNsGum/NTZu7Yeegn+lnKQcI=", + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha1-qiJ1CWLzvw5511PTzAZ/AQyV8ZQ=", "dev": true }, "@types/json-schema": { @@ -268,70 +299,71 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.44.0.tgz", - "integrity": "sha1-EFeI8pkFDJF+uFxNn9BLCJ43QN4=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz", + "integrity": "sha1-mwnuFUG/8dLOvcuH585KQAOs3gg=", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.44.0", - "@typescript-eslint/type-utils": "5.44.0", - "@typescript-eslint/utils": "5.44.0", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/type-utils": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "@typescript-eslint/parser": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/parser/-/parser-5.44.0.tgz", - "integrity": "sha1-meLHEKIlIZHnp5ETJk9Dgzi4Rq0=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/parser/-/parser-5.59.1.tgz", + "integrity": "sha1-c8LBISfFwRgtLltxqPoqhdIVy7Q=", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.44.0", - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/typescript-estree": "5.44.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz", - "integrity": "sha1-mIw/NLRbNHTrn/BnTBgwne38PgQ=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz", + "integrity": "sha1-iiAiJxnOvFGYYYpdRBE3BbUf1/4=", "dev": true, "requires": { - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/visitor-keys": "5.44.0" + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1" } }, "@typescript-eslint/type-utils": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/type-utils/-/type-utils-5.44.0.tgz", - "integrity": "sha1-vFpuigJphQcUqHDJJowDgVDfs8c=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz", + "integrity": "sha1-Y5gdYWhP0k7aL58IwKR+ywAKIRE=", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.44.0", - "@typescript-eslint/utils": "5.44.0", + "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/types/-/types-5.44.0.tgz", - "integrity": "sha1-8/C4mq/3jwl6KSf+VojAfnhqAkE=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/types/-/types-5.59.1.tgz", + "integrity": "sha1-A/P+3RwETLM268NMx4VfEhmR9B0=", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz", - "integrity": "sha1-BGGzhiA+jTg7sSaLHtHam8kFsEU=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz", + "integrity": "sha1-SqVG0n/Q1HfGGPDKALSD8OyExDw=", "dev": true, "requires": { - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/visitor-keys": "5.44.0", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -340,35 +372,35 @@ } }, "@typescript-eslint/utils": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/utils/-/utils-5.44.0.tgz", - "integrity": "sha1-1zPaTXnWww8aaLUxzdoeDB8A1S0=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/utils/-/utils-5.59.1.tgz", + "integrity": "sha1-2J/HWK0j0hV8+uU/C0Kb3xXblHM=", "dev": true, "requires": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.44.0", - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/typescript-estree": "5.44.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.44.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz", - "integrity": "sha1-EHQNwokCu5A9Eu46AFzDpwIH1DM=", + "version": "5.59.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz", + "integrity": "sha1-DZbDbvtlYNf7jrhd4QRCwQ2PYFg=", "dev": true, "requires": { - "@typescript-eslint/types": "5.44.0", + "@typescript-eslint/types": "5.59.1", "eslint-visitor-keys": "^3.3.0" } }, "acorn": { - "version": "8.8.1", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha1-Cj+cvsxOw76m8KgLZq6N0tolC3M=", + "version": "8.8.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha1-Gy8l2wKvllOZuXdrDCw5EnbTfEo=", "dev": true }, "acorn-jsx": { @@ -550,13 +582,16 @@ "dev": true }, "eslint": { - "version": "8.28.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint/-/eslint-8.28.0.tgz", - "integrity": "sha1-gaaAcyY0Z3zIkBNLzdn9/qjmPW4=", + "version": "8.39.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint/-/eslint-8.39.0.tgz", + "integrity": "sha1-f9IKKV75LUOAnpFLcMOf1aI88/E=", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "8.39.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -565,17 +600,16 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.0", + "espree": "^9.5.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -590,16 +624,15 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { "eslint-scope": { - "version": "7.1.1", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha1-//NIlML2XlIm0wQaxIC0UToWNkI=", + "version": "7.2.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha1-8h69r9oCNS8QNjS5bdR9n4HKEXs=", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -611,15 +644,6 @@ "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha1-LupSkHAvJquP5TcDcP+GyWXSESM=", "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha1-bSN9mQg5UMeSkPJMdkKj3poo+eM=", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } } } }, @@ -633,44 +657,27 @@ "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha1-iuuvrOc0W7M1WdsKHxOh0tSMNnI=", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha1-9lMoJZMFknOSyTjtROsKXJsr0wM=", - "dev": true - } - } - }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha1-9kgPprHzDv4tGWiqisdFuGJGmCY=", + "version": "3.4.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha1-x/D5VhJM5ncEfdvBkqaPmZRU3tw=", "dev": true }, "espree": { - "version": "9.4.1", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/espree/-/espree-9.4.1.tgz", - "integrity": "sha1-UdYJJhVWeiws/3gzRF43wowAZb0=", + "version": "9.5.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/espree/-/espree-9.5.1.tgz", + "integrity": "sha1-Tyak1fGJBb9PLgvZkAKquAfpbdQ=", "dev": true, "requires": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.0" } }, "esquery": { - "version": "1.4.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha1-IUj/w4uC6McFff7UhCWz5h8PJKU=", + "version": "1.5.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha1-bOF3ON6Fd2lO3XNhxXGCrIyw2ws=", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -753,6 +760,17 @@ "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, "fast-json-stable-stringify": { @@ -768,9 +786,9 @@ "dev": true }, "fastq": { - "version": "1.13.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha1-YWdg+Ip1Jr38WWt8q4wYk4w2uYw=", + "version": "1.15.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha1-0E0HxqKmj+RZn+qNLhA6k3+uazo=", "dev": true, "requires": { "reusify": "^1.0.4" @@ -874,18 +892,18 @@ } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", + "version": "6.0.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha1-bSN9mQg5UMeSkPJMdkKj3poo+eM=", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, "globals": { - "version": "13.18.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/globals/-/globals-13.18.0.tgz", - "integrity": "sha1-+yJNrusrt9JUzSxkDwA1KLjQwdw=", + "version": "13.20.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/globals/-/globals-13.20.0.tgz", + "integrity": "sha1-6idqHlCP/U8WEoiPnRutHicXv4I=", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -933,9 +951,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha1-bTusj6f+DUXZ+b57rC/CeVd+NFo=", + "version": "5.2.4", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha1-opHAxheP8blgvv5H/N7DAWdKYyQ=", "dev": true }, "import-fresh": { @@ -971,9 +989,9 @@ "dev": true }, "is-core-module": { - "version": "2.11.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha1-rUyz44Y+gUUjyW8/WNJsxXD/AUQ=", + "version": "2.12.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha1-Nq1i9vc8glP9ZHJRehJIPPA+fsQ=", "dev": true, "requires": { "has": "^1.0.3" @@ -1124,9 +1142,9 @@ "dev": true }, "js-sdsl": { - "version": "4.2.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha1-J46Yt76libi6rwSMIK6xnretCdA=", + "version": "4.4.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha1-i0N9vmQtqpV2BAC2AjeO2P/qhDA=", "dev": true }, "js-tokens": { @@ -1192,12 +1210,12 @@ } }, "magic-string": { - "version": "0.26.7", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/magic-string/-/magic-string-0.26.7.tgz", - "integrity": "sha1-yvfa9hs06ZgvgijEUnR02siYHW8=", + "version": "0.30.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/magic-string/-/magic-string-0.30.0.tgz", + "integrity": "sha1-/VikdIxcRUczikJOkPpd0X9N5Sk=", "dev": true, "requires": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.13" } }, "merge-stream": { @@ -1388,9 +1406,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=", + "version": "2.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha1-9n+mfJTaj00M//mBruQRgGQZm48=", "dev": true }, "queue-microtask": { @@ -1399,19 +1417,22 @@ "integrity": "sha1-SSkii7xyTfrEPg77BYyve2z7YkM=", "dev": true }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha1-BCWido2PI7rXDKS5BGH6LxIT4bI=", - "dev": true + "randombytes": { + "version": "2.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } }, "resolve": { - "version": "1.22.1", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha1-J8suu1P5GrtJRwqSi7p1WAZqwXc=", + "version": "1.22.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha1-DtCUPU4wGGeVV2bJ8+GubQHGhF8=", "dev": true, "requires": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.11.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -1438,22 +1459,22 @@ } }, "rollup": { - "version": "3.4.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/rollup/-/rollup-3.4.0.tgz", - "integrity": "sha1-PzY9RkdN61Tm2jjTmMOvhFwbfUM=", + "version": "3.21.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/rollup/-/rollup-3.21.1.tgz", + "integrity": "sha1-1W8y7gQTg7YJCePTGVtUtpkS27A=", "dev": true, "requires": { "fsevents": "~2.3.2" } }, "rollup-plugin-dts": { - "version": "5.0.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/rollup-plugin-dts/-/rollup-plugin-dts-5.0.0.tgz", - "integrity": "sha1-1kXyIupvfWt9236pjEWg5aOlaew=", + "version": "5.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/rollup-plugin-dts/-/rollup-plugin-dts-5.3.0.tgz", + "integrity": "sha1-gKlZiAAvGI43b22zt+L1NnkWiVc=", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "magic-string": "^0.26.7" + "magic-string": "^0.30.0" } }, "run-parallel": { @@ -1465,15 +1486,30 @@ "queue-microtask": "^1.2.2" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=", + "dev": true + }, "semver": { - "version": "7.3.8", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/semver/-/semver-7.3.8.tgz", - "integrity": "sha1-B6eP6vs/ezI0fXJeM95+Ki32d5g=", + "version": "7.5.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/semver/-/semver-7.5.0.tgz", + "integrity": "sha1-7YxdyO+2xinIiyPUHcm/QMHZbNA=", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha1-sgbvsnw9oLCra1L0jRcLeZZFjlw=", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1501,6 +1537,12 @@ "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=", "dev": true }, + "smob": { + "version": "0.0.6", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/smob/-/smob-0.0.6.tgz", + "integrity": "sha1-CbJo/qkWFYongcFSBExhVa27iqE=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/source-map/-/source-map-0.6.1.tgz", @@ -1517,12 +1559,6 @@ "source-map": "^0.6.0" } }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha1-6oBL2UhXQC5pktBaOO8a41qatMQ=", - "dev": true - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1566,9 +1602,9 @@ "dev": true }, "terser": { - "version": "5.15.1", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/terser/-/terser-5.15.1.tgz", - "integrity": "sha1-hWGvbg/W2DlmnHO5K91Xd9hw7Ww=", + "version": "5.17.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/terser/-/terser-5.17.1.tgz", + "integrity": "sha1-lI8QgwRUdh4u7txt6+RcUyyD/Wk=", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.2", @@ -1593,9 +1629,9 @@ } }, "tslib": { - "version": "2.4.1", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha1-DQv7qsKIC5HiLfB2jlW+l1OlsX4=", + "version": "2.5.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha1-Qr/thvV4eutB0DGGbI9AJCng/d8=", "dev": true }, "tsutils": { @@ -1631,9 +1667,9 @@ "dev": true }, "typescript": { - "version": "4.9.3", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha1-OuowfBdGuMOEQ12Kw2uKLlgNhds=", + "version": "5.0.4", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha1-shf9IBGb1hqU1AESdOCrNpBY2js=", "dev": true }, "uri-js": { diff --git a/src/mono/wasm/runtime/package.json b/src/mono/wasm/runtime/package.json index 96adfde687dd34..46345ab644ff7c 100644 --- a/src/mono/wasm/runtime/package.json +++ b/src/mono/wasm/runtime/package.json @@ -21,18 +21,18 @@ "author": "Microsoft", "license": "MIT", "devDependencies": { - "@rollup/plugin-typescript": "9.0.2", + "@rollup/plugin-typescript": "11.1.0", "@rollup/plugin-virtual": "3.0.1", - "@rollup/plugin-terser": "0.1.0", - "@typescript-eslint/eslint-plugin": "5.44.0", - "@typescript-eslint/parser": "5.44.0", - "eslint": "8.28.0", + "@rollup/plugin-terser": "0.4.1", + "@typescript-eslint/eslint-plugin": "5.59.1", + "@typescript-eslint/parser": "5.59.1", + "eslint": "8.39.0", "fast-glob": "3.2.12", "git-commit-info": "2.0.1", - "rollup": "3.4.0", - "rollup-plugin-dts": "5.0.0", - "terser": "5.15.1", - "tslib": "2.4.1", - "typescript": "4.9.3" + "rollup": "3.21.1", + "rollup-plugin-dts": "5.3.0", + "terser": "5.17.1", + "tslib": "2.5.0", + "typescript": "5.0.4" } } diff --git a/src/mono/wasm/runtime/polyfills.ts b/src/mono/wasm/runtime/polyfills.ts index edbc423123d9b0..4edfffe60f4675 100644 --- a/src/mono/wasm/runtime/polyfills.ts +++ b/src/mono/wasm/runtime/polyfills.ts @@ -3,15 +3,15 @@ import BuildConfiguration from "consts:configuration"; import MonoWasmThreads from "consts:monoWasmThreads"; -import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, ENVIRONMENT_IS_WORKER, INTERNAL, Module, runtimeHelpers } from "./imports"; +import type { DotnetModuleConfigImports, EmscriptenReplacements } from "./types"; +import type { TypedArray } from "./types/emscripten"; +import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WORKER, ENVIRONMENT_IS_WEB, INTERNAL, Module, runtimeHelpers } from "./globals"; import { replaceEmscriptenPThreadLibrary } from "./pthreads/shared/emscripten-replacements"; -import { DotnetModuleConfigImports, EarlyReplacements } from "./types"; -import { TypedArray } from "./types/emscripten"; let node_fs: any | undefined = undefined; let node_url: any | undefined = undefined; -export function init_polyfills(replacements: EarlyReplacements): void { +export function init_polyfills(): void { // performance.now() is used by emscripten and doesn't work in JSC if (typeof globalThis.performance === "undefined") { @@ -119,7 +119,9 @@ export function init_polyfills(replacements: EarlyReplacements): void { } }; } +} +export function initializeReplacements(replacements: EmscriptenReplacements): void { // require replacement const imports = Module.imports = (Module.imports || {}) as DotnetModuleConfigImports; const requireWrapper = (wrappedRequire: Function) => (name: string) => { @@ -150,7 +152,7 @@ export function init_polyfills(replacements: EarlyReplacements): void { console.debug(`MONO_WASM: starting in ${runtimeHelpers.scriptDirectory}`); } if (Module.__locateFile === Module.locateFile) { - // above it's our early version from dotnet.es6.pre.js, we could replace it with better + // above it's our early version, we could replace it with better Module.locateFile = runtimeHelpers.locateFile = (path) => { if (isPathAbsolute(path)) return path; return runtimeHelpers.scriptDirectory + path; @@ -188,6 +190,9 @@ export async function init_polyfills_async(): Promise { const { performance } = INTERNAL.require("perf_hooks"); globalThis.performance = performance; } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore: + INTERNAL.process = await import(/* webpackIgnore: true */"process"); if (!globalThis.crypto) { globalThis.crypto = {}; @@ -292,7 +297,7 @@ function normalizeDirectoryUrl(dir: string) { return dir.slice(0, dir.lastIndexOf("/")) + "/"; } -export function detectScriptDirectory(replacements: EarlyReplacements): string { +export function detectScriptDirectory(replacements: EmscriptenReplacements): string { if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled replacements.scriptUrl = self.location.href; diff --git a/src/mono/wasm/runtime/profiler.ts b/src/mono/wasm/runtime/profiler.ts index 489cd4ff86856c..fbaa646d903bb7 100644 --- a/src/mono/wasm/runtime/profiler.ts +++ b/src/mono/wasm/runtime/profiler.ts @@ -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. -import { ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./imports"; +import { ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./globals"; import { AOTProfilerOptions, BrowserProfilerOptions } from "./types"; import cwraps from "./cwraps"; import { MonoMethod } from "./types"; diff --git a/src/mono/wasm/runtime/pthreads/browser/index.ts b/src/mono/wasm/runtime/pthreads/browser/index.ts index 16a61cf54adfcd..9910fcea2daea4 100644 --- a/src/mono/wasm/runtime/pthreads/browser/index.ts +++ b/src/mono/wasm/runtime/pthreads/browser/index.ts @@ -5,9 +5,10 @@ import { isMonoWorkerMessageChannelCreated, monoSymbol, makeMonoThreadMessageApp import { pthread_ptr } from "../shared/types"; import { MonoThreadMessage } from "../shared"; import { PromiseController, createPromiseController } from "../../promise-controller"; -import { MonoConfig, mono_assert } from "../../types"; +import { mono_assert } from "../../types"; import Internals from "../shared/emscripten-internals"; -import { runtimeHelpers } from "../../imports"; +import { runtimeHelpers } from "../../globals"; +import { MonoConfig } from "../../types-api"; const threads: Map = new Map(); diff --git a/src/mono/wasm/runtime/pthreads/shared/emscripten-internals.ts b/src/mono/wasm/runtime/pthreads/shared/emscripten-internals.ts index c0ac8c79c280c0..106d4318d37b24 100644 --- a/src/mono/wasm/runtime/pthreads/shared/emscripten-internals.ts +++ b/src/mono/wasm/runtime/pthreads/shared/emscripten-internals.ts @@ -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. -import { Module } from "../../imports"; +import { Module } from "../../globals"; import { pthread_ptr } from "./types"; /** @module emscripten-internals accessors to the functions in the emscripten PThreads library, including diff --git a/src/mono/wasm/runtime/pthreads/shared/emscripten-replacements.ts b/src/mono/wasm/runtime/pthreads/shared/emscripten-replacements.ts index 77b9c1fc0aeea3..681a64bb21a71f 100644 --- a/src/mono/wasm/runtime/pthreads/shared/emscripten-replacements.ts +++ b/src/mono/wasm/runtime/pthreads/shared/emscripten-replacements.ts @@ -8,7 +8,7 @@ import { afterThreadInitTLS } from "../worker"; import Internals from "./emscripten-internals"; import { resolve_asset_path } from "../../assets"; import { mono_assert } from "../../types"; -import { runtimeHelpers } from "../../imports"; +import { runtimeHelpers } from "../../globals"; /** @module emscripten-replacements Replacements for individual functions in the emscripten PThreads library. * These have a hard dependency on the version of Emscripten that we are using and may need to be kept in sync with diff --git a/src/mono/wasm/runtime/pthreads/shared/index.ts b/src/mono/wasm/runtime/pthreads/shared/index.ts index 774dbc76ec8af4..e5a8d655f3a639 100644 --- a/src/mono/wasm/runtime/pthreads/shared/index.ts +++ b/src/mono/wasm/runtime/pthreads/shared/index.ts @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { Module } from "../../imports"; -import { MonoConfig } from "../../types"; +import { Module } from "../../globals"; +import { MonoConfig } from "../../types-api"; import { pthread_ptr } from "./types"; export interface PThreadInfo { diff --git a/src/mono/wasm/runtime/pthreads/worker/index.ts b/src/mono/wasm/runtime/pthreads/worker/index.ts index da4c780804c55b..5669377e88b4c7 100644 --- a/src/mono/wasm/runtime/pthreads/worker/index.ts +++ b/src/mono/wasm/runtime/pthreads/worker/index.ts @@ -4,10 +4,10 @@ /// import MonoWasmThreads from "consts:monoWasmThreads"; -import { Module, ENVIRONMENT_IS_PTHREAD, runtimeHelpers, ENVIRONMENT_IS_WEB } from "../../imports"; +import { Module, ENVIRONMENT_IS_PTHREAD, runtimeHelpers, ENVIRONMENT_IS_WEB } from "../../globals"; import { makeChannelCreatedMonoMessage, makePreloadMonoMessage } from "../shared"; import type { pthread_ptr } from "../shared/types"; -import { mono_assert, is_nullish, MonoConfig, MonoConfigInternal } from "../../types"; +import { is_nullish, MonoConfigInternal, mono_assert } from "../../types"; import type { MonoThreadMessage } from "../shared"; import { PThreadSelf, @@ -18,6 +18,7 @@ import { } from "./events"; import { setup_proxy_console } from "../../logging"; import { afterConfigLoaded, preRunWorker } from "../../startup"; +import { MonoConfig } from "../../types-api"; // re-export some of the events types export { @@ -114,7 +115,8 @@ function onMonoConfigReceived(config: MonoConfigInternal): void { export function mono_wasm_pthread_on_pthread_attached(pthread_id: pthread_ptr): void { const self = pthread_self; mono_assert(self !== null && self.pthread_id == pthread_id, "expected pthread_self to be set already when attaching"); - console.debug("MONO_WASM: attaching pthread to runtime", pthread_id); + if (runtimeHelpers.diagnosticTracing) + console.debug("MONO_WASM: attaching pthread to runtime 0x" + pthread_id.toString(16)); preRunWorker(); currentWorkerThreadEvents.dispatchEvent(makeWorkerThreadEvent(dotnetPthreadAttached, self)); } @@ -127,7 +129,8 @@ export function afterThreadInitTLS(): void { if (ENVIRONMENT_IS_PTHREAD) { const pthread_ptr = (Module)["_pthread_self"](); mono_assert(!is_nullish(pthread_ptr), "pthread_self() returned null"); - console.debug("MONO_WASM: after thread init, pthread ptr", pthread_ptr); + if (runtimeHelpers.diagnosticTracing) + console.debug("MONO_WASM: after thread init, pthread ptr 0x" + pthread_ptr.toString(16)); const self = setupChannelToMainThread(pthread_ptr); currentWorkerThreadEvents.dispatchEvent(makeWorkerThreadEvent(dotnetPthreadCreated, self)); } diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index 58e9114c3ae042..05b49a0b81df0e 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import cwraps from "./cwraps"; -import { Module } from "./imports"; +import { Module } from "./globals"; import { VoidPtr, ManagedPointer, NativePointer } from "./types/emscripten"; import { MonoObjectRef, MonoObjectRefNull, MonoObject, is_nullish, WasmRoot, WasmRootBuffer } from "./types"; import { _zero_region } from "./memory"; diff --git a/src/mono/wasm/runtime/run-outer.ts b/src/mono/wasm/runtime/run-outer.ts index 8785c0e2c639d2..0321cd8e574100 100644 --- a/src/mono/wasm/runtime/run-outer.ts +++ b/src/mono/wasm/runtime/run-outer.ts @@ -2,42 +2,39 @@ // The .NET Foundation licenses this file to you under the MIT license. // WARNING: code in this file is executed before any of the emscripten code, so there is very little initialized already -import { WebAssemblyStartOptions } from "./blazor/WebAssemblyStartOptions"; -import { emscriptenEntrypoint, runtimeHelpers } from "./imports"; -import { setup_proxy_console } from "./logging"; + +import type { MonoConfig, DotnetHostBuilder, DotnetModuleConfig, RuntimeAPI, WebAssemblyStartOptions } from "./types-api"; +import type { MonoConfigInternal, GlobalObjects, EmscriptenModuleInternal } from "./types"; + +import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_WEB, setGlobalObjects } from "./globals"; import { mono_exit } from "./run"; -import { DotnetModuleConfig, MonoConfig, MonoConfigInternal, mono_assert, RuntimeAPI } from "./types"; - -export interface DotnetHostBuilder { - withConfig(config: MonoConfig): DotnetHostBuilder - withConfigSrc(configSrc: string): DotnetHostBuilder - withApplicationArguments(...args: string[]): DotnetHostBuilder - withEnvironmentVariable(name: string, value: string): DotnetHostBuilder - withEnvironmentVariables(variables: { [i: string]: string; }): DotnetHostBuilder - withVirtualWorkingDirectory(vfsPath: string): DotnetHostBuilder - withDiagnosticTracing(enabled: boolean): DotnetHostBuilder - withDebugging(level: number): DotnetHostBuilder - withMainAssembly(mainAssemblyName: string): DotnetHostBuilder - withApplicationArgumentsFromQuery(): DotnetHostBuilder - withStartupMemoryCache(value: boolean): DotnetHostBuilder - create(): Promise - run(): Promise -} +import { mono_assert } from "./types"; +import { setup_proxy_console } from "./logging"; +import { deep_merge_config, deep_merge_module } from "./config"; +import { initializeExports } from "./exports"; + +export const globalObjectsRoot: GlobalObjects = { + mono: {}, + binding: {}, + internal: {}, + module: {}, + helpers: {}, + api: {} +} as any; + +setGlobalObjects(globalObjectsRoot); +const module = globalObjectsRoot.module; +const monoConfig = module.config as MonoConfigInternal; -class HostBuilder implements DotnetHostBuilder { +export class HostBuilder implements DotnetHostBuilder { private instance?: RuntimeAPI; private applicationArguments?: string[]; private virtualWorkingDirectory?: string; - private moduleConfig: DotnetModuleConfig = { - disableDotnet6Compatibility: true, - configSrc: "./mono-config.json", - config: runtimeHelpers.config, - }; // internal withModuleConfig(moduleConfig: DotnetModuleConfig): DotnetHostBuilder { try { - Object.assign(this.moduleConfig!, moduleConfig); + deep_merge_module(module, moduleConfig); return this; } catch (err) { mono_exit(1, err); @@ -48,10 +45,9 @@ class HostBuilder implements DotnetHostBuilder { // internal withConsoleForwarding(): DotnetHostBuilder { try { - const configInternal: MonoConfigInternal = { + deep_merge_config(monoConfig, { forwardConsoleLogsToWS: true - }; - Object.assign(this.moduleConfig.config!, configInternal); + }); return this; } catch (err) { mono_exit(1, err); @@ -64,7 +60,7 @@ class HostBuilder implements DotnetHostBuilder { const handler = function fatal_handler(event: Event, error: any) { event.preventDefault(); try { - mono_exit(1, error); + if (!error || !error.silent) mono_exit(1, error); } catch (err) { // no not re-throw from the fatal handler } @@ -85,10 +81,9 @@ class HostBuilder implements DotnetHostBuilder { // internal withAsyncFlushOnExit(): DotnetHostBuilder { try { - const configInternal: MonoConfigInternal = { + deep_merge_config(monoConfig, { asyncFlushOnExit: true - }; - Object.assign(this.moduleConfig.config!, configInternal); + }); return this; } catch (err) { mono_exit(1, err); @@ -99,10 +94,9 @@ class HostBuilder implements DotnetHostBuilder { // internal withExitCodeLogging(): DotnetHostBuilder { try { - const configInternal: MonoConfigInternal = { + deep_merge_config(monoConfig, { logExitCode: true - }; - Object.assign(this.moduleConfig.config!, configInternal); + }); return this; } catch (err) { mono_exit(1, err); @@ -113,10 +107,9 @@ class HostBuilder implements DotnetHostBuilder { // internal withElementOnExit(): DotnetHostBuilder { try { - const configInternal: MonoConfigInternal = { + deep_merge_config(monoConfig, { appendElementOnExit: true - }; - Object.assign(this.moduleConfig.config!, configInternal); + }); return this; } catch (err) { mono_exit(1, err); @@ -128,10 +121,9 @@ class HostBuilder implements DotnetHostBuilder { // todo fallback later by debugLevel withWaitingForDebugger(level: number): DotnetHostBuilder { try { - const configInternal: MonoConfigInternal = { + deep_merge_config(monoConfig, { waitForDebugger: level - }; - Object.assign(this.moduleConfig.config!, configInternal); + }); return this; } catch (err) { mono_exit(1, err); @@ -141,10 +133,9 @@ class HostBuilder implements DotnetHostBuilder { withStartupMemoryCache(value: boolean): DotnetHostBuilder { try { - const configInternal: MonoConfigInternal = { + deep_merge_config(monoConfig, { startupMemoryCache: value - }; - Object.assign(this.moduleConfig.config!, configInternal); + }); return this; } catch (err) { mono_exit(1, err); @@ -154,10 +145,7 @@ class HostBuilder implements DotnetHostBuilder { withConfig(config: MonoConfig): DotnetHostBuilder { try { - const providedConfig = { ...config }; - providedConfig.assets = [...(this.moduleConfig.config!.assets || []), ...(providedConfig.assets || [])]; - providedConfig.environmentVariables = { ...(this.moduleConfig.config!.environmentVariables || {}), ...(providedConfig.environmentVariables || {}) }; - Object.assign(this.moduleConfig.config!, providedConfig); + deep_merge_config(monoConfig, config); return this; } catch (err) { mono_exit(1, err); @@ -168,7 +156,7 @@ class HostBuilder implements DotnetHostBuilder { withConfigSrc(configSrc: string): DotnetHostBuilder { try { mono_assert(configSrc && typeof configSrc === "string", "must be file path or URL"); - Object.assign(this.moduleConfig, { configSrc }); + deep_merge_module(module, { configSrc }); return this; } catch (err) { mono_exit(1, err); @@ -189,7 +177,11 @@ class HostBuilder implements DotnetHostBuilder { withEnvironmentVariable(name: string, value: string): DotnetHostBuilder { try { - this.moduleConfig.config!.environmentVariables![name] = value; + const environmentVariables: { [key: string]: string } = {}; + environmentVariables[name] = value; + deep_merge_config(monoConfig, { + environmentVariables + }); return this; } catch (err) { mono_exit(1, err); @@ -200,7 +192,9 @@ class HostBuilder implements DotnetHostBuilder { withEnvironmentVariables(variables: { [i: string]: string; }): DotnetHostBuilder { try { mono_assert(variables && typeof variables === "object", "must be dictionary object"); - Object.assign(this.moduleConfig.config!.environmentVariables!, variables); + deep_merge_config(monoConfig, { + environmentVariables: variables + }); return this; } catch (err) { mono_exit(1, err); @@ -211,7 +205,9 @@ class HostBuilder implements DotnetHostBuilder { withDiagnosticTracing(enabled: boolean): DotnetHostBuilder { try { mono_assert(typeof enabled === "boolean", "must be boolean"); - this.moduleConfig.config!.diagnosticTracing = enabled; + deep_merge_config(monoConfig, { + diagnosticTracing: enabled + }); return this; } catch (err) { mono_exit(1, err); @@ -222,7 +218,9 @@ class HostBuilder implements DotnetHostBuilder { withDebugging(level: number): DotnetHostBuilder { try { mono_assert(level && typeof level === "number", "must be number"); - this.moduleConfig.config!.debugLevel = level; + deep_merge_config(monoConfig, { + debugLevel: level + }); return this; } catch (err) { mono_exit(1, err); @@ -244,8 +242,9 @@ class HostBuilder implements DotnetHostBuilder { withRuntimeOptions(runtimeOptions: string[]): DotnetHostBuilder { try { mono_assert(runtimeOptions && Array.isArray(runtimeOptions), "must be array of strings"); - const configInternal = this.moduleConfig.config as MonoConfigInternal; - configInternal.runtimeOptions = [...(configInternal.runtimeOptions || []), ...(runtimeOptions || [])]; + deep_merge_config(monoConfig, { + runtimeOptions + }); return this; } catch (err) { mono_exit(1, err); @@ -255,7 +254,9 @@ class HostBuilder implements DotnetHostBuilder { withMainAssembly(mainAssemblyName: string): DotnetHostBuilder { try { - this.moduleConfig.config!.mainAssemblyName = mainAssemblyName; + deep_merge_config(monoConfig, { + mainAssemblyName + }); return this; } catch (err) { mono_exit(1, err); @@ -283,15 +284,16 @@ class HostBuilder implements DotnetHostBuilder { } withStartupOptions(startupOptions: Partial): DotnetHostBuilder { - const configInternal = this.moduleConfig.config as MonoConfigInternal; - configInternal.startupOptions = startupOptions; + deep_merge_config(monoConfig, { + startupOptions + }); return this.withConfigSrc("blazor.boot.json"); } async create(): Promise { try { if (!this.instance) { - if (ENVIRONMENT_IS_WEB && (this.moduleConfig.config! as MonoConfigInternal).forwardConsoleLogsToWS && typeof globalThis.WebSocket != "undefined") { + if (ENVIRONMENT_IS_WEB && (module.config! as MonoConfigInternal).forwardConsoleLogsToWS && typeof globalThis.WebSocket != "undefined") { setup_proxy_console("main", globalThis.console, globalThis.location.origin); } if (ENVIRONMENT_IS_NODE) { @@ -302,9 +304,10 @@ class HostBuilder implements DotnetHostBuilder { throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}'`); } } - mono_assert(this.moduleConfig, "Null moduleConfig"); - mono_assert(this.moduleConfig.config, "Null moduleConfig.config"); - this.instance = await emscriptenEntrypoint(this.moduleConfig); + mono_assert(module, "Null moduleConfig"); + mono_assert(module.config, "Null moduleConfig.config"); + await createEmscripten(module); + this.instance = globalObjectsRoot.api; } if (this.virtualWorkingDirectory) { const FS = (this.instance!.Module as any).FS; @@ -321,11 +324,11 @@ class HostBuilder implements DotnetHostBuilder { async run(): Promise { try { - mono_assert(this.moduleConfig.config, "Null moduleConfig.config"); + mono_assert(module.config, "Null moduleConfig.config"); if (!this.instance) { await this.create(); } - mono_assert(this.moduleConfig.config.mainAssemblyName, "Null moduleConfig.config.mainAssemblyName"); + mono_assert(module.config.mainAssemblyName, "Null moduleConfig.config.mainAssemblyName"); if (!this.applicationArguments) { if (ENVIRONMENT_IS_NODE) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -336,7 +339,7 @@ class HostBuilder implements DotnetHostBuilder { this.applicationArguments = []; } } - return this.instance!.runMainAndExit(this.moduleConfig.config.mainAssemblyName, this.applicationArguments!); + return this.instance!.runMainAndExit(module.config.mainAssemblyName, this.applicationArguments!); } catch (err) { mono_exit(1, err); throw err; @@ -344,4 +347,23 @@ class HostBuilder implements DotnetHostBuilder { } } -export const dotnet: DotnetHostBuilder = new HostBuilder(); +export function unifyModuleConfig(originalModule: EmscriptenModuleInternal, moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)): DotnetModuleConfig { + initializeExports(); + Object.assign(module, { ready: originalModule.ready }); + if (typeof moduleFactory === "function") { + const extension = moduleFactory(globalObjectsRoot.api) as any; + if (extension.ready) { + throw new Error("MONO_WASM: Module.ready couldn't be redefined."); + } + Object.assign(module, extension); + deep_merge_module(module, extension); + } + else if (typeof moduleFactory === "object") { + deep_merge_module(module, moduleFactory); + } + else { + throw new Error("MONO_WASM: Can't use moduleFactory callback of createDotnetRuntime function."); + } + + return module; +} diff --git a/src/mono/wasm/runtime/run.ts b/src/mono/wasm/runtime/run.ts index 27d1a65fd6fb60..9b92f33555e65d 100644 --- a/src/mono/wasm/runtime/run.ts +++ b/src/mono/wasm/runtime/run.ts @@ -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. -import { ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./imports"; +import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_WEB, INTERNAL, Module, runtimeHelpers } from "./globals"; import { mono_wasm_wait_for_debugger } from "./debug"; import { abort_startup, mono_wasm_set_main_args } from "./startup"; import cwraps from "./cwraps"; @@ -64,7 +64,7 @@ export function mono_on_abort(error: any): void { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function mono_exit(exit_code: number, reason?: any): void { - if (runtimeHelpers.config.asyncFlushOnExit && exit_code === 0) { + if (runtimeHelpers.config && runtimeHelpers.config.asyncFlushOnExit && exit_code === 0) { // this would NOT call Node's exit() immediately, it's a hanging promise (async () => { try { @@ -127,7 +127,11 @@ function set_exit_code_and_quit_now(exit_code: number, reason?: any): void { logErrorOnExit(exit_code, reason); appendElementOnExit(exit_code); if (exit_code !== 0 || !ENVIRONMENT_IS_WEB) { - if (runtimeHelpers.quit) { + if (ENVIRONMENT_IS_NODE && INTERNAL.process) { + INTERNAL.process.exit(exit_code); + throw reason; + } + else if (runtimeHelpers.quit) { runtimeHelpers.quit(exit_code, reason); } else { throw reason; @@ -136,7 +140,7 @@ function set_exit_code_and_quit_now(exit_code: number, reason?: any): void { } function appendElementOnExit(exit_code: number) { - if (ENVIRONMENT_IS_WEB && runtimeHelpers.config.appendElementOnExit) { + if (ENVIRONMENT_IS_WEB && runtimeHelpers.config && runtimeHelpers.config.appendElementOnExit) { //Tell xharness WasmBrowserTestRunner what was the exit code const tests_done_elem = document.createElement("label"); tests_done_elem.id = "tests_done"; @@ -147,7 +151,7 @@ function appendElementOnExit(exit_code: number) { } function logErrorOnExit(exit_code: number, reason?: any) { - if (runtimeHelpers.config.logExitCode) { + if (runtimeHelpers.config && runtimeHelpers.config.logExitCode) { if (exit_code != 0 && reason) { if (reason instanceof Error) console.error(mono_wasm_stringify_as_error_with_stack(reason)); diff --git a/src/mono/wasm/runtime/snapshot.ts b/src/mono/wasm/runtime/snapshot.ts index eb96dec46c5611..cf225916edeeab 100644 --- a/src/mono/wasm/runtime/snapshot.ts +++ b/src/mono/wasm/runtime/snapshot.ts @@ -4,7 +4,7 @@ import ProductVersion from "consts:productVersion"; import GitHash from "consts:gitHash"; import MonoWasmThreads from "consts:monoWasmThreads"; -import { runtimeHelpers } from "./imports"; +import { ENVIRONMENT_IS_WEB, runtimeHelpers } from "./globals"; const memoryPrefix = "https://dotnet.generated.invalid/wasm-memory"; diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 92c644c64a182b..1ae473cf243389 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -4,8 +4,11 @@ import BuildConfiguration from "consts:configuration"; import MonoWasmThreads from "consts:monoWasmThreads"; import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; -import { CharPtrNull, DotnetModule, RuntimeAPI, MonoConfig, MonoConfigInternal, DotnetModuleInternal, mono_assert } from "./types"; -import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, disableLegacyJsInterop, INTERNAL, Module, runtimeHelpers } from "./imports"; +import type { MonoConfig } from "./types-api"; +import type { MonoConfigInternal, DotnetModuleInternal } from "./types"; + +import { mono_assert, CharPtrNull } from "./types"; +import { disableLegacyJsInterop, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, exportedRuntimeAPI, INTERNAL, Module, runtimeHelpers } from "./globals"; import cwraps, { init_c_exports } from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; import { toBase64StringImpl } from "./base64"; @@ -31,7 +34,7 @@ import { loadBootConfig } from "./blazor/_Integration"; // legacy import { init_legacy_exports } from "./net6-legacy/corebindings"; import { cwraps_binding_api, cwraps_mono_api } from "./net6-legacy/exports-legacy"; -import { BINDING, MONO } from "./net6-legacy/imports"; +import { BINDING, MONO } from "./net6-legacy/globals"; import { init_globalization } from "./icu"; let config: MonoConfigInternal = undefined as any; @@ -52,8 +55,27 @@ const MONO_PTHREAD_POOL_SIZE = 4; // we are making emscripten startup async friendly // emscripten is executing the events without awaiting it and so we need to block progress via PromiseControllers above -export function configure_emscripten_startup(module: DotnetModuleInternal, exportedAPI: RuntimeAPI): void { +export function configureEmscriptenStartup(module: DotnetModuleInternal): void { const mark = startMeasure(); + + if (!module.configSrc && (!module.config || Object.keys(module.config).length === 0 || !module.config.assets)) { + // if config file location nor assets are provided + module.configSrc = "./mono-config.json"; + } + + if (!module["locateFile"]) { + // this is dummy plug so that wasmBinaryFile doesn't try to use URL class + module["locateFile"] = module["__locateFile"] = (path) => runtimeHelpers.scriptDirectory + path; + } + + if (!module.out) { + module.out = console.log.bind(console); + } + + if (!module.err) { + module.err = console.error.bind(console); + } + // these all could be overridden on DotnetModuleConfig, we are chaing them to async below, as opposed to emscripten // when user set configSrc or config, we are running our default startup sequence. const userInstantiateWasm: undefined | ((imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback) => any) = module.instantiateWasm; @@ -83,7 +105,8 @@ export function configure_emscripten_startup(module: DotnetModuleInternal, expor endMeasure(mark, MeasuredBlock.emscriptenStartup); // - here we resolve the promise returned by createDotnetRuntime export // - any code after createDotnetRuntime is executed now - dotnetReady.promise_control.resolve(exportedAPI); + dotnetReady.promise_control.resolve(exportedRuntimeAPI); + runtimeHelpers.runtimeReady = true; }).catch(err => { dotnetReady.promise_control.reject(err); }); @@ -94,7 +117,6 @@ export function configure_emscripten_startup(module: DotnetModuleInternal, expor } } - function instantiateWasm( imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback, @@ -210,11 +232,11 @@ export function preRunWorker() { async function preRunAsync(userPreRun: (() => void)[]) { Module.addRunDependency("mono_pre_run_async"); // wait for previous stages - await afterInstantiateWasm.promise; - await afterPreInit.promise; - if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: preRunAsync"); - const mark = startMeasure(); try { + await afterInstantiateWasm.promise; + await afterPreInit.promise; + if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: preRunAsync"); + const mark = startMeasure(); // all user Module.preRun callbacks userPreRun.map(fn => fn()); endMeasure(mark, MeasuredBlock.preRun); @@ -229,13 +251,14 @@ async function preRunAsync(userPreRun: (() => void)[]) { } async function onRuntimeInitializedAsync(userOnRuntimeInitialized: () => void) { - // wait for previous stage - await afterPreRun.promise; - if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: onRuntimeInitialized"); - const mark = startMeasure(); - // signal this stage, this will allow pending assets to allocate memory - beforeOnRuntimeInitialized.promise_control.resolve(); try { + // wait for previous stage + await afterPreRun.promise; + if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: onRuntimeInitialized"); + const mark = startMeasure(); + // signal this stage, this will allow pending assets to allocate memory + beforeOnRuntimeInitialized.promise_control.resolve(); + await wait_for_all_assets(); // Diagnostics early are not supported with memory snapshot. See below how we enable them later. @@ -302,9 +325,9 @@ async function onRuntimeInitializedAsync(userOnRuntimeInitialized: () => void) { async function postRunAsync(userpostRun: (() => void)[]) { // wait for previous stage - await afterOnRuntimeInitialized.promise; - if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: postRunAsync"); try { + await afterOnRuntimeInitialized.promise; + if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: postRunAsync"); const mark = startMeasure(); // create /usr/share folder which is SpecialFolder.CommonApplicationData @@ -335,8 +358,15 @@ export function abort_startup(reason: any, should_exit: boolean): void { beforeOnRuntimeInitialized.promise_control.reject(reason); afterOnRuntimeInitialized.promise_control.reject(reason); afterPostRun.promise_control.reject(reason); - if (should_exit && (typeof reason !== "object" || reason.silent !== true)) { - mono_exit(1, reason); + if (typeof reason !== "object" || reason.silent !== true) { + if (should_exit) { + mono_exit(1, reason); + } + else if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) { + const wasm_exit = cwraps.mono_wasm_exit; + wasm_exit(1); + } + throw reason; } } @@ -346,7 +376,6 @@ function mono_wasm_pre_init_essential(isWorker: boolean): void { if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_pre_init_essential"); - // init_polyfills() is already called from export.ts init_c_exports(); cwraps_internal(INTERNAL); if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { @@ -595,13 +624,7 @@ export function mono_wasm_load_runtime(unused?: string, debugLevel?: number): vo } catch (err: any) { _print_error("MONO_WASM: mono_wasm_load_runtime () failed", err); - abort_startup(err, false); - if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) { - const wasm_exit = cwraps.mono_wasm_exit; - wasm_exit(1); - } - throw err; } } @@ -667,7 +690,7 @@ export async function mono_wasm_load_config(configFilePath?: string): Promiseconfig); + await Module.onConfigLoaded(config, exportedRuntimeAPI); normalizeConfig(); } catch (err: any) { @@ -678,11 +701,10 @@ export async function mono_wasm_load_config(configFilePath?: string): Promise{ message: errMessage, error: err, isError: true }; + abort_startup(errMessage, true); throw err; } - } function normalizeConfig() { @@ -757,17 +779,16 @@ export function mono_wasm_set_main_args(name: string, allRuntimeArguments: strin /// 1. Emscripten skips a lot of initialization on the pthread workers, Module may not have everything you expect. /// 2. Emscripten does not run any event but preInit in the workers. /// 3. At the point when this executes there is no pthread assigned to the worker yet. -export async function mono_wasm_pthread_worker_init(module: DotnetModule, exportedAPI: RuntimeAPI): Promise { +export async function configureWorkerStartup(module: DotnetModuleInternal): Promise { pthreads_worker.setupPreloadChannelToMainThread(); // This is a good place for subsystems to attach listeners for pthreads_worker.currentWorkerThreadEvents pthreads_worker.currentWorkerThreadEvents.addEventListener(pthreads_worker.dotnetPthreadCreated, (ev) => { - console.debug("MONO_WASM: pthread created", ev.pthread_self.pthread_id); + if (runtimeHelpers.diagnosticTracing) + console.debug("MONO_WASM: pthread created 0x" + ev.pthread_self.pthread_id.toString(16)); }); - // this is the only event which is called on worker + // these are the only events which are called on worker module.preInit = [() => preInitWorkerAsync()]; module.instantiateWasm = instantiateWasmWorker; - await afterPreInit.promise; - return exportedAPI.Module; } diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 8eba930124db5c..9ec559ff219997 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -3,7 +3,7 @@ import { mono_wasm_new_root_buffer } from "./roots"; import { MonoString, MonoStringNull, is_nullish, WasmRoot, WasmRootBuffer } from "./types"; -import { Module } from "./imports"; +import { Module } from "./globals"; import cwraps from "./cwraps"; import { mono_wasm_new_root } from "./roots"; import { getI32, getU32 } from "./memory"; diff --git a/src/mono/wasm/runtime/types-api.ts b/src/mono/wasm/runtime/types-api.ts new file mode 100644 index 00000000000000..3fd1c327e0c1d7 --- /dev/null +++ b/src/mono/wasm/runtime/types-api.ts @@ -0,0 +1,245 @@ +import type { EmscriptenModule, NativePointer } from "./types/emscripten"; + +export interface DotnetHostBuilder { + withConfig(config: MonoConfig): DotnetHostBuilder + withConfigSrc(configSrc: string): DotnetHostBuilder + withApplicationArguments(...args: string[]): DotnetHostBuilder + withEnvironmentVariable(name: string, value: string): DotnetHostBuilder + withEnvironmentVariables(variables: { [i: string]: string; }): DotnetHostBuilder + withVirtualWorkingDirectory(vfsPath: string): DotnetHostBuilder + withDiagnosticTracing(enabled: boolean): DotnetHostBuilder + withDebugging(level: number): DotnetHostBuilder + withMainAssembly(mainAssemblyName: string): DotnetHostBuilder + withApplicationArgumentsFromQuery(): DotnetHostBuilder + create(): Promise + run(): Promise +} + +export type MonoConfig = { + /** + * The subfolder containing managed assemblies and pdbs. This is relative to dotnet.js script. + */ + assemblyRootFolder?: string, + /** + * A list of assets to load along with the runtime. + */ + assets?: AssetEntry[], + /** + * Additional search locations for assets. + */ + remoteSources?: string[], // Sources will be checked in sequential order until the asset is found. The string "./" indicates to load from the application directory (as with the files in assembly_list), and a fully-qualified URL like "https://example.com/" indicates that asset loads can be attempted from a remote server. Sources must end with a "/". + /** + * It will not fail the startup is .pdb files can't be downloaded + */ + ignorePdbLoadErrors?: boolean, + /** + * We are throttling parallel downloads in order to avoid net::ERR_INSUFFICIENT_RESOURCES on chrome. The default value is 16. + */ + maxParallelDownloads?: number, + /** + * We are making up to 2 more delayed attempts to download same asset. Default true. + */ + enableDownloadRetry?: boolean, + /** + * Name of the assembly with main entrypoint + */ + mainAssemblyName?: string, + /** + * Configures the runtime's globalization mode + */ + globalizationMode?: GlobalizationMode, + /** + * debugLevel > 0 enables debugging and sets the debug log level to debugLevel + * debugLevel == 0 disables debugging and enables interpreter optimizations + * debugLevel < 0 enabled debugging and disables debug logging. + */ + debugLevel?: number, + /** + * Enables diagnostic log messages during startup + */ + diagnosticTracing?: boolean + /** + * Dictionary-style Object containing environment variables + */ + environmentVariables?: { + [i: string]: string; + }, + /** + * initial number of workers to add to the emscripten pthread pool + */ + pthreadPoolSize?: number, + /** + * If true, the snapshot of runtime's memory will be stored in the browser and used for faster startup next time. Default is false. + */ + startupMemoryCache?: boolean, + /** + * hash of assets + */ + assetsHash?: string, + /** + * application environment + */ + applicationEnvironment?: string +}; + +export interface ResourceRequest { + name: string, // the name of the asset, including extension. + behavior: AssetBehaviours, // determines how the asset will be handled once loaded + resolvedUrl?: string; + hash?: string; +} + +export interface LoadingResource { + name: string; + url: string; + response: Promise; +} + +// Types of assets that can be in the mono-config.js/mono-config.json file (taken from /src/tasks/WasmAppBuilder/WasmAppBuilder.cs) +export interface AssetEntry extends ResourceRequest { + /** + * If specified, overrides the path of the asset in the virtual filesystem and similar data structures once downloaded. + */ + virtualPath?: string, + /** + * Culture code + */ + culture?: string, + /** + * If true, an attempt will be made to load the asset from each location in MonoConfig.remoteSources. + */ + loadRemote?: boolean, // + /** + * If true, the runtime startup would not fail if the asset download was not successful. + */ + isOptional?: boolean + /** + * If provided, runtime doesn't have to fetch the data. + * Runtime would set the buffer to null after instantiation to free the memory. + */ + buffer?: ArrayBuffer + /** + * It's metadata + fetch-like Promise + * If provided, the runtime doesn't have to initiate the download. It would just await the response. + */ + pendingDownload?: LoadingResource +} + +export type AssetBehaviours = + "resource" // load asset as a managed resource assembly + | "assembly" // load asset as a managed assembly + | "pdb" // load asset as a managed debugging information + | "heap" // store asset into the native heap + | "icu" // load asset as an ICU data archive + | "vfs" // load asset into the virtual filesystem (for fopen, File.Open, etc) + | "dotnetwasm" // the binary of the dotnet runtime + | "js-module-threads" // the javascript module for threads + | "symbols" // the javascript module for threads + +export type GlobalizationMode = + "icu" | // load ICU globalization data from any runtime assets with behavior "icu". + "invariant" | // operate in invariant globalization mode. + "hybrid" | // operate in hybrid globalization mode with small ICU files, using native platform functions + "auto" // (default): if "icu" behavior assets are present, use ICU, otherwise invariant. + +export type DotnetModuleConfig = { + disableDotnet6Compatibility?: boolean, + + config?: MonoConfig, + configSrc?: string, + onConfigLoaded?: (config: MonoConfig) => void | Promise; + onDotnetReady?: () => void | Promise; + onDownloadResourceProgress?: (resourcesLoaded: number, totalResources: number) => void; + getApplicationEnvironment?: (bootConfigResponse: Response) => string | null; + + imports?: any; + exports?: string[]; + downloadResource?: (request: ResourceRequest) => LoadingResource | undefined +} & Partial + +export type APIType = { + runMain: (mainAssemblyName: string, args: string[]) => Promise, + runMainAndExit: (mainAssemblyName: string, args: string[]) => Promise, + setEnvironmentVariable: (name: string, value: string) => void, + getAssemblyExports(assemblyName: string): Promise, + setModuleImports(moduleName: string, moduleImports: any): void, + getConfig: () => MonoConfig, + setHeapB32: (offset: NativePointer, value: number | boolean) => void, + setHeapU8: (offset: NativePointer, value: number) => void, + setHeapU16: (offset: NativePointer, value: number) => void, + setHeapU32: (offset: NativePointer, value: NativePointer | number) => void, + setHeapI8: (offset: NativePointer, value: number) => void, + setHeapI16: (offset: NativePointer, value: number) => void, + setHeapI32: (offset: NativePointer, value: number) => void, + setHeapI52: (offset: NativePointer, value: number) => void, + setHeapU52: (offset: NativePointer, value: number) => void, + setHeapI64Big: (offset: NativePointer, value: bigint) => void, + setHeapF32: (offset: NativePointer, value: number) => void, + setHeapF64: (offset: NativePointer, value: number) => void, + getHeapB32: (offset: NativePointer) => boolean, + getHeapU8: (offset: NativePointer) => number, + getHeapU16: (offset: NativePointer) => number, + getHeapU32: (offset: NativePointer) => number, + getHeapI8: (offset: NativePointer) => number, + getHeapI16: (offset: NativePointer) => number, + getHeapI32: (offset: NativePointer) => number, + getHeapI52: (offset: NativePointer) => number, + getHeapU52: (offset: NativePointer) => number, + getHeapI64Big: (offset: NativePointer) => bigint, + getHeapF32: (offset: NativePointer) => number, + getHeapF64: (offset: NativePointer) => number, +} + +export type RuntimeAPI = { + /** + * @deprecated Please use API object instead. See also MONOType in dotnet-legacy.d.ts + */ + MONO: any, + /** + * @deprecated Please use API object instead. See also BINDINGType in dotnet-legacy.d.ts + */ + BINDING: any, + INTERNAL: any, + Module: EmscriptenModule, + runtimeId: number, + runtimeBuildInfo: { + productVersion: string, + gitHash: string, + buildConfiguration: string, + } +} & APIType + +export type ModuleAPI = { + dotnet: DotnetHostBuilder; + exit: (code: number, reason?: any) => void +} + +export type CreateDotnetRuntimeType = (moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)) => Promise; + +export interface WebAssemblyStartOptions { + /** + * Overrides the built-in boot resource loading mechanism so that boot resources can be fetched + * from a custom source, such as an external CDN. + * @param type The type of the resource to be loaded. + * @param name The name of the resource to be loaded. + * @param defaultUri The URI from which the framework would fetch the resource by default. The URI may be relative or absolute. + * @param integrity The integrity string representing the expected content in the response. + * @returns A URI string or a Response promise to override the loading process, or null/undefined to allow the default loading behavior. + */ + loadBootResource(type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string): string | Promise | null | undefined; + + /** + * Override built-in environment setting on start. + */ + environment?: string; + + /** + * Gets the application culture. This is a name specified in the BCP 47 format. See https://tools.ietf.org/html/bcp47 + */ + applicationCulture?: string; +} + +// This type doesn't have to align with anything in BootConfig. +// Instead, this represents the public API through which certain aspects +// of boot resource loading can be customized. +export type WebAssemblyBootResourceType = "assembly" | "pdb" | "dotnetjs" | "dotnetwasm" | "globalization" | "manifest" | "configuration"; \ No newline at end of file diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index 98c14d0fd33af5..3f1c811dceccb0 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -1,9 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { WebAssemblyStartOptions } from "./blazor/WebAssemblyStartOptions"; -import { DotnetHostBuilder } from "./run-outer"; -import { CharPtr, EmscriptenModule, ManagedPointer, NativePointer, VoidPtr, Int32Ptr, EmscriptenModuleInternal } from "./types/emscripten"; +import { AssetEntry, DotnetModuleConfig, LoadingResource, MonoConfig, RuntimeAPI, WebAssemblyStartOptions } from "./types-api"; +import { CharPtr, EmscriptenModule, ManagedPointer, NativePointer, VoidPtr, Int32Ptr } from "./types/emscripten"; export type GCHandle = { __brand: "GCHandle" @@ -67,74 +66,6 @@ export function coerceNull(ptr: T | nu return ptr as T; } -export type MonoConfig = { - /** - * The subfolder containing managed assemblies and pdbs. This is relative to dotnet.js script. - */ - assemblyRootFolder?: string, - /** - * A list of assets to load along with the runtime. - */ - assets?: AssetEntry[], - /** - * Additional search locations for assets. - */ - remoteSources?: string[], // Sources will be checked in sequential order until the asset is found. The string "./" indicates to load from the application directory (as with the files in assembly_list), and a fully-qualified URL like "https://example.com/" indicates that asset loads can be attempted from a remote server. Sources must end with a "/". - /** - * It will not fail the startup is .pdb files can't be downloaded - */ - ignorePdbLoadErrors?: boolean, - /** - * We are throttling parallel downloads in order to avoid net::ERR_INSUFFICIENT_RESOURCES on chrome. The default value is 16. - */ - maxParallelDownloads?: number, - /** - * We are making up to 2 more delayed attempts to download same asset. Default true. - */ - enableDownloadRetry?: boolean, - /** - * Name of the assembly with main entrypoint - */ - mainAssemblyName?: string, - /** - * Configures the runtime's globalization mode - */ - globalizationMode?: GlobalizationMode, - /** - * debugLevel > 0 enables debugging and sets the debug log level to debugLevel - * debugLevel == 0 disables debugging and enables interpreter optimizations - * debugLevel < 0 enabled debugging and disables debug logging. - */ - debugLevel?: number, - /** - * Enables diagnostic log messages during startup - */ - diagnosticTracing?: boolean - /** - * Dictionary-style Object containing environment variables - */ - environmentVariables?: { - [i: string]: string; - }, - /** - * initial number of workers to add to the emscripten pthread pool - */ - pthreadPoolSize?: number, - /** - * If true, the snapshot of runtime's memory will be stored in the browser and used for faster startup next time. Default is false. - */ - startupMemoryCache?: boolean, - /** - * hash of assets - */ - assetsHash?: string, - - /** - * application environment - */ - applicationEnvironment?: string -}; - export type MonoConfigInternal = MonoConfig & { runtimeOptions?: string[], // array of runtime options as strings aotProfilerOptions?: AOTProfilerOptions, // dictionary-style Object. If omitted, aot profiler will not be initialized. @@ -156,49 +87,6 @@ export type RunArguments = { diagnosticTracing?: boolean, } -export interface ResourceRequest { - name: string, // the name of the asset, including extension. - behavior: AssetBehaviours, // determines how the asset will be handled once loaded - resolvedUrl?: string; - hash?: string; -} - -export interface LoadingResource { - name: string; - url: string; - response: Promise; -} - -// Types of assets that can be in the mono-config.js/mono-config.json file (taken from /src/tasks/WasmAppBuilder/WasmAppBuilder.cs) -export interface AssetEntry extends ResourceRequest { - /** - * If specified, overrides the path of the asset in the virtual filesystem and similar data structures once downloaded. - */ - virtualPath?: string, - /** - * Culture code - */ - culture?: string, - /** - * If true, an attempt will be made to load the asset from each location in MonoConfig.remoteSources. - */ - loadRemote?: boolean, // - /** - * If true, the runtime startup would not fail if the asset download was not successful. - */ - isOptional?: boolean - /** - * If provided, runtime doesn't have to fetch the data. - * Runtime would set the buffer to null after instantiation to free the memory. - */ - buffer?: ArrayBuffer - /** - * It's metadata + fetch-like Promise - * If provided, the runtime doesn't have to initiate the download. It would just await the response. - */ - pendingDownload?: LoadingResource -} - export interface AssetEntryInternal extends AssetEntry { // this is almost the same as pendingDownload, but it could have multiple values in time, because of re-try download logic pendingDownloadInternal?: LoadingResource @@ -247,15 +135,9 @@ export type RuntimeHelpers = { preferredIcuAsset: string | null, invariantMode: boolean, updateMemoryViews: () => void + runtimeReady: boolean, } -export type GlobalizationMode = - "icu" | // load ICU globalization data from any runtime assets with behavior "icu". - "invariant" | // operate in invariant globalization mode. - "hybrid" | // operate in hybrid globalization mode with small ICU files, using native platform functions - "auto" // (default): if "icu" behavior assets are present, use ICU, otherwise invariant. - - export type AOTProfilerOptions = { writeAt?: string, // should be in the format ::, default: 'WebAssembly.Runtime::StopProfile' sendTo?: string // should be in the format ::, default: 'WebAssembly.Runtime::DumpAotProfileData' (DumpAotProfileData stores the data into INTERNAL.aotProfileData.) @@ -268,20 +150,6 @@ export type BrowserProfilerOptions = { export type DotnetModule = EmscriptenModule & DotnetModuleConfig; export type DotnetModuleInternal = EmscriptenModule & DotnetModuleConfig & EmscriptenModuleInternal; -export type DotnetModuleConfig = { - disableDotnet6Compatibility?: boolean, - - config?: MonoConfig, - configSrc?: string, - onConfigLoaded?: (config: MonoConfig) => void | Promise; - onDotnetReady?: () => void | Promise; - onDownloadResourceProgress?: (resourcesLoaded: number, totalResources: number) => void; - getApplicationEnvironment?: (bootConfigResponse: Response) => string | null; - - imports?: any; - exports?: string[]; - downloadResource?: (request: ResourceRequest) => LoadingResource | undefined -} & Partial export type DotnetModuleConfigImports = { require?: (name: string) => any; @@ -364,34 +232,32 @@ export function is_nullish(value: T | null | undefined): value is null | unde return (value === undefined) || (value === null); } -export type EarlyImports = { - isGlobal: boolean, - isNode: boolean, +export type EmscriptenInternals = { isWorker: boolean, isShell: boolean, - isWeb: boolean, isPThread: boolean, disableLegacyJsInterop: boolean, quit_: Function, ExitStatus: ExitStatusError, requirePromise: Promise }; -export type EarlyExports = { +export type GlobalObjects = { mono: any, binding: any, internal: any, - module: any, - marshaled_imports: any, + module: DotnetModuleInternal, + helpers: RuntimeHelpers, + api: RuntimeAPI, }; -export type EarlyReplacements = { +export type EmscriptenReplacements = { fetch: any, require: any, requirePromise: Promise, - noExitRuntime: boolean, updateMemoryViews: Function, pthreadReplacements: PThreadReplacements | undefined | null scriptDirectory: string; scriptUrl: string + noExitRuntime?: boolean; } export interface ExitStatusError { new(status: number): any; @@ -531,64 +397,16 @@ export interface WasmRootBuffer { toString(): string; } -export type APIType = { - runMain: (mainAssemblyName: string, args: string[]) => Promise, - runMainAndExit: (mainAssemblyName: string, args: string[]) => Promise, - setEnvironmentVariable: (name: string, value: string) => void, - getAssemblyExports(assemblyName: string): Promise, - setModuleImports(moduleName: string, moduleImports: any): void, - getConfig: () => MonoConfig, - setHeapB32: (offset: NativePointer, value: number | boolean) => void, - setHeapU8: (offset: NativePointer, value: number) => void, - setHeapU16: (offset: NativePointer, value: number) => void, - setHeapU32: (offset: NativePointer, value: NativePointer | number) => void, - setHeapI8: (offset: NativePointer, value: number) => void, - setHeapI16: (offset: NativePointer, value: number) => void, - setHeapI32: (offset: NativePointer, value: number) => void, - setHeapI52: (offset: NativePointer, value: number) => void, - setHeapU52: (offset: NativePointer, value: number) => void, - setHeapI64Big: (offset: NativePointer, value: bigint) => void, - setHeapF32: (offset: NativePointer, value: number) => void, - setHeapF64: (offset: NativePointer, value: number) => void, - getHeapB32: (offset: NativePointer) => boolean, - getHeapU8: (offset: NativePointer) => number, - getHeapU16: (offset: NativePointer) => number, - getHeapU32: (offset: NativePointer) => number, - getHeapI8: (offset: NativePointer) => number, - getHeapI16: (offset: NativePointer) => number, - getHeapI32: (offset: NativePointer) => number, - getHeapI52: (offset: NativePointer) => number, - getHeapU52: (offset: NativePointer) => number, - getHeapI64Big: (offset: NativePointer) => bigint, - getHeapF32: (offset: NativePointer) => number, - getHeapF64: (offset: NativePointer) => number, -} - -// this represents visibility in the javascript -// like https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web.JS/src/Platform/Mono/MonoTypes.ts -export type RuntimeAPI = { - /** - * @deprecated Please use API object instead. See also MONOType in dotnet-legacy.d.ts - */ - MONO: any, - /** - * @deprecated Please use API object instead. See also BINDINGType in dotnet-legacy.d.ts - */ - BINDING: any, - INTERNAL: any, - Module: EmscriptenModule, - runtimeId: number, - runtimeBuildInfo: { - productVersion: string, - gitHash: string, - buildConfiguration: string, - } -} & APIType - -export type ModuleAPI = { - dotnet: DotnetHostBuilder; - exit: (code: number, reason?: any) => void +export declare interface EmscriptenModuleInternal { + __locateFile?: (path: string, prefix?: string) => string; + locateFile?: (path: string, prefix?: string) => string; + mainScriptUrlOrBlob?: string; + wasmModule: WebAssembly.Instance | null; + ready: Promise; + asm: { memory?: WebAssembly.Memory }; + wasmMemory?: WebAssembly.Memory; + getWasmTableEntry(index: number): any; + removeRunDependency(id: string): void; + addRunDependency(id: string): void; + onConfigLoaded?: (config: MonoConfig, api: RuntimeAPI) => void | Promise; } - -export declare function createDotnetRuntime(moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)): Promise; -export type CreateDotnetRuntimeType = typeof createDotnetRuntime; diff --git a/src/mono/wasm/runtime/types/consts.d.ts b/src/mono/wasm/runtime/types/consts.d.ts index f286d28da3b045..11a7e5439e3110 100644 --- a/src/mono/wasm/runtime/types/consts.d.ts +++ b/src/mono/wasm/runtime/types/consts.d.ts @@ -18,6 +18,4 @@ declare module "consts:monoDiagnosticsMock" { export default constant; } -// these constants from dotnet.es6.extpost.js duplicate detection inside emscripten internals, but happen earlier -declare const ENVIRONMENT_IS_NODE: boolean; -declare const ENVIRONMENT_IS_WEB: boolean; \ No newline at end of file +declare function createEmscripten(module: any): Promise; diff --git a/src/mono/wasm/runtime/types/emscripten.ts b/src/mono/wasm/runtime/types/emscripten.ts index 7c508458a3e1e9..bcefbbbb40b9b6 100644 --- a/src/mono/wasm/runtime/types/emscripten.ts +++ b/src/mono/wasm/runtime/types/emscripten.ts @@ -64,20 +64,6 @@ export declare interface EmscriptenModule { onAbort?: { (error: any): void }; } -export declare interface EmscriptenModuleInternal { - __locateFile?: (path: string, prefix?: string) => string; - locateFile?: (path: string, prefix?: string) => string; - mainScriptUrlOrBlob?: string; - wasmModule: WebAssembly.Instance | null; - ready: Promise; - asm: { memory?: WebAssembly.Memory }; - wasmMemory?: WebAssembly.Memory; - getWasmTableEntry(index: number): any; - removeRunDependency(id: string): void; - addRunDependency(id: string): void; -} - - export type InstantiateWasmSuccessCallback = (instance: WebAssembly.Instance, module: WebAssembly.Module | undefined) => void; export type InstantiateWasmCallBack = (imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback) => any; diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index ea9dc2a8922879..9b2e1042cb4c00 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -5,7 +5,7 @@ import { prevent_timer_throttling } from "./scheduling"; import { Queue } from "./queue"; import { PromiseController, createPromiseController } from "./promise-controller"; import { mono_assert } from "./types"; -import { Module } from "./imports"; +import { Module } from "./globals"; import { setI32 } from "./memory"; import { VoidPtr } from "./types/emscripten"; diff --git a/src/mono/wasm/test-main.js b/src/mono/wasm/test-main.js index 3d835c0bb61407..63dc5d143f7aff 100644 --- a/src/mono/wasm/test-main.js +++ b/src/mono/wasm/test-main.js @@ -4,13 +4,13 @@ // // Run runtime tests under a JS shell or a browser // -"use strict"; +import { dotnet, exit } from './dotnet.js'; /***************************************************************************** * Please don't use this as template for startup code. * There are simpler and better samples like src\mono\sample\wasm\browser\main.js - * This one is not ES6 nor CJS, doesn't use top level await and has edge case polyfills. + * It has edge case polyfills. * It handles strange things which happen with XHarness. ****************************************************************************/ @@ -25,12 +25,12 @@ if (is_node && process.versions.node.split(".")[0] < 14) { if (is_node) { // the emscripten 3.1.34 stopped handling these when MODULARIZE is enabled - process.on('uncaughtException', function(ex) { + process.on('uncaughtException', function (ex) { // ignore UnhandledPromiseRejection exceptions with exit status if (ex !== 'unwind' && (ex.name !== "UnhandledPromiseRejection" || !ex.message.includes('"#"'))) { - throw ex; + throw ex; } - }); + }); } if (!is_node && !is_browser && typeof globalThis.crypto === 'undefined') { @@ -204,10 +204,6 @@ let mono_exit = (code, reason) => { console.log(`test-main failed early ${code} ${reason}`); }; -async function loadDotnet(file) { - return await import(file); -} - const App = { /** Runs a particular test in legacy interop tests * @type {(method_name: string, args: any[]=, signature: any=) => return number} @@ -255,7 +251,7 @@ const App = { }; globalThis.App = App; // Necessary as System.Runtime.InteropServices.JavaScript.Tests.MarshalTests (among others) call the App.call_test_method directly -function configureRuntime(dotnet, runArgs, INTERNAL) { +function configureRuntime(dotnet, runArgs) { dotnet .withVirtualWorkingDirectory(runArgs.workingDirectory) .withEnvironmentVariables(runArgs.environmentVariables) @@ -272,7 +268,7 @@ function configureRuntime(dotnet, runArgs, INTERNAL) { const modulesToLoad = runArgs.environmentVariables["NPM_MODULES"]; if (modulesToLoad) { dotnet.withModuleConfig({ - onConfigLoaded: (config) => { + onConfigLoaded: (config, { INTERNAL }) => { loadNodeModules(config, INTERNAL.require, modulesToLoad) } }) @@ -300,9 +296,8 @@ async function dry_run(runArgs) { try { console.log("Silently starting separate runtime instance as another ES6 module to populate caches..."); // this separate instance of the ES6 module, in which we just populate the caches - const { dotnet, exit, INTERNAL } = await loadDotnet('./dotnet.js?dry_run=true'); - mono_exit = exit; - configureRuntime(dotnet, runArgs, INTERNAL); + const { dotnet } = await import('./dotnet.js?dry_run=true'); + configureRuntime(dotnet, runArgs); // silent minimal startup await dotnet.withConfig({ forwardConsoleLogsToWS: false, @@ -314,12 +309,14 @@ async function dry_run(runArgs) { // If there was previously a matching snapshot, it will be used. exitAfterSnapshot: true }).create(); + console.log("Separate runtime instance finished loading."); } catch (err) { - if (err && err.status !== 0) { - return false; + if (err && err.status === 0) { + return true; } + console.log("Separate runtime instance failed loading.", err); + return false; } - console.log("Separate runtime instance finished loading."); return true; } @@ -338,7 +335,6 @@ async function run() { // this is subsequent run with the actual tests. It will use whatever was cached in the previous run. // This way, we are testing that the cached version works. - const { dotnet, exit, INTERNAL } = await loadDotnet('./dotnet.js'); mono_exit = exit; if (runArgs.applicationArguments.length == 0) { @@ -346,7 +342,7 @@ async function run() { return; } - configureRuntime(dotnet, runArgs, INTERNAL); + configureRuntime(dotnet, runArgs); App.runtime = await dotnet.create(); App.runArgs = runArgs @@ -387,6 +383,7 @@ async function run() { const main_assembly_name = runArgs.applicationArguments[1]; const app_args = runArgs.applicationArguments.slice(2); const result = await App.runtime.runMain(main_assembly_name, app_args); + console.log(`test-main.js exiting ${app_args.length > 1 ? main_assembly_name + " " + app_args[0] : main_assembly_name} with result ${result}`); mono_exit(result); } catch (error) { if (error.name != "ExitStatus") { @@ -401,4 +398,4 @@ async function run() { } } -run(); +await run(); diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 971ee55a3baa72..cb76cb0d19e025 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -427,7 +427,6 @@ diff --git a/src/native/corehost/apphost/static/CMakeLists.txt b/src/native/corehost/apphost/static/CMakeLists.txt index cb77f959463cf5..db5d751a3fc6fe 100644 --- a/src/native/corehost/apphost/static/CMakeLists.txt +++ b/src/native/corehost/apphost/static/CMakeLists.txt @@ -227,6 +227,10 @@ if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD set(END_WHOLE_ARCHIVE -Wl,--no-whole-archive) endif(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD OR CLR_CMAKE_TARGET_SUNOS) +if(CLR_CMAKE_TARGET_LINUX AND CLR_CMAKE_TARGET_ARCH_RISCV64) + add_linker_flag(-Wl,-z,notext) +endif() + if(CLR_CMAKE_TARGET_APPLE) # These options are used to force every object to be included even if it's unused. set(START_WHOLE_ARCHIVE -force_load) diff --git a/src/native/corehost/corehost.proj b/src/native/corehost/corehost.proj index d489571ed9ec51..18ac25f41841d2 100644 --- a/src/native/corehost/corehost.proj +++ b/src/native/corehost/corehost.proj @@ -8,7 +8,7 @@ true GetProductVersions;GenerateNativeVersionFile $(BuildCoreHostDependsOn);InitializeSourceControlInformationFromSourceControlManager - $(ArtifactsObjDir)$(OutputRid).$(Configuration)\ + $(ArtifactsObjDir)$(OutputRID).$(Configuration)\ @@ -82,7 +82,7 @@ $(BuildArgs) -ninja $(BuildArgs) -runtimeflavor $(RuntimeFlavor) $(BuildArgs) /p:OfficialBuildId="$(OfficialBuildId)" - $(BuildArgs) -outputrid $(OutputRid) + $(BuildArgs) -outputrid $(OutputRID) <_MergedWrapperMarker Include="$(TestBinDir)**\*.MergedTestAssembly" Exclude="$(TestBinDir)**\supportFiles\*.MergedTestAssembly" /> + + <_MergedWrapperMarker Update="@(_MergedWrapperMarker)"> + $([System.IO.Path]::ChangeExtension('%(Identity)', '.$(TestScriptExtension)')) + + + + <_MergedWrapperMarker Remove="@(_MergedWrapperMarker)" Condition="!Exists('%(TestExecutionScriptPath)')" /> + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/Common/ilasm/ilasm.ilproj b/src/tests/Common/ilasm/ilasm.ilproj index c73f6efe31f8e3..29cd4d0791990f 100644 --- a/src/tests/Common/ilasm/ilasm.ilproj +++ b/src/tests/Common/ilasm/ilasm.ilproj @@ -4,6 +4,6 @@ needed by the IL SDK. --> - $(OutputRid) + $(OutputRID) diff --git a/src/tests/Common/publishdependency.targets b/src/tests/Common/publishdependency.targets index 30b541ecea7784..4a16052008d7d2 100644 --- a/src/tests/Common/publishdependency.targets +++ b/src/tests/Common/publishdependency.targets @@ -28,7 +28,7 @@ + Properties="Language=C#;RuntimeIdentifier=$(OutputRID);CORE_ROOT=$(CORE_ROOT)" /> diff --git a/src/tests/Common/test_dependencies/test_dependencies.csproj b/src/tests/Common/test_dependencies/test_dependencies.csproj index 38417a9e8e31ae..454e4003f0c20f 100644 --- a/src/tests/Common/test_dependencies/test_dependencies.csproj +++ b/src/tests/Common/test_dependencies/test_dependencies.csproj @@ -5,7 +5,7 @@ $(NetCoreAppToolCurrent) true true - win-arm;win-arm64;win-x64;win-x86;$(OutputRid) + win-arm;win-arm64;win-x64;win-x86;$(OutputRID) true diff --git a/src/tests/Common/test_dependencies_fs/test_dependencies.fsproj b/src/tests/Common/test_dependencies_fs/test_dependencies.fsproj index 196db8eabec630..b7e9dde969981d 100644 --- a/src/tests/Common/test_dependencies_fs/test_dependencies.fsproj +++ b/src/tests/Common/test_dependencies_fs/test_dependencies.fsproj @@ -5,7 +5,7 @@ $(NetCoreAppToolCurrent) true true - win-arm;win-arm64;win-x64;win-x86;$(OutputRid) + win-arm;win-arm64;win-x64;win-x86;$(OutputRID) true diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index 104f53ebda3a8a..6f6fc552ba222c 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -531,7 +531,7 @@ $(CoreCLRAotSdkDir) $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir) $(MicrosoftNetCoreAppRuntimePackNativeDir) - $(OutputRid) + $(OutputRID) lld $(ROOTFS_DIR) diff --git a/src/tests/Interop/COM/ComWrappers/API/Program.cs b/src/tests/Interop/COM/ComWrappers/API/Program.cs index 3319f8e2621603..1a2b71ba2f881a 100644 --- a/src/tests/Interop/COM/ComWrappers/API/Program.cs +++ b/src/tests/Interop/COM/ComWrappers/API/Program.cs @@ -11,6 +11,7 @@ namespace ComWrappersTests using System.Runtime.InteropServices; using ComWrappersTests.Common; + using TestLibrary; using Xunit; class Program @@ -122,6 +123,7 @@ static void ForceGC() } } + [MethodImpl(MethodImplOptions.NoInlining)] static void ValidateComInterfaceCreation() { Console.WriteLine($"Running {nameof(ValidateComInterfaceCreation)}..."); @@ -155,6 +157,7 @@ static void ValidateComInterfaceCreation() Assert.Equal(0, count); } + [MethodImpl(MethodImplOptions.NoInlining)] static void ValidateComInterfaceCreationRoundTrip() { Console.WriteLine($"Running {nameof(ValidateComInterfaceCreationRoundTrip)}..."); @@ -175,6 +178,79 @@ static void ValidateComInterfaceCreationRoundTrip() Assert.Equal(0, count); } + static void ValidateComObjectExtendsManagedLifetime() + { + Console.WriteLine($"Running {nameof(ValidateComObjectExtendsManagedLifetime)}..."); + + // Cleanup any existing objects + ForceGC(); + Assert.Equal(0, Test.InstanceCount); + + // Allocate a wrapper for the object + IntPtr comWrapper = CreateObjectAndGetComInterface(); + Assert.NotEqual(IntPtr.Zero, comWrapper); + + // GC should not free object + Assert.Equal(1, Test.InstanceCount); + ForceGC(); + Assert.Equal(1, Test.InstanceCount); + + // Release the wrapper + int count = Marshal.Release(comWrapper); + Assert.Equal(0, count); + + // Check that the object is no longer rooted. + ForceGC(); + Assert.Equal(0, Test.InstanceCount); + + [MethodImpl(MethodImplOptions.NoInlining)] + static IntPtr CreateObjectAndGetComInterface() + { + var wrappers = new TestComWrappers(); + return wrappers.GetOrCreateComInterfaceForObject(new Test(), CreateComInterfaceFlags.None); + } + } + + // Just because one use of a COM interface returned from GetOrCreateComInterfaceForObject + // hits zero ref count does not mean future calls to GetOrCreateComInterfaceForObject + // should return an unusable object. + [MethodImpl(MethodImplOptions.NoInlining)] + static void ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree() + { + Console.WriteLine($"Running {nameof(ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree)}..."); + + var wrappers = new TestComWrappers(); + var testInstance = new Test(); + + CallSetValue(wrappers, testInstance, 1); + CallSetValue(wrappers, testInstance, 2); + + GC.KeepAlive(testInstance); + + unsafe static void CallSetValue(TestComWrappers wrappers, Test testInstance, int value) + { + IntPtr nativeInstance = wrappers.GetOrCreateComInterfaceForObject(testInstance, CreateComInterfaceFlags.None); + Assert.NotEqual(IntPtr.Zero, nativeInstance); + + var iid = typeof(ITest).GUID; + IntPtr itestPtr; + Assert.Equal(0, Marshal.QueryInterface(nativeInstance, ref iid, out itestPtr)); + + var inst = Marshal.PtrToStructure(itestPtr); + var vtbl = Marshal.PtrToStructure(inst.Vtbl); + var setValue = (delegate* unmanaged)vtbl.SetValue; + + Assert.Equal(0, setValue(itestPtr, value)); + Assert.Equal(value, testInstance.GetValue()); + + // release for QueryInterface + Assert.Equal(1, Marshal.Release(itestPtr)); + // release for GetOrCreateComInterfaceForObject + Assert.Equal(0, Marshal.Release(itestPtr)); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] static void ValidateFallbackQueryInterface() { Console.WriteLine($"Running {nameof(ValidateFallbackQueryInterface)}..."); @@ -228,6 +304,42 @@ static void ValidateCreateObjectCachingScenario() Assert.NotEqual(trackerObj1, trackerObj3); } + // Verify that if a GC nulls the contents of a weak GCHandle but has not yet + // run finializers to remove that GCHandle from the cache, the state of the system is valid. + static void ValidateCreateObjectWeakHandleCacheCleanUp() + { + Console.WriteLine($"Running {nameof(ValidateCreateObjectWeakHandleCacheCleanUp)}..."); + + var cw = new TestComWrappers(); + + // Get an object from a tracker runtime. + IntPtr trackerObjRaw = MockReferenceTrackerRuntime.CreateTrackerObject(); + + // Create the first native object wrapper and run the GC. + CreateObject(cw, trackerObjRaw); + + // Only attempt to run the GC, don't wait for the finalizer. We do this + // because of the multiple phase clean-up for ComWrappers caches. + // See weak GC handles in the NativeAOT scenario. + GC.Collect(); + + // Try to create another wrapper for the same object. The above GC + // may have collected parts of the ComWrapper cache, but not fully + // cleared the contents of the cache. + CreateObject(cw, trackerObjRaw); + ForceGC(); + + Marshal.Release(trackerObjRaw); + + [MethodImpl(MethodImplOptions.NoInlining)] + static void CreateObject(ComWrappers cw, IntPtr trackerObj) + { + var obj = (ITrackerObjectWrapper)cw.GetOrCreateObjectForComInstance(trackerObj, CreateObjectFlags.None); + Assert.NotNull(obj); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] static void ValidateMappingAPIs() { Console.WriteLine($"Running {nameof(ValidateMappingAPIs)}..."); @@ -281,6 +393,7 @@ static void ValidateMappingAPIs() Marshal.Release(unmanagedObjIUnknown); } + [MethodImpl(MethodImplOptions.NoInlining)] static void ValidateWrappersInstanceIsolation() { Console.WriteLine($"Running {nameof(ValidateWrappersInstanceIsolation)}..."); @@ -702,8 +815,11 @@ static int Main() { ValidateComInterfaceCreation(); ValidateComInterfaceCreationRoundTrip(); + ValidateComObjectExtendsManagedLifetime(); + ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree(); ValidateFallbackQueryInterface(); ValidateCreateObjectCachingScenario(); + ValidateCreateObjectWeakHandleCacheCleanUp(); ValidateMappingAPIs(); ValidateWrappersInstanceIsolation(); ValidatePrecreatedExternalWrapper(); @@ -713,8 +829,13 @@ static int Main() ValidateBadComWrapperImpl(); ValidateRuntimeTrackerScenario(); ValidateQueryInterfaceAfterManagedObjectCollected(); - ValidateAggregationWithComObject(); - ValidateAggregationWithReferenceTrackerObject(); + + // Tracked by https://github.com/dotnet/runtime/issues/74620 + if (!TestLibrary.Utilities.IsNativeAot) + { + ValidateAggregationWithComObject(); + ValidateAggregationWithReferenceTrackerObject(); + } // Ensure all objects have been cleaned up. ForceGC(); diff --git a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp index 37f11314f4cd7b..2cb73d9312e416 100644 --- a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp +++ b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/src/tests/JIT/Directed/physicalpromotion/mixedpromotion.cs b/src/tests/JIT/Directed/physicalpromotion/mixedpromotion.cs new file mode 100644 index 00000000000000..a61402a3f097ad --- /dev/null +++ b/src/tests/JIT/Directed/physicalpromotion/mixedpromotion.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +using System.Runtime.CompilerServices; +using System; +using Xunit; +using System.Runtime.InteropServices; + +public class PhysicalPromotion +{ + private static S s_static = new S { A = 0x10101010, B = 0x20202020 }; + + [Fact] + public static unsafe void FromPhysicalToOld() + { + SWithInner src; + src.S = s_static; + src.S.A = src.S.B + 3; + src.S.B = 0x20202020; + + S dst; + dst = src.S; + dst.A = dst.B + 3; + dst.B = 0x10101010; + Consume(dst); + Assert.Equal(0x20202023U, dst.A); + Assert.Equal(0x10101010U, dst.B); + } + + [Fact] + public static unsafe void FromOldToPhysical() + { + S src; + src = s_static; + src.A = src.B + 3; + src.B = 0x20202020; + + SWithInner dst; + dst.Field = 0; + dst.S = src; + dst.S.A = dst.S.B + 3; + dst.S.B = 0x10101010; + Consume(dst); + Assert.Equal(0x20202023U, dst.S.A); + Assert.Equal(0x10101010U, dst.S.B); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(T val) + { + } + + private struct S + { + public uint A; + public uint B; + } + + private struct SWithInner + { + public int Field; + public S S; + } +} diff --git a/src/tests/JIT/Directed/physicalpromotion/mixedpromotion.csproj b/src/tests/JIT/Directed/physicalpromotion/mixedpromotion.csproj new file mode 100644 index 00000000000000..736bd239f0cd81 --- /dev/null +++ b/src/tests/JIT/Directed/physicalpromotion/mixedpromotion.csproj @@ -0,0 +1,10 @@ + + + True + True + + + + + + diff --git a/src/tests/JIT/Directed/physicalpromotion/physicalpromotion.cs b/src/tests/JIT/Directed/physicalpromotion/physicalpromotion.cs new file mode 100644 index 00000000000000..6d06cedbbcc0c4 --- /dev/null +++ b/src/tests/JIT/Directed/physicalpromotion/physicalpromotion.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +using System.Runtime.CompilerServices; +using System; +using Xunit; +using System.Runtime.InteropServices; + +public class PhysicalPromotion +{ + [Fact] + public static unsafe void PartialOverlap1() + { + S s = default; + s.A = 0x10101010; + s.B = 0x20202020; + + Unsafe.InitBlockUnaligned(ref Unsafe.As(ref s.C), 0xcc, 4); + Assert.Equal(0xcccc1010U, s.A); + Assert.Equal(0x2020ccccU, s.B); + } + + private static S s_static = new S { A = 0x10101010, B = 0x20202020 }; + [Fact] + public static unsafe void CopyFromLocalVar() + { + S src = s_static; + S dst; + dst = src; + dst.A = dst.B + 3; + dst.B = 0x20202020; + Consume(dst); + Assert.Equal(0x20202023U, dst.A); + Assert.Equal(0x20202020U, dst.B); + } + + [Fact] + public static unsafe void CopyFromLocalField() + { + SWithInner src; + src.S = s_static; + S dst; + dst = src.S; + dst.A = dst.B + 3; + dst.B = 0x20202020; + Consume(dst); + Assert.Equal(0x20202023U, dst.A); + Assert.Equal(0x20202020U, dst.B); + } + + [Fact] + public static unsafe void CopyFromBlk() + { + S dst; + dst = s_static; + dst.A = dst.B + 3; + dst.B = 0x20202020; + Consume(dst); + Assert.Equal(0x20202023U, dst.A); + Assert.Equal(0x20202020U, dst.B); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(T val) + { + } + + [StructLayout(LayoutKind.Explicit)] + private struct S + { + [FieldOffset(0)] + public uint A; + [FieldOffset(4)] + public uint B; + [FieldOffset(2)] + public uint C; + } + + private struct SWithInner + { + public int Field; + public S S; + } +} diff --git a/src/tests/JIT/Directed/physicalpromotion/physicalpromotion.csproj b/src/tests/JIT/Directed/physicalpromotion/physicalpromotion.csproj new file mode 100644 index 00000000000000..02c64d568536ae --- /dev/null +++ b/src/tests/JIT/Directed/physicalpromotion/physicalpromotion.csproj @@ -0,0 +1,10 @@ + + + True + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs b/src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs new file mode 100644 index 00000000000000..d6368207d0b524 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs @@ -0,0 +1,186 @@ +// 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.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; + +namespace JIT.HardwareIntrinsics.X86 +{ + + public static class Avx512Verify + { + public static bool ValidateFixup(double actual, double x, double y, long z) + { + // Tests expect true on error + double expected = Fixup(x, y, (int)(z)); + + if (BitConverter.DoubleToInt64Bits(actual) == BitConverter.DoubleToInt64Bits(expected)) + { + return false; + } + + // The real fixup returns specific NaNs, but we don't need to validate for this test + return !(double.IsNaN(actual) && double.IsNaN(expected)); + } + + public static bool ValidateFixup(float actual, float x, float y, int z) + { + // Tests expect true on error + float expected = Fixup(x, y, (int)(z)); + + if (BitConverter.SingleToInt32Bits(actual) == BitConverter.SingleToInt32Bits(expected)) + { + return false; + } + + // The real fixup returns specific NaNs, but we don't need to validate for this test + return !(float.IsNaN(actual) && float.IsNaN(expected)); + } + + public static float GetExponent(float x) + { + int biasedExponent = GetBiasedExponent(x); + return biasedExponent - 127; + } + + public static double GetExponent(double x) + { + long biasedExponent = GetBiasedExponent(x); + return biasedExponent - 1023; + } + + public static float GetMantissa(float x) + { + float trailingSignificand = GetTrailingSignificand(x); + return 1.0f + (trailingSignificand / (1 << 23)); + } + + public static double GetMantissa(double x) + { + double trailingSignificand = GetTrailingSignificand(x); + return 1.0 + (trailingSignificand / (1L << 52)); + } + + public static TFloat Reduce(TFloat x, int m) + where TFloat : IFloatingPointIeee754 + { + return x - TFloat.Round(TFloat.ScaleB(TFloat.One, m) * x) * TFloat.ScaleB(TFloat.One, -m); + } + + public static bool ValidateReciprocal14(TFloat actual, TFloat value) + where TFloat : IFloatingPointIeee754 + { + // Tests expect true on error + + TFloat expected = TFloat.One / value; + TFloat relativeError = RelativeError(expected, actual); + + return relativeError >= (TFloat.One / TFloat.CreateSaturating(16384)); // 2^-14 + } + + public static bool ValidateReciprocalSqrt14(TFloat actual, TFloat value) + where TFloat : IFloatingPointIeee754 + { + // Tests expect true on error + + TFloat expected = TFloat.One/ TFloat.Sqrt(value); + TFloat relativeError = RelativeError(expected, actual); + + return relativeError >= (TFloat.One / TFloat.CreateSaturating(16384)); // 2^-14 + } + + private static TFloat Fixup(TFloat x, TFloat y, int z) + where TFloat : IFloatingPointIeee754, IMinMaxValue + { + int tokenType = GetTokenType(y); + int tokenResponse = GetTokenResponse(tokenType, z); + + switch (tokenResponse) + { + case 0: return x; + case 1: return y; + case 2: return TFloat.NaN; + case 3: return TFloat.NaN; + case 4: return TFloat.NegativeInfinity; + case 5: return TFloat.PositiveInfinity; + case 6: return TFloat.CopySign(TFloat.PositiveInfinity, y); + case 7: return TFloat.NegativeZero; + case 8: return TFloat.Zero; + case 9: return -TFloat.One; + case 10: return TFloat.One; + case 11: return TFloat.CreateSaturating(0.5); + case 12: return TFloat.CreateSaturating(90); + case 13: return TFloat.Pi / TFloat.CreateSaturating(2); + case 14: return TFloat.MaxValue; + case 15: return TFloat.MinValue; + default: throw new Exception($"Unexpected tokenResponse ({tokenResponse}) for ({x}, {y}, {z})"); + } + } + + private static int GetBiasedExponent(float x) + { + int bits = BitConverter.SingleToInt32Bits(x); + return (bits >>> 23) & 0x00FF; + } + + private static long GetBiasedExponent(double x) + { + long bits = BitConverter.DoubleToInt64Bits(x); + return (bits >>> 52) & 0x07FF; + } + + private static int GetTokenResponse(int tokenType, int z) + { + return (z >> (4 * tokenType)) & 0xF; + } + + private static int GetTokenType(TFloat x) + where TFloat : IFloatingPointIeee754 + { + if (TFloat.IsNaN(x)) + { + return 0; + } + else if (TFloat.IsZero(x)) + { + return 2; + } + else if (x == TFloat.One) + { + return 3; + } + else if (TFloat.IsInfinity(x)) + { + return TFloat.IsNegative(x) ? 4 : 5; + } + else + { + return TFloat.IsNegative(x) ? 6 : 7; + } + } + + private static int GetTrailingSignificand(float x) + { + int bits = BitConverter.SingleToInt32Bits(x); + return bits & 0x007F_FFFF; + } + + private static long GetTrailingSignificand(double x) + { + long bits = BitConverter.DoubleToInt64Bits(x); + return bits & 0x000F_FFFF_FFFF_FFFF; + } + + private static TFloat RelativeError(TFloat expected, TFloat actual) + where TFloat : IFloatingPointIeee754 + { + TFloat absoluteError = TFloat.Abs(expected - actual); + return absoluteError / expected; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmTernOpTest.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmTernOpTest.template new file mode 100644 index 00000000000000..ef96f2b3b36cd2 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmTernOpTest.template @@ -0,0 +1,325 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + [Fact] + public static void {Method}{RetBaseType}{Imm}() + { + var test = new ImmTernaryOpTest__{Method}{RetBaseType}{Imm}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class ImmTernaryOpTest__{Method}{RetBaseType}{Imm} + { + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + public {Op3VectorType}<{Op3BaseType}> _fld3; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmTernaryOpTest__{Method}{RetBaseType}{Imm} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2, _fld3, {Imm}); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + private {Op3VectorType}<{Op3BaseType}> _fld3; + + private SimpleTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}> _dataTable; + + public ImmTernaryOpTest__{Method}{RetBaseType}{Imm}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + _dataTable = new SimpleTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}>(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = {Isa}.{Method}( + {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {LoadIsa}.LoadAligned{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof({Op3VectorType}<{Op3BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var op3 = Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr); + var result = {Isa}.{Method}(op1, op2, op3, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2, _fld3, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2, test._fld3, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op3VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, inArray3, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, inArray3, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] op1, {Op2BaseType}[] op2, {Op3BaseType}[] op3, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if ({ValidateFirstResult}) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ({ValidateRemainingResults}) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>, {Op3VectorType}<{Op3BaseType}>, {Imm}): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" op1: ({string.Join(", ", op1)})"); + TestLibrary.TestFramework.LogInformation($" op2: ({string.Join(", ", op2)})"); + TestLibrary.TestFramework.LogInformation($" op3: ({string.Join(", ", op3)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs new file mode 100644 index 00000000000000..363704b493eac5 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs @@ -0,0 +1,77 @@ +// 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.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public unsafe struct SimpleTernaryOpTest__DataTable : IDisposable + where TResult : struct + where TOp1 : struct + where TOp2 : struct + where TOp3 : struct + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] inArray3; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle inHandle3; + private GCHandle outHandle; + + private ulong alignment; + + public SimpleTernaryOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, TOp3[] inArray3, TResult[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if (((alignment != 64) && (alignment != 32) && (alignment != 16)) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.inArray3 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As(ref inArray3[0]), (uint)sizeOfinArray3); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + inHandle3.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Sse2/Sse2Verify.cs b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SseVerify.cs similarity index 98% rename from src/tests/JIT/HardwareIntrinsics/X86/Sse2/Sse2Verify.cs rename to src/tests/JIT/HardwareIntrinsics/X86/Shared/SseVerify.cs index 85b361c422aef0..09fcea6a89afdd 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Sse2/Sse2Verify.cs +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SseVerify.cs @@ -11,7 +11,7 @@ namespace JIT.HardwareIntrinsics.X86 { - public static class Sse2Verify + public static class SseVerify { public static bool AddSaturate(byte x, byte y, byte z) { diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/_BinaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/_BinaryOpTestTemplate.template index 6c50e7bc1e5b54..2335fdc58658fb 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/_BinaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/_BinaryOpTestTemplate.template @@ -68,59 +68,6 @@ namespace JIT.HardwareIntrinsics.X86 public sealed unsafe class {TemplateName}BinaryOpTest__{Method}{RetBaseType} { - private struct DataTable - { - private byte[] inArray1; - private byte[] inArray2; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle inHandle2; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {RetBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - if (((alignment != 64) && (alignment != 32) && (alignment != 16)) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException("Invalid value of alignment"); - } - - this.inArray1 = new byte[alignment * 2]; - this.inArray2 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); - } - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - private struct TestStruct { public {Op1VectorType}<{Op1BaseType}> _fld1; @@ -159,7 +106,7 @@ namespace JIT.HardwareIntrinsics.X86 private {Op1VectorType}<{Op1BaseType}> _fld1; private {Op2VectorType}<{Op2BaseType}> _fld2; - private DataTable _dataTable; + private SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable; public {TemplateName}BinaryOpTest__{Method}{RetBaseType}() { @@ -172,7 +119,7 @@ namespace JIT.HardwareIntrinsics.X86 for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } - _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); + _dataTable = new SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}>(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); } public bool IsSupported => {Isa}.IsSupported; diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/_TernaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/_TernaryOpTestTemplate.template index eb6fc49d009b33..5cd0ab652ea088 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/_TernaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/_TernaryOpTestTemplate.template @@ -68,67 +68,6 @@ namespace JIT.HardwareIntrinsics.X86 public sealed unsafe class {TemplateName}TernaryOpTest__{Method}{RetBaseType} { - private struct DataTable - { - private byte[] inArray1; - private byte[] inArray2; - private byte[] inArray3; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle inHandle2; - private GCHandle inHandle3; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op3BaseType}[] inArray3, {RetBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); - int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - if (((alignment != 64) && (alignment != 32) && (alignment != 16)) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException("Invalid value of alignment"); - } - - this.inArray1 = new byte[alignment * 2]; - this.inArray2 = new byte[alignment * 2]; - this.inArray3 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); - this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); - } - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); - public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - inHandle3.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - private struct TestStruct { public {Op1VectorType}<{Op1BaseType}> _fld1; @@ -173,7 +112,7 @@ namespace JIT.HardwareIntrinsics.X86 private {Op2VectorType}<{Op2BaseType}> _fld2; private {Op3VectorType}<{Op3BaseType}> _fld3; - private DataTable _dataTable; + private SimpleTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}> _dataTable; public {TemplateName}TernaryOpTest__{Method}{RetBaseType}() { @@ -189,7 +128,7 @@ namespace JIT.HardwareIntrinsics.X86 for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } - _dataTable = new DataTable(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize); + _dataTable = new SimpleTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}>(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize); } public bool IsSupported => {Isa}.IsSupported; diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/_UnaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/_UnaryOpTestTemplate.template index e5f9148acd9368..308bb33e72fdf3 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/_UnaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/_UnaryOpTestTemplate.template @@ -68,51 +68,6 @@ namespace JIT.HardwareIntrinsics.X86 public sealed unsafe class {TemplateName}UnaryOpTest__{Method}{RetBaseType} { - private struct DataTable - { - private byte[] inArray1; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - if (((alignment != 64) && (alignment != 32) && (alignment != 16)) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException("Invalid value of alignment"); - } - - this.inArray1 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - } - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - private struct TestStruct { public {Op1VectorType}<{Op1BaseType}> _fld1; @@ -145,7 +100,7 @@ namespace JIT.HardwareIntrinsics.X86 private {Op1VectorType}<{Op1BaseType}> _fld1; - private DataTable _dataTable; + private SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}> _dataTable; public {TemplateName}UnaryOpTest__{Method}{RetBaseType}() { @@ -155,7 +110,7 @@ namespace JIT.HardwareIntrinsics.X86 Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); + _dataTable = new SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}>(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); } public bool IsSupported => {Isa}.IsSupported; @@ -167,11 +122,11 @@ namespace JIT.HardwareIntrinsics.X86 TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); var result = {Isa}.{Method}( - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr) ); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); } public void RunBasicScenario_Load() @@ -179,11 +134,11 @@ namespace JIT.HardwareIntrinsics.X86 TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); var result = {Isa}.{Method}( - {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)) + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)) ); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); } public void RunBasicScenario_LoadAligned() @@ -191,11 +146,11 @@ namespace JIT.HardwareIntrinsics.X86 TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); var result = {Isa}.{Method}( - {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)) + {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)) ); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); } public void RunReflectionScenario_UnsafeRead() @@ -204,18 +159,18 @@ namespace JIT.HardwareIntrinsics.X86 var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) }) .Invoke(null, new object[] { - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr) }); Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); } public void RunLclVarScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); - var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr); var result = {Isa}.{Method}(op1); Unsafe.Write(_dataTable.outArrayPtr, result); diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Sse2/ConvertToVector128Int32WithTruncation.Int32.cs b/src/tests/JIT/HardwareIntrinsics/X86/Sse2/ConvertToVector128Int32WithTruncation.Int32.cs deleted file mode 100644 index ae7d8e1c490d7c..00000000000000 --- a/src/tests/JIT/HardwareIntrinsics/X86/Sse2/ConvertToVector128Int32WithTruncation.Int32.cs +++ /dev/null @@ -1,375 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/****************************************************************************** - * This file is auto-generated from a template file by the GenerateTests.csx * - * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * - * changes, please update the corresponding template and run according to the * - * directions listed in the file. * - ******************************************************************************/ - -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace JIT.HardwareIntrinsics.X86 -{ - public static partial class Program - { - private static void ConvertToVector128Int32WithTruncationInt32Vector128Single() - { - var test = new SimpleUnaryOpConvTest__ConvertToVector128Int32WithTruncationInt32Vector128Single(); - - if (test.IsSupported) - { - // Validates basic functionality works, using Unsafe.Read - test.RunBasicScenario_UnsafeRead(); - - if (Sse2.IsSupported) - { - // Validates basic functionality works, using Load - test.RunBasicScenario_Load(); - - // Validates basic functionality works, using LoadAligned - test.RunBasicScenario_LoadAligned(); - } - - // Validates calling via reflection works, using Unsafe.Read - test.RunReflectionScenario_UnsafeRead(); - - if (Sse2.IsSupported) - { - // Validates calling via reflection works, using Load - test.RunReflectionScenario_Load(); - - // Validates calling via reflection works, using LoadAligned - test.RunReflectionScenario_LoadAligned(); - } - - // Validates passing a static member works - test.RunClsVarScenario(); - - // Validates passing a local works, using Unsafe.Read - test.RunLclVarScenario_UnsafeRead(); - - if (Sse2.IsSupported) - { - // Validates passing a local works, using Load - test.RunLclVarScenario_Load(); - - // Validates passing a local works, using LoadAligned - test.RunLclVarScenario_LoadAligned(); - } - - // Validates passing the field of a local class works - test.RunClassLclFldScenario(); - - // Validates passing an instance member of a class works - test.RunClassFldScenario(); - - // Validates passing the field of a local struct works - test.RunStructLclFldScenario(); - - // Validates passing an instance member of a struct works - test.RunStructFldScenario(); - } - else - { - // Validates we throw on unsupported hardware - test.RunUnsupportedScenario(); - } - - if (!test.Succeeded) - { - throw new Exception("One or more scenarios did not complete as expected."); - } - } - } - - public sealed unsafe class SimpleUnaryOpConvTest__ConvertToVector128Int32WithTruncationInt32Vector128Single - { - private struct TestStruct - { - public Vector128 _fld; - - public static TestStruct Create() - { - var testStruct = new TestStruct(); - - for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); - - return testStruct; - } - - public void RunStructFldScenario(SimpleUnaryOpConvTest__ConvertToVector128Int32WithTruncationInt32Vector128Single testClass) - { - var result = Sse2.ConvertToVector128Int32WithTruncation(_fld); - - Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); - } - } - - private static readonly int LargestVectorSize = 16; - - private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); - private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); - - private static Single[] _data = new Single[Op1ElementCount]; - - private static Vector128 _clsVar; - - private Vector128 _fld; - - private SimpleUnaryOpTest__DataTable _dataTable; - - static SimpleUnaryOpConvTest__ConvertToVector128Int32WithTruncationInt32Vector128Single() - { - for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); - } - - public SimpleUnaryOpConvTest__ConvertToVector128Int32WithTruncationInt32Vector128Single() - { - Succeeded = true; - - for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); - - for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } - _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Int32[RetElementCount], LargestVectorSize); - } - - public bool IsSupported => Sse2.IsSupported; - - public bool Succeeded { get; set; } - - public void RunBasicScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - - var result = Sse2.ConvertToVector128Int32WithTruncation( - Unsafe.Read>(_dataTable.inArrayPtr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - - var result = Sse2.ConvertToVector128Int32WithTruncation( - Sse2.LoadVector128((Single*)(_dataTable.inArrayPtr)) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_LoadAligned() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); - - var result = Sse2.ConvertToVector128Int32WithTruncation( - Sse2.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); - } - - public void RunReflectionScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - - var result = typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Int32WithTruncation), new Type[] { typeof(Vector128) }) - .Invoke(null, new object[] { - Unsafe.Read>(_dataTable.inArrayPtr) - }); - - Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); - ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); - } - - public void RunReflectionScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - - var result = typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Int32WithTruncation), new Type[] { typeof(Vector128) }) - .Invoke(null, new object[] { - Sse2.LoadVector128((Single*)(_dataTable.inArrayPtr)) - }); - - Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); - ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); - } - - public void RunReflectionScenario_LoadAligned() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); - - var result = typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Int32WithTruncation), new Type[] { typeof(Vector128) }) - .Invoke(null, new object[] { - Sse2.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)) - }); - - Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); - ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); - } - - public void RunClsVarScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - - var result = Sse2.ConvertToVector128Int32WithTruncation( - _clsVar - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_clsVar, _dataTable.outArrayPtr); - } - - public void RunLclVarScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); - - var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); - var result = Sse2.ConvertToVector128Int32WithTruncation(firstOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(firstOp, _dataTable.outArrayPtr); - } - - public void RunLclVarScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); - - var firstOp = Sse2.LoadVector128((Single*)(_dataTable.inArrayPtr)); - var result = Sse2.ConvertToVector128Int32WithTruncation(firstOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(firstOp, _dataTable.outArrayPtr); - } - - public void RunLclVarScenario_LoadAligned() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); - - var firstOp = Sse2.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)); - var result = Sse2.ConvertToVector128Int32WithTruncation(firstOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(firstOp, _dataTable.outArrayPtr); - } - - public void RunClassLclFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - - var test = new SimpleUnaryOpConvTest__ConvertToVector128Int32WithTruncationInt32Vector128Single(); - var result = Sse2.ConvertToVector128Int32WithTruncation(test._fld); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(test._fld, _dataTable.outArrayPtr); - } - - public void RunClassFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - - var result = Sse2.ConvertToVector128Int32WithTruncation(_fld); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld, _dataTable.outArrayPtr); - } - - public void RunStructLclFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); - - var test = TestStruct.Create(); - var result = Sse2.ConvertToVector128Int32WithTruncation(test._fld); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(test._fld, _dataTable.outArrayPtr); - } - - public void RunStructFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); - - var test = TestStruct.Create(); - test.RunStructFldScenario(this); - } - - public void RunUnsupportedScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); - - Succeeded = false; - - try - { - RunBasicScenario_UnsafeRead(); - } - catch (PlatformNotSupportedException) - { - Succeeded = true; - } - } - - private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") - { - Single[] inArray = new Single[Op1ElementCount]; - Int32[] outArray = new Int32[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); - - ValidateResult(inArray, outArray, method); - } - - private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") - { - Single[] inArray = new Single[Op1ElementCount]; - Int32[] outArray = new Int32[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); - - ValidateResult(inArray, outArray, method); - } - - private void ValidateResult(Single[] firstOp, Int32[] result, [CallerMemberName] string method = "") - { - if (Sse2Verify.ConvertToVector128Int32WithTruncation(result, firstOp)) - { - Succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) - { - if (Sse2Verify.ConvertToVector128Int32WithTruncation(result, firstOp)) - { - Succeeded = false; - break; - } - } - } - - if (!Succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.ConvertToVector128Int32WithTruncation)}(Vector128): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - } - } - } -} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_r.csproj new file mode 100644 index 00000000000000..41c8931bed2b55 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512BW_VL_Vector128_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_ro.csproj new file mode 100644 index 00000000000000..68076c3230f244 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Avx512BW_VL_Vector128_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512BW_VL_Vector128_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Program.Avx512BW_VL_Vector128.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Program.Avx512BW_VL_Vector128.cs new file mode 100644 index 00000000000000..8e9512fa18d691 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector128/Program.Avx512BW_VL_Vector128.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512BW_VL_Vector128 +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_r.csproj new file mode 100644 index 00000000000000..76689ab25f3341 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512BW_VL_Vector256_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_ro.csproj new file mode 100644 index 00000000000000..e453a772ae16a8 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Avx512BW_VL_Vector256_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512BW_VL_Vector256_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Program.Avx512BW_VL_Vector256.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Program.Avx512BW_VL_Vector256.cs new file mode 100644 index 00000000000000..8a6257f32df6ac --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512BW_VL_Vector256/Program.Avx512BW_VL_Vector256.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512BW_VL_Vector256 +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_r.csproj new file mode 100644 index 00000000000000..6fb84148a2d2a4 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512DQ_ScalarUpper_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_ro.csproj new file mode 100644 index 00000000000000..cde667fb6d2c5a --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Avx512DQ_ScalarUpper_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512DQ_ScalarUpper_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Program.Avx512DQ_ScalarUpper.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Program.Avx512DQ_ScalarUpper.cs new file mode 100644 index 00000000000000..d5ee7dafa28abc --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512DQ_ScalarUpper/Program.Avx512DQ_ScalarUpper.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512DQ_ScalarUpper +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_r.csproj new file mode 100644 index 00000000000000..c529fcf5dfc5fd --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512F_ScalarUpper_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_ro.csproj new file mode 100644 index 00000000000000..7a0ffd3b945cf9 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Avx512F_ScalarUpper_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512F_ScalarUpper_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Program.Avx512F_ScalarUpper.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Program.Avx512F_ScalarUpper.cs new file mode 100644 index 00000000000000..46f0585e81a7b2 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_ScalarUpper/Program.Avx512F_ScalarUpper.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512F_ScalarUpper +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_r.csproj new file mode 100644 index 00000000000000..d0ee67147ff46d --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512F_X64_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_ro.csproj new file mode 100644 index 00000000000000..c6ed7edc3123cc --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Avx512F_X64_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512F_X64_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Program.Avx512F_X64.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Program.Avx512F_X64.cs new file mode 100644 index 00000000000000..cf39595135de1e --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512F_X64/Program.Avx512F_X64.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512F_X64 +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_r.csproj new file mode 100644 index 00000000000000..f0c8a2644c5e8f --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512Vbmi_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_ro.csproj new file mode 100644 index 00000000000000..738ffc91365939 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Avx512Vbmi_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512Vbmi_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Program.Avx512Vbmi.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Program.Avx512Vbmi.cs new file mode 100644 index 00000000000000..0531b6f329a871 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi/Program.Avx512Vbmi.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512Vbmi +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_r.csproj new file mode 100644 index 00000000000000..d3947eb4d6c7b8 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512Vbmi_VL_Vector128_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_ro.csproj new file mode 100644 index 00000000000000..c45f12dbbe1209 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Avx512Vbmi_VL_Vector128_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512Vbmi_VL_Vector128_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Program.Avx512Vbmi_VL_Vector128.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Program.Avx512Vbmi_VL_Vector128.cs new file mode 100644 index 00000000000000..4da50c0b49cb45 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector128/Program.Avx512Vbmi_VL_Vector128.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512Vbmi_VL_Vector128 +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_r.csproj new file mode 100644 index 00000000000000..777f83b5c67283 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512Vbmi_VL_Vector256_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_ro.csproj new file mode 100644 index 00000000000000..224d4752be30e5 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Avx512Vbmi_VL_Vector256_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx512Vbmi_VL_Vector256_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Program.Avx512Vbmi_VL_Vector256.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Program.Avx512Vbmi_VL_Vector256.cs new file mode 100644 index 00000000000000..f36bfcaf1744dc --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx512/Avx512Vbmi_VL_Vector256/Program.Avx512Vbmi_VL_Vector256.cs @@ -0,0 +1,16 @@ +// 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; + +namespace JIT.HardwareIntrinsics.X86._Avx512Vbmi_VL_Vector256 +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/Methodical/delegate/GSDelegate.cs b/src/tests/JIT/Methodical/delegate/GSDelegate.cs new file mode 100644 index 00000000000000..cbf80ad8848aca --- /dev/null +++ b/src/tests/JIT/Methodical/delegate/GSDelegate.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Reflection; + + +public interface IGetContents { + (string, int, T) GetContents(); +} +public struct MyStruct : IGetContents { + public string s; + public int a; + public T t; + + public (string, int, T) GetContents() + { + return (s, a, t); + } +} + +public class Program { + + public delegate (string, int, T) MyDelegate(IGetContents arg); + + public static int Main(string[] args) + { + int retVal = 100; + + try { + MyStruct myStruct = new MyStruct(); + myStruct.s = "test1"; + myStruct.a = 42; + myStruct.t = "test2"; + + MethodInfo mi = typeof(IGetContents).GetMethod("GetContents"); + MyDelegate func = (MyDelegate)mi.CreateDelegate(typeof(MyDelegate)); + + (string c1, int c2, string c3) = func(myStruct); + if (c1 != "test1") + retVal = 1; + if (c2 != 42) + retVal = 2; + if (c3 != "test2") + retVal = 3; + } catch (Exception e) { + Console.WriteLine(e); + retVal = 1; + } + + return retVal; + } +} diff --git a/src/tests/JIT/Methodical/delegate/GSDelegate.csproj b/src/tests/JIT/Methodical/delegate/GSDelegate.csproj new file mode 100644 index 00000000000000..96112c69f3c377 --- /dev/null +++ b/src/tests/JIT/Methodical/delegate/GSDelegate.csproj @@ -0,0 +1,13 @@ + + + Exe + true + + + PdbOnly + True + + + + + diff --git a/src/tests/JIT/Methodical/delegate/VirtualDelegate.cs b/src/tests/JIT/Methodical/delegate/VirtualDelegate.cs new file mode 100644 index 00000000000000..5a28c6841ad140 --- /dev/null +++ b/src/tests/JIT/Methodical/delegate/VirtualDelegate.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + + +using System; +using System.Runtime.InteropServices; + +public class VirtualDelegate +{ + public static int Main () { + int retVal = 100; + try { + var del = (Func)Delegate.CreateDelegate (typeof (Func), null, typeof (object).GetMethod ("ToString")); + if (del ("FOO") != "FOO") + retVal = 1; + } catch(Exception e) { + Console.WriteLine(e); + retVal = 1; + } + + return retVal; + + } +} diff --git a/src/tests/JIT/Methodical/delegate/VirtualDelegate.csproj b/src/tests/JIT/Methodical/delegate/VirtualDelegate.csproj new file mode 100644 index 00000000000000..c8f15c2cc00c1e --- /dev/null +++ b/src/tests/JIT/Methodical/delegate/VirtualDelegate.csproj @@ -0,0 +1,13 @@ + + + Exe + true + + + PdbOnly + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.cs b/src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.cs new file mode 100644 index 00000000000000..042df982dfb083 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.cs @@ -0,0 +1,47 @@ +// 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.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using Xunit; + +public class Program +{ + [Fact] + public static int TestEntryPoint() + { + + Vector256 v256Shuffle = Vector256.Create(100, 101, 102, 103, 104, 105, 106, 107); + Vector256 v256ShuffleExpectedResult = Vector256.Create(107, 105, 0, 101, 106, 104, 0, 100); + Vector256 v256ShuffleActualResult = Vector256Shuffle(v256Shuffle); + if(v256ShuffleExpectedResult != v256ShuffleActualResult) + { + return 1; + } + + Vector512 v512Shuffle = Vector512.Create(100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115); + Vector512 v512ShuffleExpectedResult = Vector512.Create(115, 113, 111, 0, 107, 105, 103, 101, 114, 112, 110, 108, 0, 104, 102, 100); + Vector512 v512ShuffleActualResult = Vector512Shuffle(v512Shuffle); + if (v512ShuffleExpectedResult != v512ShuffleActualResult) + { + return 1; + } + return 100; + } + + + [MethodImpl(MethodImplOptions.NoInlining)] + public static Vector256 Vector256Shuffle(Vector256 v1) + { + return Vector256.Shuffle(v1, Vector256.Create(7, 5, 132, 1, 6, 4, -3, 0)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static Vector512 Vector512Shuffle(Vector512 v1) + { + return Vector512.Shuffle(v1, Vector512.Create(15, 13, 11, 99, 7, 5, 3, 1, 14, 12, 10, 8, -11, 4, 2, 0)); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.csproj b/src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.csproj new file mode 100644 index 00000000000000..501217e4d86892 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/GitHub_85129/GitHub_85129.csproj @@ -0,0 +1,9 @@ + + + None + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635.il b/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635.il index db7d01121eb164..43140ffd87ea9a 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635.il +++ b/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635.il @@ -32,9 +32,6 @@ call bool .this::ProblemWithLocAlloc() brtrue LOCALLOC_FAILED - call bool .this::ProblemWithCapturingCtors() - brtrue CAPTURING_CTORS_FAILED - ldc.i4 100 ret @@ -49,10 +46,6 @@ LOCALLOC_FAILED: ldc.i4 103 ret - - CAPTURING_CTORS_FAILED: - ldc.i4 104 - ret } .method private static bool ProblemWithDevirtualization() noinlining @@ -120,29 +113,6 @@ stind.i4 ret } - - .method private static bool ProblemWithCapturingCtors() noinlining - { - .locals (valuetype Closure closure) - - ldc.i4 EXPECTED - ldloca closure - newobj instance void Struct::.ctor(int32, valuetype Closure&) - ldloc closure - ldfld valuetype Struct& Closure::StructRef - ldc.i4 THRASHED - stfld int32 Struct::Value - ldfld int32 Struct::Value - ldc.i4 EXPECTED - bne.un FAILED - - ldc.i4 FALSE - ret - - FAILED: - ldc.i4 TRUE - ret - } } .class interface Interface diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.il b/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.il new file mode 100644 index 00000000000000..5e73749a57c376 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.il @@ -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. + +.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } +.assembly extern xunit.core {} +.assembly extern System.Console { } + +.assembly Runtime_74635_1 { } + +#define TRUE "1" +#define FALSE "0" +#define THIS "0" + +#define EXPECTED "0" +#define THRASHED "1" + +.class public Runtime_74635_1 extends [System.Runtime]System.Object +{ + .method public static int32 Main() + { + .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( + 01 00 00 00 + ) + .entrypoint + + .locals (valuetype Closure closure) + + ldc.i4 EXPECTED + ldloca closure + newobj instance void Struct::.ctor(int32, valuetype Closure&) + ldloc closure + ldfld valuetype Struct& Closure::StructRef + ldc.i4 THRASHED + stfld int32 Struct::Value + ldfld int32 Struct::Value + ldc.i4 EXPECTED + bne.un FAILED + + ldc.i4 100 + ret + + FAILED: + ldc.i4 101 + ret + } +} + +.class sealed sequential Struct extends [System.Runtime]System.ValueType +{ + .field public int32 Value + + .method public void .ctor(int32 val, valuetype Closure& closureRef) noinlining + { + ldarg THIS + ldarg val + stfld int32 .this::Value + + ldarg closureRef + ldarg THIS + stfld valuetype Struct& Closure::StructRef + + ret + } +} + +.class sealed Closure extends [System.Runtime]System.ValueType +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00) + + .field public valuetype Struct& StructRef +} + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.ilproj b/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.ilproj new file mode 100644 index 00000000000000..5fa250452852d2 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635_1.ilproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.cs b/src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.cs new file mode 100644 index 00000000000000..110ea1d0d802b1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.cs @@ -0,0 +1,131 @@ +// 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.CompilerServices; + +public class Program +{ + public Program() + { + } + + static int Main(string[] args) + { + Foo currentFoo; + + Bacon defaultBacon = new Bacon(-180, 180, true, false, 300f, 0.1f, 0.1f, "Foo", false); + currentFoo = new Foo(); + try { + currentFoo.GetBar().m_Bacon = defaultBacon; + } catch (NullReferenceException) { + return 100; + } + return 101; + } +} + +public class Foo +{ + private Bar m_Bar; + public Bar GetBar() + { + return m_Bar; + } +} + + +public class Bar +{ + public Bacon m_Bacon = new Bacon(-180, 180, true, false, 300f, 0.1f, 0.1f, "Foo", false); +} + +public struct Bacon +{ + public float Value; + public enum FooEnum + { + One, + Two + }; + + public FooEnum m_FooEnum; + public float m_f1; + public float m_f2; + public float m_f3; + public string m_s1; + public float m_f8; + public bool m_bool1; + public float m_f4; + public float m_f5; + public bool m_bool2; + public FooBar m_FooBar; + + float m_f6; + float m_f7; + int m_i1; + + public bool bool3 { get; set; } + + public bool bool4 { get; set; } + + public interface IFooInterface + { + float GetFooValue(int foo); + } + + IFooInterface m_FooProvider; + int m_i2; + + public Bacon( + float minValue, float maxValue, bool wrap, bool rangeLocked, + float maxSpeed, float accelTime, float decelTime, + string name, bool invert) + { + m_f4 = minValue; + m_f5 = maxValue; + m_bool2 = wrap; + bool3 = rangeLocked; + + bool4 = false; + m_FooBar = new FooBar(false, 1, 2); + + m_FooEnum = FooEnum.One; + m_f1 = maxSpeed; + m_f2 = accelTime; + m_f3 = decelTime; + Value = (minValue + maxValue) / 2; + m_s1 = name; + m_f8 = 0; + m_bool1 = invert; + + m_f6 = 0f; + m_FooProvider = null; + m_i2 = 0; + m_f7 = 0; + m_i1 = 0; + } + + public struct FooBar + { + public bool m_FooBar_bool1; + public float m_FooBar_f1; + public float m_FooBar_f2; + + float m_FooBar_f3; + float m_FooBar_f4; + float m_FooBar_f5; + int m_FooBar_i1; + int m_FooBar_i2; + + public FooBar(bool b1, float f1, float f2) + { + m_FooBar_bool1 = b1; + m_FooBar_f1 = f1; + m_FooBar_f2 = f2; + m_FooBar_f4 = 0; + m_FooBar_f5 = 0; + m_FooBar_i1 = m_FooBar_i2 = -1; + m_FooBar_f3 = 0; + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.csproj new file mode 100644 index 00000000000000..23a7bac808073e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_82535/Runtime_82535.csproj @@ -0,0 +1,10 @@ + + + Library + True + + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.il b/src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.il new file mode 100644 index 00000000000000..1c94c70f521aba --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.il @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern System.Runtime { } +.assembly extern xunit.core { } +.assembly Runtime_84522 { } + +.class sealed StructWithInt extends [System.Runtime]System.ValueType +{ + .field public int32 Value +} + +.class Runtime_84522 extends [System.Runtime]System.Object +{ + .method public static int32 Main() + { + .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( + 01 00 00 00 + ) + .entrypoint + + .try + { + ldc.i4 0 + newarr StructWithInt + call void .this::UnusedLdelem(valuetype StructWithInt[]) + leave FAIL + } + catch [System.Runtime]System.IndexOutOfRangeException + { + pop + leave SUCCESS + } + + FAIL: + ldc.i4 0 + ret + + SUCCESS: + ldc.i4 100 + ret + } + + .method private static void UnusedLdelem(valuetype StructWithInt[] arr) noinlining + { + ldarg arr + ldc.i4 0 + ldelem valuetype StructWithInt + pop + ret + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.ilproj b/src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.ilproj new file mode 100644 index 00000000000000..4b3a54c1abb8a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_84522/Runtime_84522.ilproj @@ -0,0 +1,9 @@ + + + None + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_84693/Runtime_84693.cs b/src/tests/JIT/Regression/JitBlue/Runtime_84693/Runtime_84693.cs index 65e6202aabbe4a..19e39efcffa63f 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_84693/Runtime_84693.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_84693/Runtime_84693.cs @@ -28,7 +28,7 @@ public static int M8(byte arg0) } } - [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/85081")] public static int TestEntryPoint() { var result = Test.Program.M8(1); if (result != 255) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.cs b/src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.cs new file mode 100644 index 00000000000000..f6ff6fdc321dfa --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.cs @@ -0,0 +1,50 @@ +// 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.CompilerServices; +using Xunit; + +public class Runtime_85088 +{ + [Fact] + public static int Test() + { + Foo f = new(); + try + { + try + { + throw new Exception(); + } + finally + { + f.X = 15; + f.Y = 20; + f.X += f.Y; + f.Y *= f.X; + + // f will be physically promoted and will require a read back after this call. + // Since this is a finally, some platforms will have a GT_RETFILT that we were + // inserting IR after instead of before. + f = Call(f); + } + } + catch + { + } + + return f.X + f.Y; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Foo Call(Foo f) + { + return new Foo { X = 75, Y = 25 }; + } + + private struct Foo + { + public short X, Y; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.csproj new file mode 100644 index 00000000000000..85f04c1ebc8f71 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85088/Runtime_85088.csproj @@ -0,0 +1,9 @@ + + + True + + + + + + \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.cs b/src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.cs new file mode 100644 index 00000000000000..249fd4af0c075d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.cs @@ -0,0 +1,107 @@ +// 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; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Xunit; + +public class Test +{ + // Verify that containment on NEG is correctly handled for ARM64. + public class Program + { + [MethodImpl(MethodImplOptions.NoInlining)] + static void Consume(int x) { } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Consume(bool x) { } + //--------------------------------- + public static uint s_2; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Test1() + { + int vr0 = default(int); + if (56058 < (uint)(-s_2)) + { + Consume(vr0); + return 0; + } + return 100; + } + //--------------------------------- + public class C0 + { + public bool F8; + } + + public static C0 s_11; + public static byte s_35; + public static sbyte s_44; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Test2() + { + try + { + s_11.F8 |= s_35 < (-(1 << s_44)); + return 0; + } + catch (NullReferenceException) + { + return 100; + } + } + //--------------------------------- + public static uint s_4; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Test3() + { + return M17(0); + } + + public static int M17(long arg0) + { + short var0 = default(short); + if ((ulong)((-s_4) & arg0) >= 1) + { + Consume(var0); + return 0; + } + return 100; + } + //--------------------------------- + public static long s_7; + public static int[] s_12 = new int[] { 0 }; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Test4() + { + s_12[0] = -2147483648; + var vr9 = (int)s_7 < (-s_12[0]); + Consume(vr9); + return vr9 ? 0 : 100; + } + } + + [Fact] + public static int TestEntryPoint() + { + if (Program.Test1() != 100) + return 0; + + if (Program.Test2() != 100) + return 0; + + if (Program.Test3() != 100) + return 0; + + if (Program.Test4() != 100) + return 0; + + return 100; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85225/Runtime_85225.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.cs b/src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.cs new file mode 100644 index 00000000000000..7aadc68a28d95f --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.cs @@ -0,0 +1,36 @@ +// 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 Xunit; + +// Generated by Fuzzlyn v1.5 on 2023-04-23 17:14:26 +// Run on X64 Windows +// Seed: 11244895947685014560 +// Reduced from 7.8 KiB to 0.3 KiB in 00:00:41 +// Hits JIT assert in Release: +// Assertion failed '!"SSA check failures"' in 'Program:M1()' during 'Redundant branch opts' (IL size 29; hash 0xaf510bb6; FullOpts) +// +// File: D:\a\_work\1\s\src\coreclr\jit\fgdiagnostic.cpp Line: 4392 +// +public class Runtime_85226 +{ + [Fact] + public static int Test() + { + M1(); + return 100; + } + + private static void M1() + { + for (int var0 = 0; var0 < -1; var0++) + { + short var1 = 2; + if (((ushort)((var0 % (var1 | 1)) % 0) < 0UL)) + { + return; + } + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85226/Runtime_85226.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.cs b/src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.cs new file mode 100644 index 00000000000000..f594215b3d02f4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.cs @@ -0,0 +1,50 @@ +// 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; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Xunit; + +public class Test +{ + public class C0 + { + public C0(ulong f0, sbyte f1, byte f2, ulong f3, ulong f4, int f5, short f6) + { + } + } + + // This is trying to verify that we eliminate 'mov' instructions correctly. + public class Program + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static ulong Consume(ulong x) { return x; } + + public static ushort s_1; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static ulong M0() + { + ulong var0 = ~(ulong)(uint)(-15356 * (2637600427U % (byte)((2147483647 ^ (4167361218894137384UL * (ushort)(-(ushort)(-(ushort)(128 * (5114990800133743712L % (byte)((byte)(-(byte)(-(byte)(-(byte)~(byte)(-2 % (short)((short)~(short)(-(short)(-90400400 - (-(0 | ~~(int)(32766 & (uint)(-~(uint)(-(uint)(629572031969723397L ^ (sbyte)(1UL * (byte)(8945663325738713761L / ((-(long)(127 / (sbyte)((sbyte)(-23817 % (ushort)((ushort)~M1(new C0(8144643251292930980UL, -118, 183, 18446744073709551614UL, 1827525571111008345UL, 1751590714, -32653)) | 1)) | 1))) | 1))))))))))) | 1))))) | 1))))))) | 1))); + return Program.Consume(var0); + } + + public static ushort M1(C0 argThis) + { + return s_1; + } + } + + [Fact] + public static int TestEntryPoint() + { + var result = Test.Program.M0(); + if (result != 18446744069414922151) + { + return 0; + } + return 100; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85602/Runtime_85602.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.cs b/src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.cs new file mode 100644 index 00000000000000..53a1442ac6d0e6 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.cs @@ -0,0 +1,181 @@ +// 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; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Xunit; + +public class Test +{ + public class TestClass + { + public struct S1 + { + public float float_0; + } + public struct S2 + { + public struct S2_D1_F1 + { + public uint uint_1; + } + } + static bool s_bool_2 = true; + static byte s_byte_3 = 1; + static char s_char_4 = 'M'; + static decimal s_decimal_5 = 2.0405405405405405405405405405m; + static double s_double_6 = -1.8846153846153846; + static short s_short_7 = -1; + static int s_int_8 = -5; + static long s_long_9 = -5; + static sbyte s_sbyte_10 = 1; + static float s_float_11 = -4.952381f; + static string s_string_12 = "JZDP"; + static ushort s_ushort_13 = 1; + static uint s_uint_14 = 5; + static ulong s_ulong_15 = 2; + static S1 s_s1_16 = new S1(); + static S2.S2_D1_F1 s_s2_s2_d1_f1_17 = new S2.S2_D1_F1(); + static S2 s_s2_18 = new S2(); + bool bool_19 = true; + byte byte_20 = 0; + char char_21 = 'W'; + decimal decimal_22 = 2.2307692307692307692307692308m; + double double_23 = -1; + short short_24 = 0; + int int_25 = 0; + long long_26 = 2; + sbyte sbyte_27 = -2; + float float_28 = 0.071428575f; + string string_29 = "MNK"; + ushort ushort_30 = 2; + uint uint_31 = 1; + ulong ulong_32 = 31; + S1 s1_33 = new S1(); + S2.S2_D1_F1 s2_s2_d1_f1_34 = new S2.S2_D1_F1(); + S2 s2_35 = new S2(); + static int s_loopInvariant = 3; + private static List toPrint = new List(); + [MethodImpl(MethodImplOptions.NoInlining)] + public bool LeafMethod0() + { + unchecked + { + return ((bool)(((ulong)(((ulong)(((int)(int_25 % ((int)((int_25) | 66)))) % ((int)((((int)(int_25 | s_int_8))) | 53)))) + ulong_32)) == ((ulong)(((ulong)(((ulong)(s_ulong_15 ^ s_ulong_15)) + ((ulong)(s_int_8 % ((int)((s_int_8) | 49)))))) * ((ulong)(((ulong)(ulong_32 * s_ulong_15)) | ulong_32)))))); + } + } + public byte LeafMethod1() + { + unchecked + { + return ((byte)(byte_20 - ((byte)(((int)(s_int_8 / ((int)((((int)(s_int_8 %= ((int)((-1) | 4))))) | 81)))) / ((int)((((int)(int_25 = ((int)(s_int_8 - 5))))) | 85)))))); + } + } + public char LeafMethod2() + { + unchecked + { + return s_char_4; + } + } + public decimal LeafMethod3() + { + unchecked + { + return ((decimal)(((int)(((int)(((int)(s_int_8 &= s_int_8)) >> ((int)(int_25 >> s_int_8)))) ^ ((int)(int_25 / ((int)((((int)(1 * int_25))) | 83)))))) / ((int)((((int)(((int)(int_25 *= ((int)(int_25 % ((int)((int_25) | 1)))))) >> ((int)(((int)(s_int_8 / ((int)((s_int_8) | 18)))) & ((int)(31 & int_25))))))) | 20)))); + } + } + public double LeafMethod4() + { + unchecked + { + return ((double)(((double)(s_double_6 *= ((double)(((double)(s_int_8 % ((int)((s_int_8) | 4)))) * ((double)(s_double_6 += s_double_6)))))) + ((double)(((int)(s_int_8 <<= ((int)(s_int_8 | int_25)))) % ((int)((((int)(s_int_8 = -5))) | 16)))))); + } + } + public short LeafMethod5() + { + unchecked + { + return ((short)(s_short_7 + ((short)(short_24 |= ((short)(((short)(s_int_8 / ((int)((int_25) | 30)))) << ((int)(int_25 + 5)))))))); + } + } + public int LeafMethod6() + { + unchecked + { + return ((int)(int_25 <<= ((int)(((int)(((int)(s_int_8 * s_int_8)) << ((int)(int_25 - 31)))) & s_int_8)))); + } + } + public long LeafMethod7() + { + unchecked + { + return ((long)(((long)(s_long_9 += ((long)(((long)(s_long_9 >>= LeafMethod6())) >> s_int_8)))) - ((long)(long_26 = long_26)))); + } + } + public S1 Method23(out S1 p_s1_653, out S1 p_s1_654, ref int p_int_655, S2.S2_D1_F1 p_s2_s2_d1_f1_656, out S2 p_s2_657, ref S2.S2_D1_F1 p_s2_s2_d1_f1_658, float p_float_659) + { + unchecked + { + bool bool_660 = true; + byte byte_661 = 2; + char char_662 = 'Y'; + decimal decimal_663 = 1.0476190476190476190476190476m; + double double_664 = -1.95; + short short_665 = 31; + int int_666 = 0; + long long_667 = 31; + sbyte sbyte_668 = 0; + float float_669 = 31f; + string string_670 = "3P5A58X"; + ushort ushort_671 = 5; + uint uint_672 = 2; + ulong ulong_673 = 2; + S1 s1_674 = new S1(); + S2.S2_D1_F1 s2_s2_d1_f1_675 = new S2.S2_D1_F1(); + S2 s2_676 = new S2(); + p_s1_653 = s1_674; + p_s1_654 = s_s1_16; + switch (((long)(((long)(s_long_9 *= ((long)(((int)(s_int_8 <<= int_25)) % ((int)((((int)(s_int_8 | s_int_8))) | 82)))))) ^ ((long)(((long)(int_25 /= ((int)((((int)(s_int_8 = LeafMethod6()))) | 38)))) + ((long)(long_26 + ((long)(-2 & LeafMethod7()))))))))) + { + case -2147483648: + { + int __loopvar0 = s_loopInvariant; + break; + } + case 31: + { + break; + } + default: + { + long_667 += ((long)(long_667 |= ((long)(long_667 & ((long)(((int)(LeafMethod6() % ((int)((p_int_655) | 24)))) % ((int)((int_666) | 2)))))))); + break; + } + } + return s_s1_16; + } + } + public void Method0() + { + unchecked + { + int int_2775 = -2147483648; + S2.S2_D1_F1 s2_s2_d1_f1_2784 = new S2.S2_D1_F1(); + int __loopvar2 = s_loopInvariant, __loopSecondaryVar2_0 = s_loopInvariant; + s_s1_16 = Method23(out s1_33, out s_s1_16, ref int_2775, s2_s2_d1_f1_2784, out s_s2_18, ref s_s2_s2_d1_f1_17, ((float)(s_int_8 /= ((int)((((int)(((int)(int_25 % ((int)((LeafMethod6()) | 91)))) * ((int)(int_25 >> s_int_8))))) | 29))))); + return; + } + } + } + + // This is trying to stress the JIT to ensure we do not encounter an assertion. + [Fact] + public static int TestEntryPoint() + { + new TestClass().Method0(); + return 100; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85630/Runtime_85630.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.cs b/src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.cs new file mode 100644 index 00000000000000..9c428384e38e99 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_85645 +{ + [Fact] + public static int Test() + { + try + { + Bar(null, new int[0]); + Console.WriteLine("FAIL: Should have thrown exception"); + return -1; + } + catch (NullReferenceException) + { + Console.WriteLine("PASS: Caught NullReferenceException"); + return 100; + } + catch (Exception ex) + { + Console.WriteLine("FAIL: {0}", ex); + return -1; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Bar(int[] a, int[] b) + { + Consume(a[0], b[0] + 3); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(int a, int b) + { + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85645/Runtime_85645.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/opt/AssertionPropagation/DynBlkNullAssertions.cs b/src/tests/JIT/opt/AssertionPropagation/DynBlkNullAssertions.cs index 22b7c3b94e6934..f13bbc20103974 100644 --- a/src/tests/JIT/opt/AssertionPropagation/DynBlkNullAssertions.cs +++ b/src/tests/JIT/opt/AssertionPropagation/DynBlkNullAssertions.cs @@ -29,7 +29,7 @@ private static bool TestCpBlk(ref byte dst, ref byte src, uint size) { Unsafe.CopyBlock(ref dst, ref src, size); - return Unsafe.AreSame(ref dst, ref Unsafe.NullRef()); + return Unsafe.AreSame(ref dst, ref Unsafe.NullRef()) && Unsafe.AreSame(ref src, ref Unsafe.NullRef()); } [MethodImpl(MethodImplOptions.NoInlining)] diff --git a/src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.cs b/src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.cs new file mode 100644 index 00000000000000..cd10be102c8724 --- /dev/null +++ b/src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Showed a JIT importer bug where a tree would be constructed for +// call / stsfld and then the type initialization call inserted before +// the entire tree. The call needs to happen before type initialization. + +using System; +using System.Runtime.CompilerServices; + +public class CorrectException : Exception +{ +} + +public class CCC +{ + public static int Main() => ClassCallingCctor.Test(); +} + +public class ClassCallingCctor +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static int Call() => throw new CorrectException(); + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int Test() + { + try + { + ClassWithCctor.StaticField = Call(); + } + catch (CorrectException) + { + return 100; + } + catch + { + } + return 1; + } +} + +public class ClassWithCctor +{ + public static int StaticField; + static ClassWithCctor() => throw new Exception(); +} diff --git a/src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.csproj b/src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.csproj new file mode 100644 index 00000000000000..6946bed81bfd5b --- /dev/null +++ b/src/tests/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorForWrite2.csproj @@ -0,0 +1,9 @@ + + + Exe + True + + + + + diff --git a/src/tests/Regressions/coreclr/GitHub_85240/test85240.cs b/src/tests/Regressions/coreclr/GitHub_85240/test85240.cs new file mode 100644 index 00000000000000..e56c7d49128539 --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_85240/test85240.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +#pragma warning disable 8500 + +public unsafe class Program +{ + static void AssertEqual(T actual, T expected) + { + if (!actual.Equals(expected)) + throw new Exception($"Failed Scenario. Actual = {actual}. Expected = {expected}"); + } + + public static Type GrabArray() => typeof(T[]); + public static Type GrabPtr() => typeof(T*); + public static Type GrabFnptr() => typeof(delegate*); + + public static int Main() + { + AssertEqual(GrabArray().GetElementType(), typeof(int)); + AssertEqual(GrabArray().GetElementType(), typeof(string)); + + AssertEqual(GrabPtr().GetElementType(), typeof(uint)); + AssertEqual(GrabPtr().GetElementType(), typeof(object)); + + AssertEqual(GrabFnptr().GetFunctionPointerReturnType(), typeof(DateTime)); + AssertEqual(GrabFnptr().GetFunctionPointerReturnType(), typeof(Action)); + + return 100; + } +} diff --git a/src/tests/Regressions/coreclr/GitHub_85240/test85240.csproj b/src/tests/Regressions/coreclr/GitHub_85240/test85240.csproj new file mode 100644 index 00000000000000..2dc4ce74905d7f --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_85240/test85240.csproj @@ -0,0 +1,9 @@ + + + Exe + true + + + + + diff --git a/src/tests/build.proj b/src/tests/build.proj index d9df2372171cb0..e0b7398f1d7a5f 100644 --- a/src/tests/build.proj +++ b/src/tests/build.proj @@ -8,7 +8,7 @@ $(XunitTestBinBase)\TestWrappers\ 1 C# - $(OutputRid) + $(OutputRID) @@ -126,8 +126,8 @@ $(MonoBinDir) - $(MonoBinDir)/cross/$(OutputRid)/mono-aot-cross - $(MonoBinDir)/cross/$(OutputRid) + $(MonoBinDir)/cross/$(OutputRID)/mono-aot-cross + $(MonoBinDir)/cross/$(OutputRID) @@ -537,8 +537,7 @@ <_ConfigurationProperties>/p:TargetOS=$(TargetOS) /p:TargetArchitecture=$(TargetArchitecture) /p:Configuration=$(Configuration) /p:CrossBuild=$(CrossBuild) - "$(DotNetTool)" restore $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties) - "$(DotNetTool)" restore -r $(__DistroRid) $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties) + "$(DotNetTool)" restore -r $(PackageRID) $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties) @@ -578,9 +577,11 @@ $(GroupBuildCmd) "/p:Configuration=$(Configuration)" $(GroupBuildCmd) "/p:LibrariesConfiguration=$(LibrariesConfiguration)" $(GroupBuildCmd) "/p:TargetOS=$(TargetOS)" - $(GroupBuildCmd) "/p:RuntimeOS=$(RuntimeOS)" + $(GroupBuildCmd) "/p:ToolsOS=$(ToolsOS)" + $(GroupBuildCmd) "/p:PackageOS=$(PackageOS)" $(GroupBuildCmd) "/p:RuntimeFlavor=$(RuntimeFlavor)" $(GroupBuildCmd) "/p:RuntimeVariant=$(RuntimeVariant)" + $(GroupBuildCmd) "/p:ServerGarbageCollection=$(ServerGarbageCollection)" $(GroupBuildCmd) "/p:CLRTestBuildAllTargets=$(CLRTestBuildAllTargets)" $(GroupBuildCmd) "/p:UseCodeFlowEnforcement=$(UseCodeFlowEnforcement)" $(GroupBuildCmd) "/p:__TestGroupToBuild=$(__TestGroupToBuild)" diff --git a/src/tests/build.sh b/src/tests/build.sh index 5d742126a08d02..50efe6a764ebbf 100755 --- a/src/tests/build.sh +++ b/src/tests/build.sh @@ -332,7 +332,6 @@ __ConfigureOnly=0 __CopyNativeProjectsAfterCombinedTestBuild=true __CopyNativeTestBinaries=0 __CrossBuild=0 -__DistroRid="" __CompositeBuildMode= __CreatePerfmap= __TestBuildMode= diff --git a/src/tests/issues.targets b/src/tests/issues.targets index a362cbd6b8650b..d4b3f62bc226e4 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -871,9 +871,6 @@ https://github.com/dotnet/runtime/issues/615 - - https://github.com/dotnet/runtime/issues/85081 - Not compatible with crossgen2 @@ -886,9 +883,6 @@ https://github.com/dotnet/runtime/issues/81103 - - https://github.com/dotnet/runtime/issues/84007 - @@ -985,12 +979,6 @@ https://github.com/dotnet/runtimelab/issues/155: SAFEARRAY - - https://github.com/dotnet/runtime/issues/74620 - - - https://github.com/dotnet/runtime/issues/74620 - https://github.com/dotnet/runtime/issues/74620 @@ -1159,12 +1147,6 @@ https://github.com/dotnet/runtimelab/issues/155: RuntimeHelpers.InitializeArray - - https://github.com/dotnet/runtimelab/issues/188 - - - https://github.com/dotnet/runtimelab/issues/188 - https://github.com/dotnet/runtimelab/issues/155: Non-exception throw @@ -1210,9 +1192,6 @@ Needs xunit.performance - - https://github.com/dotnet/runtimelab/issues/188 - https://github.com/dotnet/runtimelab/issues/155: Varargs @@ -1222,9 +1201,6 @@ https://github.com/dotnet/runtimelab/issues/155: RuntimeHelpers.InitializeArray - - https://github.com/dotnet/runtimelab/issues/197 - https://github.com/dotnet/runtimelab/issues/155: Type equivalence @@ -1237,9 +1213,6 @@ https://github.com/dotnet/runtimelab/issues/198 - - https://github.com/dotnet/runtimelab/issues/188 - https://github.com/dotnet/runtimelab/issues/155: Varargs @@ -1258,12 +1231,6 @@ https://github.com/dotnet/runtimelab/issues/154 - - https://github.com/dotnet/runtime/issues/71883 - - - https://github.com/dotnet/runtime/issues/71883 - Won't fix https://github.com/dotnet/corert/issues/2396 @@ -1330,9 +1297,6 @@ https://github.com/dotnet/runtimelab/issues/155: Assembly.Load - - https://github.com/dotnet/runtime/issues/71883 - https://github.com/dotnet/runtimelab/issues/155: Reflection emit @@ -1432,6 +1396,9 @@ + + https://github.com/dotnet/runtime/issues/71095 + https://github.com/dotnet/runtime/issues/79022 @@ -2687,7 +2654,7 @@ needs triage - + https://github.com/dotnet/runtime/issues/74687 @@ -3345,6 +3312,12 @@ https://github.com/dotnet/runtime/issues/82859 + + https://github.com/dotnet/runtime/issues/85316 + + + https://github.com/dotnet/runtime/issues/85316 + diff --git a/src/tests/nativeaot/GenerateUnmanagedEntryPoints/GenerateUnmanagedEntryPoints.csproj b/src/tests/nativeaot/GenerateUnmanagedEntryPoints/GenerateUnmanagedEntryPoints.csproj index db5f0741f8d419..9f73f30aa0b24f 100644 --- a/src/tests/nativeaot/GenerateUnmanagedEntryPoints/GenerateUnmanagedEntryPoints.csproj +++ b/src/tests/nativeaot/GenerateUnmanagedEntryPoints/GenerateUnmanagedEntryPoints.csproj @@ -4,6 +4,9 @@ BuildAndRun true true + + + false diff --git a/src/tests/nativeaot/SmokeTests/DwarfDump/DwarfDump.csproj b/src/tests/nativeaot/SmokeTests/DwarfDump/DwarfDump.csproj index abb451df53c96e..25eece838c4b43 100644 --- a/src/tests/nativeaot/SmokeTests/DwarfDump/DwarfDump.csproj +++ b/src/tests/nativeaot/SmokeTests/DwarfDump/DwarfDump.csproj @@ -6,6 +6,7 @@ 0 true + false diff --git a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/X64Baseline.csproj b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/X64Baseline.csproj index 51ef171354befa..e49eb84629044d 100644 --- a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/X64Baseline.csproj +++ b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/X64Baseline.csproj @@ -6,7 +6,6 @@ true true $(DefineConstants);BASELINE_INTRINSICS - true diff --git a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64NonVex.csproj b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64NonVex.csproj index 86c1e23e9dfa51..5e8d35d67bf3da 100644 --- a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64NonVex.csproj +++ b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64NonVex.csproj @@ -6,7 +6,6 @@ true true $(DefineConstants);NON_VEX_INTRINSICS - true diff --git a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64Vex.csproj b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64Vex.csproj index d485e9dae32cc8..983436eab7d79f 100644 --- a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64Vex.csproj +++ b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/x64Vex.csproj @@ -6,7 +6,6 @@ true true $(DefineConstants);VEX_INTRINSICS - true diff --git a/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs b/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs index e87d6f44f46735..ed280830098392 100644 --- a/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs +++ b/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs @@ -36,6 +36,7 @@ private static int Main() TestBadClass.Run(); TestRefs.Run(); TestDelegate.Run(); + TestDelegateReflectionVisible.Run(); TestInitFromOtherClass.Run(); TestInitFromOtherClassDouble.Run(); TestDelegateToOtherClass.Run(); @@ -610,6 +611,19 @@ public static void Run() } } +class TestDelegateReflectionVisible +{ + static readonly Action s_a = DelegateTarget; + + static void DelegateTarget() { } + + public static void Run() + { + Assert.IsPreinitialized(typeof(TestDelegateReflectionVisible)); + Assert.AreEqual(nameof(DelegateTarget), s_a.Method.Name); + } +} + class TestInitFromOtherClass { class OtherClass @@ -986,9 +1000,9 @@ public static void Run() } { - // Expecting this to be a frozen array, and reported as Gen2 by the GC + // Expecting this to be a frozen array, and reported as int.MaxValue by the GC object val = AccessArray(); - Assert.AreEqual(2, GC.GetGeneration(val)); + Assert.AreEqual(int.MaxValue, GC.GetGeneration(val)); val = typeof(ClassWithTemplate<>).MakeGenericType(typeof(C4)).GetField("Array").GetValue(null); Assert.AreEqual(0, GC.GetGeneration(val)); diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index 6717acad6db5c3..06faaef6ed37ab 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -62,6 +62,8 @@ private static int Main() TestInterfaceLists.Run(); TestMethodConsistency.Run(); TestIsValueTypeWithoutTypeHandle.Run(); + TestMdArrayLoad.Run(); + TestByRefTypeLoad.Run(); // // Mostly functionality tests @@ -2181,6 +2183,34 @@ class NothingAttribute : Attribute class G where T : struct { } } + class TestMdArrayLoad + { + class Atom { } + + public static Type MakeMdArray() => typeof(T[,,]); + + public static void Run() + { + var mi = typeof(TestMdArrayLoad).GetMethod(nameof(MakeMdArray)).MakeGenericMethod(typeof(Atom)); + if ((Type)mi.Invoke(null, Array.Empty()) != typeof(Atom[,,])) + throw new Exception(); + } + } + + class TestByRefTypeLoad + { + class Atom { } + + public static Type MakeFnPtrType() => typeof(delegate*); + + public static void Run() + { + var mi = typeof(TestByRefTypeLoad).GetMethod(nameof(MakeFnPtrType)).MakeGenericMethod(typeof(Atom)); + if ((Type)mi.Invoke(null, Array.Empty()) != typeof(delegate*)) + throw new Exception(); + } + } + class TestEntryPoint { public static void Run() diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs index 2aa1bd082579f8..8e70602728f5ab 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs @@ -55,6 +55,7 @@ internal static int Run() TestMDArrayAddressMethod.Run(); TestNativeLayoutGeneration.Run(); TestByRefLikeVTables.Run(); + TestFunctionPointerLoading.Run(); return 100; } @@ -2434,6 +2435,97 @@ public static void Run() } } + class TestFunctionPointerLoading + { + interface IFace + { + Type GrabManagedFnptr(); + Type GrabManagedRefFnptr(); + Type GrabUnmanagedFnptr(); + Type GrabUnmanagedStdcallFnptr(); + Type GrabUnmanagedStdcallSuppressGCFnptr(); + Array GetFunctionPointerArray(); + Array GetFunctionPointerMdArray(); + Type GrabManagedFnptrOverAlsoGen(); + Type GrabManagedFnptrOverAlsoAlsoGen(); + } + + unsafe class Gen : IFace + { + public Type GrabManagedFnptr() => typeof(delegate*); + public Type GrabManagedRefFnptr() => typeof(delegate*); + public Type GrabUnmanagedFnptr() => typeof(delegate* unmanaged); + public Type GrabUnmanagedStdcallFnptr() => typeof(delegate* unmanaged[Stdcall]); + public Type GrabUnmanagedStdcallSuppressGCFnptr() => typeof(delegate* unmanaged[Stdcall, SuppressGCTransition]); + public Array GetFunctionPointerArray() => new delegate*[1]; + public Array GetFunctionPointerMdArray() => new delegate*[1, 1]; + public Type GrabManagedFnptrOverAlsoGen() => typeof(delegate*, AlsoGen>); + public Type GrabManagedFnptrOverAlsoAlsoGen() => typeof(delegate*, MyGen>); + } + + class MyGen { } + + class AlsoGen { } + + class AlsoAlsoGen { } + + class Atom { } + + static Type s_atomType = typeof(Atom); + + public static void Run() + { + var o = (IFace)Activator.CreateInstance(typeof(Gen<>).MakeGenericType(s_atomType)); + + { + Type t = o.GrabManagedFnptr(); + if (!t.IsFunctionPointer || t.GetFunctionPointerReturnType() != typeof(Atom) || t.IsUnmanagedFunctionPointer) + throw new Exception(); + } + + { + Type t = o.GrabManagedRefFnptr(); + if (!t.IsFunctionPointer || t.GetFunctionPointerReturnType() != typeof(Atom).MakeByRefType() || t.IsUnmanagedFunctionPointer) + throw new Exception(); + } + + { + Type t = o.GrabUnmanagedFnptr(); + if (!t.IsFunctionPointer || t.GetFunctionPointerReturnType() != typeof(Atom) || !t.IsUnmanagedFunctionPointer) + throw new Exception(); + + if (t != o.GrabUnmanagedStdcallFnptr() || t != o.GrabUnmanagedStdcallSuppressGCFnptr()) + throw new Exception(); + } + + { + Array arr = o.GetFunctionPointerArray(); + if (!arr.GetType().GetElementType().IsFunctionPointer) + throw new Exception(); + } + + { + Array arr = o.GetFunctionPointerMdArray(); + if (!arr.GetType().GetElementType().IsFunctionPointer) + throw new Exception(); + } + + { + Type t = o.GrabManagedFnptrOverAlsoGen(); + if (!t.IsFunctionPointer + || t.GetFunctionPointerReturnType().GetGenericTypeDefinition() != typeof(AlsoGen<>) + || t.GetFunctionPointerReturnType().GetGenericArguments()[0] != typeof(Atom)) + throw new Exception(); + } + + { + Type t = o.GrabManagedFnptrOverAlsoAlsoGen(); + if (!t.TypeHandle.Equals(typeof(delegate*, MyGen>).TypeHandle)) + throw new Exception(); + } + } + } + class TestDevirtualization { interface IDevirt diff --git a/src/tests/profiler/gc/nongcheap.cs b/src/tests/profiler/gc/nongcheap.cs new file mode 100644 index 00000000000000..a03c99743e1eb8 --- /dev/null +++ b/src/tests/profiler/gc/nongcheap.cs @@ -0,0 +1,55 @@ +// 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.CompilerServices; +using System.Threading; + +namespace Profiler.Tests +{ + class NonGCHeapTests + { + static readonly Guid GcAllocateEventsProfilerGuid = new Guid("EF0D191C-3FC7-4311-88AF-E474CBEB2859"); + + [MethodImpl(MethodImplOptions.NoInlining)] + static void AllocateNonGcHeapObjects() + { + // When this method is invoked, JIT is expected to trigger allocations for these + // string literals and they're expected to end up in a nongc segment (also known as frozen) + Consume("string1"); + Consume("string2"); + Consume("string3"); + Consume("string4"); + Consume("string5"); + Consume("string6"); + + int gen = GC.GetGeneration("string7"); + if (gen != int.MaxValue) + throw new Exception("object is expected to be in a non-gc heap for this test to work"); + + GC.Collect(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Consume(object o) {} + + public static int RunTest(String[] args) + { + AllocateNonGcHeapObjects(); + Console.WriteLine("Test Passed"); + return 100; + } + + public static int Main(string[] args) + { + if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase)) + { + return RunTest(args); + } + + return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location, + testName: "NonGCHeapAllocate", + profilerClsid: GcAllocateEventsProfilerGuid); + } + } +} diff --git a/src/tests/profiler/gc/nongcheap.csproj b/src/tests/profiler/gc/nongcheap.csproj new file mode 100644 index 00000000000000..d51dcb692abfe0 --- /dev/null +++ b/src/tests/profiler/gc/nongcheap.csproj @@ -0,0 +1,21 @@ + + + .NETCoreApp + exe + true + true + + true + + true + + + + + + + + diff --git a/src/tests/profiler/multiple/multiple.csproj b/src/tests/profiler/multiple/multiple.csproj index 59b9a05a030755..11dfca21ecbb57 100644 --- a/src/tests/profiler/multiple/multiple.csproj +++ b/src/tests/profiler/multiple/multiple.csproj @@ -3,6 +3,7 @@ .NETCoreApp exe true + true true diff --git a/src/tests/profiler/native/CMakeLists.txt b/src/tests/profiler/native/CMakeLists.txt index a3d2d77902f386..feb446e8846df6 100644 --- a/src/tests/profiler/native/CMakeLists.txt +++ b/src/tests/profiler/native/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES eventpipeprofiler/eventpipewritingprofiler.cpp eventpipeprofiler/eventpipemetadatareader.cpp gcallocateprofiler/gcallocateprofiler.cpp + nongcheap/nongcheap.cpp gcbasicprofiler/gcbasicprofiler.cpp gcprofiler/gcprofiler.cpp getappdomainstaticaddress/getappdomainstaticaddress.cpp diff --git a/src/tests/profiler/native/classfactory.cpp b/src/tests/profiler/native/classfactory.cpp index 418b0b680830b9..7d8aa7942e5d9d 100644 --- a/src/tests/profiler/native/classfactory.cpp +++ b/src/tests/profiler/native/classfactory.cpp @@ -7,6 +7,7 @@ #include "eventpipeprofiler/eventpipewritingprofiler.h" #include "getappdomainstaticaddress/getappdomainstaticaddress.h" #include "gcallocateprofiler/gcallocateprofiler.h" +#include "nongcheap/nongcheap.h" #include "gcbasicprofiler/gcbasicprofiler.h" #include "gcprofiler/gcprofiler.h" #include "handlesprofiler/handlesprofiler.h" @@ -69,6 +70,10 @@ HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFI { profiler = new GCAllocateProfiler(); } + else if (clsid == NonGcHeapProfiler::GetClsid()) + { + profiler = new NonGcHeapProfiler(); + } else if (clsid == GCBasicProfiler::GetClsid()) { profiler = new GCBasicProfiler(); diff --git a/src/tests/profiler/native/guids.cpp b/src/tests/profiler/native/guids.cpp index 1a4e0928c00b0d..3000fb43ca2552 100644 --- a/src/tests/profiler/native/guids.cpp +++ b/src/tests/profiler/native/guids.cpp @@ -49,6 +49,7 @@ DEFINE_GUID(IID_ICorProfilerInfo10, 0x2F1B5152,0xC869,0x40C9, DEFINE_GUID(IID_ICorProfilerInfo11, 0x06398876,0x8987,0x4154,0xB6,0x21,0x40,0xA0,0x0D,0x6E,0x4D,0x04); DEFINE_GUID(IID_ICorProfilerInfo12, 0x27B24CCD,0x1CB1,0x47C5,0x96,0xEE,0x98,0x19,0x0D,0xC3,0x09,0x59); DEFINE_GUID(IID_ICorProfilerInfo13, 0x6E6C7EE2,0x0701,0x4EC2,0x9D,0x29,0x2E,0x87,0x33,0xB6,0x69,0x34); +DEFINE_GUID(IID_ICorProfilerInfo14, 0XF460E352,0XD76D,0X4FE9,0X83,0X5F,0XF6,0XAF,0X9D,0X6E,0X86,0X2D); DEFINE_GUID(IID_ICorProfilerMethodEnum, 0xFCCEE788,0x0088,0x454B,0xA8,0x11,0xC9,0x9F,0x29,0x8D,0x19,0x42); DEFINE_GUID(IID_ICorProfilerThreadEnum, 0x571194F7,0x25ED,0x419F,0xAA,0x8B,0x70,0x16,0xB3,0x15,0x97,0x01); DEFINE_GUID(IID_ICorProfilerAssemblyReferenceProvider, 0x66A78C24,0x2EEF,0x4F65,0xB4,0x5F,0xDD,0x1D,0x80,0x38,0xBF,0x3C); diff --git a/src/tests/profiler/native/nongcheap/nongcheap.cpp b/src/tests/profiler/native/nongcheap/nongcheap.cpp new file mode 100644 index 00000000000000..eca9270d33b436 --- /dev/null +++ b/src/tests/profiler/native/nongcheap/nongcheap.cpp @@ -0,0 +1,179 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "nongcheap.h" + +GUID NonGcHeapProfiler::GetClsid() +{ + // {EF0D191C-3FC7-4311-88AF-E474CBEB2859} + GUID clsid = { 0xef0d191c, 0x3fc7, 0x4311, { 0x88, 0xaf, 0xe4, 0x74, 0xcb, 0xeb, 0x28, 0x59 } }; + return clsid; +} + +HRESULT NonGcHeapProfiler::Initialize(IUnknown* pICorProfilerInfoUnk) +{ + Profiler::Initialize(pICorProfilerInfoUnk); + + HRESULT hr = S_OK; + if (FAILED(hr = pCorProfilerInfo->SetEventMask2( + COR_PRF_ENABLE_OBJECT_ALLOCATED | COR_PRF_MONITOR_OBJECT_ALLOCATED, + COR_PRF_HIGH_BASIC_GC))) + { + printf("FAIL: ICorProfilerInfo::SetEventMask2() failed hr=0x%x", hr); + return hr; + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NonGcHeapProfiler::ObjectAllocated(ObjectID objectId, ClassID classId) +{ + COR_PRF_GC_GENERATION_RANGE gen; + HRESULT hr = pCorProfilerInfo->GetObjectGeneration(objectId, &gen); + + // non-GC objects (same for GC.GetGeneration() API) have generation = -1 + if (gen.generation == (COR_PRF_GC_GENERATION)INT32_MAX) + { + if (!FAILED(hr)) + { + // We expect GetObjectGeneration to return an error (CORPROF_E_NOT_GC_OBJECT) + // for non-GC objects. + _failures++; + } + _nonGcHeapObjects++; + if (gen.rangeLength != 0 || gen.rangeLengthReserved != 0 || gen.rangeStart != 0) + { + _failures++; + } + } + else if (FAILED(hr)) + { + _failures++; + } + return S_OK; +} + +HRESULT NonGcHeapProfiler::GarbageCollectionFinished() +{ + SHUTDOWNGUARD(); + + _garbageCollections++; + + const int MAX_NON_GC_HEAP_SEGMENTS = 16; + COR_PRF_NONGC_HEAP_RANGE segments[MAX_NON_GC_HEAP_SEGMENTS]; + ULONG segCount; + ObjectID firstObj = 0; + HRESULT hr = pCorProfilerInfo->GetNonGCHeapBounds(MAX_NON_GC_HEAP_SEGMENTS, &segCount, segments); + if (FAILED(hr)) + { + printf("GetNonGCHeapBounds returned an error\n!"); + _failures++; + } + else if (segCount == 0 || segCount > MAX_NON_GC_HEAP_SEGMENTS) + { + printf("GetNonGCHeapBounds: invalid segCount (%u)\n!", segCount); + _failures++; + } + else + { + // Save very first object ID to compare with EnumerateNonGCObjects + firstObj = segments[0].rangeStart; + + printf("\nGetNonGCHeapBounds (segCount = %u):\n", segCount); + for (ULONG i = 0; i < segCount; i++) + { + printf("\tseg#%u, rangeStart=%p, rangeLength=%u, rangeLengthReserved=%u\n", + i, (void*)segments[i].rangeStart, (ULONG)segments[i].rangeLength, (ULONG)segments[i].rangeLengthReserved); + + if ((ULONG)segments[i].rangeLength > (ULONG)segments[i].rangeLengthReserved) + { + printf("GetNonGCHeapBounds: rangeLength > rangeLengthReserved"); + _failures++; + } + + if (!segments[i].rangeStart) + { + printf("GetNonGCHeapBounds: rangeStart is null"); + _failures++; + } + } + printf("\n"); + } + + // Let's make sure we got the same number of objects as we got from the callback + // by testing the EnumerateNonGCObjects API. + ICorProfilerObjectEnum* pEnum = NULL; + hr = pCorProfilerInfo->EnumerateNonGCObjects(&pEnum); + if (FAILED(hr)) + { + printf("EnumerateNonGCObjects returned an error\n!"); + _failures++; + } + else + { + int nonGcObjectsEnumerated = 0; + ObjectID obj; + bool isFirstObj = true; + while (pEnum->Next(1, &obj, NULL) == S_OK) + { + if (isFirstObj) + { + if (firstObj != obj) + { + printf("EnumerateNonGCObjects: firstObj != obj\n!"); + _failures++; + } + } + + // Add test coverage for IsFrozenObject API, currently, it is expected to return true + // for objects from non-GC heap (it might also return true for frozen segments we don't track) + BOOL isFrozen; + hr = pCorProfilerInfo->IsFrozenObject(obj, &isFrozen); + if (FAILED(hr) || !isFrozen) + { + printf("EnumerateNonGCObjects: IsFrozenObject failed\n!"); + _failures++; + } + + isFirstObj = false; + nonGcObjectsEnumerated++; + } + + if (nonGcObjectsEnumerated != _nonGcHeapObjects) + { + printf("objectAllocated(%d) != _nonGcHeapObjects(%d)\n!", nonGcObjectsEnumerated, (int)_nonGcHeapObjects); + _failures++; + } + } + + return S_OK; +} + +HRESULT NonGcHeapProfiler::Shutdown() +{ + Profiler::Shutdown(); + + if (_garbageCollections == 0) + { + printf("PROFILER TEST FAILS: no garbage collections were triggered\n"); + _failures++; + } + + if (_nonGcHeapObjects == 0) + { + printf("PROFILER TEST FAILS: non-GC heap objects were not allocated\n"); + _failures++; + } + + if (_failures > 0) + { + printf("PROFILER TEST FAILS\n"); + } + else + { + printf("PROFILER TEST PASSES\n"); + } + printf("Non-GC objects allocated: %d\n", (int)_nonGcHeapObjects); + fflush(stdout); + return S_OK; +} diff --git a/src/tests/profiler/native/nongcheap/nongcheap.h b/src/tests/profiler/native/nongcheap/nongcheap.h new file mode 100644 index 00000000000000..9ce78b7cee1ded --- /dev/null +++ b/src/tests/profiler/native/nongcheap/nongcheap.h @@ -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. + +#pragma once + +#include "../profiler.h" + +class NonGcHeapProfiler : public Profiler +{ +public: + NonGcHeapProfiler() : Profiler(), + _nonGcHeapObjects(0), + _failures(0), + _garbageCollections(0) + {} + + static GUID GetClsid(); + virtual HRESULT STDMETHODCALLTYPE Initialize(IUnknown* pICorProfilerInfoUnk); + virtual HRESULT STDMETHODCALLTYPE ObjectAllocated(ObjectID objectId, ClassID classId); + virtual HRESULT STDMETHODCALLTYPE Shutdown(); + virtual HRESULT STDMETHODCALLTYPE GarbageCollectionFinished(); + +private: + std::atomic _nonGcHeapObjects; + std::atomic _failures; + std::atomic _garbageCollections; +}; diff --git a/src/tests/profiler/native/profiler.cpp b/src/tests/profiler/native/profiler.cpp index 0508bc9fdc9434..4eff2428b99d55 100644 --- a/src/tests/profiler/native/profiler.cpp +++ b/src/tests/profiler/native/profiler.cpp @@ -785,7 +785,7 @@ void Profiler::SetCallback(ProfilerCallback cb) s_callbackSet.Signal(); } -void Profiler::NotifyManagedCodeViaCallback(ICorProfilerInfo13 *pCorProfilerInfo) +void Profiler::NotifyManagedCodeViaCallback(ICorProfilerInfo14 *pCorProfilerInfo) { s_callbackSet.Wait(); @@ -795,7 +795,7 @@ void Profiler::NotifyManagedCodeViaCallback(ICorProfilerInfo13 *pCorProfilerInfo // some crst order asserts if we call back in to managed code. Spin up // a new thread to avoid that. pCorProfilerInfo->InitializeCurrentThread(); - s_callback(); + s_callback(); }); callbackThread.join(); diff --git a/src/tests/profiler/native/profiler.h b/src/tests/profiler/native/profiler.h index 61b718238ae08b..00c64a1d950038 100644 --- a/src/tests/profiler/native/profiler.h +++ b/src/tests/profiler/native/profiler.h @@ -88,12 +88,12 @@ class Profiler : public ICorProfilerCallback11 { private: std::atomic refCount; - static ProfilerCallback s_callback; + static ProfilerCallback s_callback; static ManualEvent s_callbackSet; protected: - static void NotifyManagedCodeViaCallback(ICorProfilerInfo13 *pCorProfilerInfo); + static void NotifyManagedCodeViaCallback(ICorProfilerInfo14 *pCorProfilerInfo); String GetClassIDName(ClassID classId); String GetFunctionIDName(FunctionID funcId); @@ -103,7 +103,7 @@ class Profiler : public ICorProfilerCallback11 static Profiler *Instance; static void SetCallback(ProfilerCallback callback); - ICorProfilerInfo13* pCorProfilerInfo; + ICorProfilerInfo14* pCorProfilerInfo; Profiler(); virtual ~Profiler(); diff --git a/src/tests/run.py b/src/tests/run.py index 5e9f94a160459b..81c41560904ebf 100755 --- a/src/tests/run.py +++ b/src/tests/run.py @@ -1163,6 +1163,10 @@ def dir_has_nested_substrings(test_path, test_item): for index, item in enumerate(loc_split): if not append: test_path = os.path.join(starting_path, item) + # Ensure the joined path is correct. Avoid forming /Vector256/1/ for Vector256_1 + # where both Vector256 and Vector256_1 are valid dirs. + if not os.path.isdir(os.path.dirname(test_path)): + test_path = starting_path + "_" + item else: append = False test_path, size_of_largest_name_file = match_filename(starting_path + "_" + item) diff --git a/src/tests/tracing/eventactivityidcontrol/eventactivityidcontrol.csproj b/src/tests/tracing/eventactivityidcontrol/eventactivityidcontrol.csproj index d0d1c40bfe4635..737e8166c82c9c 100644 --- a/src/tests/tracing/eventactivityidcontrol/eventactivityidcontrol.csproj +++ b/src/tests/tracing/eventactivityidcontrol/eventactivityidcontrol.csproj @@ -2,6 +2,9 @@ Exe true + + true + true diff --git a/src/tests/tracing/eventcounter/eventcounter.csproj b/src/tests/tracing/eventcounter/eventcounter.csproj index 0b548a3d140b63..0659d4e5e8ba4c 100644 --- a/src/tests/tracing/eventcounter/eventcounter.csproj +++ b/src/tests/tracing/eventcounter/eventcounter.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventcounter/gh53564.csproj b/src/tests/tracing/eventcounter/gh53564.csproj index 25b71bcfbf9ad1..461e257260f156 100644 --- a/src/tests/tracing/eventcounter/gh53564.csproj +++ b/src/tests/tracing/eventcounter/gh53564.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventcounter/incrementingeventcounter.csproj b/src/tests/tracing/eventcounter/incrementingeventcounter.csproj index 421ba01d16384c..4c7e8c35777a03 100644 --- a/src/tests/tracing/eventcounter/incrementingeventcounter.csproj +++ b/src/tests/tracing/eventcounter/incrementingeventcounter.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventcounter/incrementingpollingcounter.csproj b/src/tests/tracing/eventcounter/incrementingpollingcounter.csproj index 88614b0bb5d4aa..78b4c466b1381e 100644 --- a/src/tests/tracing/eventcounter/incrementingpollingcounter.csproj +++ b/src/tests/tracing/eventcounter/incrementingpollingcounter.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventcounter/pollingcounter.csproj b/src/tests/tracing/eventcounter/pollingcounter.csproj index 648bdccd7a5c7e..aa5bbc6055c9db 100644 --- a/src/tests/tracing/eventcounter/pollingcounter.csproj +++ b/src/tests/tracing/eventcounter/pollingcounter.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventcounter/regression-25709.csproj b/src/tests/tracing/eventcounter/regression-25709.csproj index d35dcf8d011452..bf258349ee0d6c 100644 --- a/src/tests/tracing/eventcounter/regression-25709.csproj +++ b/src/tests/tracing/eventcounter/regression-25709.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventcounter/regression-46938.csproj b/src/tests/tracing/eventcounter/regression-46938.csproj index 0fa47827d4cbdb..a9efeaf30d8bac 100644 --- a/src/tests/tracing/eventcounter/regression-46938.csproj +++ b/src/tests/tracing/eventcounter/regression-46938.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventcounter/runtimecounters.csproj b/src/tests/tracing/eventcounter/runtimecounters.csproj index 44abb2b5f37e67..0bd33174144b01 100644 --- a/src/tests/tracing/eventcounter/runtimecounters.csproj +++ b/src/tests/tracing/eventcounter/runtimecounters.csproj @@ -2,8 +2,8 @@ Exe true + true - true true diff --git a/src/tests/tracing/eventlistener/EventListenerThreadPool.csproj b/src/tests/tracing/eventlistener/EventListenerThreadPool.csproj index 4072b985020ce0..203b64d1a3101c 100644 --- a/src/tests/tracing/eventlistener/EventListenerThreadPool.csproj +++ b/src/tests/tracing/eventlistener/EventListenerThreadPool.csproj @@ -3,6 +3,9 @@ Exe true true + + true + true diff --git a/src/tests/tracing/eventlistener/eventlistener.csproj b/src/tests/tracing/eventlistener/eventlistener.csproj index 2f015b971e28b7..b1c44c2bfdc795 100644 --- a/src/tests/tracing/eventlistener/eventlistener.csproj +++ b/src/tests/tracing/eventlistener/eventlistener.csproj @@ -2,6 +2,9 @@ Exe true + + true + true diff --git a/src/tests/tracing/eventlistener/eventlistenerenabledisable.csproj b/src/tests/tracing/eventlistener/eventlistenerenabledisable.csproj index c4b65fcb339259..7ad98f416ce2e0 100644 --- a/src/tests/tracing/eventlistener/eventlistenerenabledisable.csproj +++ b/src/tests/tracing/eventlistener/eventlistenerenabledisable.csproj @@ -2,6 +2,9 @@ Exe true + + true + true diff --git a/src/tests/tracing/eventpipe/bigevent/bigevent.csproj b/src/tests/tracing/eventpipe/bigevent/bigevent.csproj index 1dcce61a3ef450..afca48eb516982 100644 --- a/src/tests/tracing/eventpipe/bigevent/bigevent.csproj +++ b/src/tests/tracing/eventpipe/bigevent/bigevent.csproj @@ -3,11 +3,10 @@ .NETCoreApp exe true + + true true true - - true - true diff --git a/src/tests/tracing/eventpipe/buffersize/buffersize.csproj b/src/tests/tracing/eventpipe/buffersize/buffersize.csproj index 8a67dfd70a8fc5..18068018243a0b 100644 --- a/src/tests/tracing/eventpipe/buffersize/buffersize.csproj +++ b/src/tests/tracing/eventpipe/buffersize/buffersize.csproj @@ -4,8 +4,9 @@ exe true true - true + true + true diff --git a/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj b/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj index c91a39690ebe2c..6089c06c5b0f2c 100644 --- a/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj +++ b/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj @@ -2,7 +2,9 @@ exe true + true + true diff --git a/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj index ed69ca0a75e6de..c20471b62209ef 100644 --- a/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj +++ b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj @@ -4,9 +4,9 @@ exe true true - true - + true + true diff --git a/src/tests/tracing/eventpipe/enabledisable/enabledisable.csproj b/src/tests/tracing/eventpipe/enabledisable/enabledisable.csproj index 5ff333fc67ae1d..961ee4ce17c9b5 100644 --- a/src/tests/tracing/eventpipe/enabledisable/enabledisable.csproj +++ b/src/tests/tracing/eventpipe/enabledisable/enabledisable.csproj @@ -4,9 +4,10 @@ exe true $(DefineConstants);DIAGNOSTICS_RUNTIME - true true + true + true diff --git a/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj b/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj index 1900d4e9375cfa..afca48eb516982 100644 --- a/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj +++ b/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj @@ -3,8 +3,9 @@ .NETCoreApp exe true - + true + true true diff --git a/src/tests/tracing/eventpipe/eventsvalidation/ExceptionThrown_V1.csproj b/src/tests/tracing/eventpipe/eventsvalidation/ExceptionThrown_V1.csproj index 7a1fe2297b05bd..722bf260cd64b2 100644 --- a/src/tests/tracing/eventpipe/eventsvalidation/ExceptionThrown_V1.csproj +++ b/src/tests/tracing/eventpipe/eventsvalidation/ExceptionThrown_V1.csproj @@ -5,11 +5,9 @@ true 1 true - true - + true + true diff --git a/src/tests/tracing/eventpipe/eventsvalidation/GCEvents.csproj b/src/tests/tracing/eventpipe/eventsvalidation/GCEvents.csproj index 9bb9ce074fe197..92eb223634307f 100644 --- a/src/tests/tracing/eventpipe/eventsvalidation/GCEvents.csproj +++ b/src/tests/tracing/eventpipe/eventsvalidation/GCEvents.csproj @@ -5,8 +5,9 @@ true 1 true - true + true + true diff --git a/src/tests/tracing/eventpipe/eventsvalidation/GCFinalizers.csproj b/src/tests/tracing/eventpipe/eventsvalidation/GCFinalizers.csproj index c80d9a0a60292a..794a4794d15262 100644 --- a/src/tests/tracing/eventpipe/eventsvalidation/GCFinalizers.csproj +++ b/src/tests/tracing/eventpipe/eventsvalidation/GCFinalizers.csproj @@ -5,8 +5,9 @@ true 1 true - true + true + true diff --git a/src/tests/tracing/eventpipe/gcdump/gcdump.csproj b/src/tests/tracing/eventpipe/gcdump/gcdump.csproj index 3cbcf3577bacc7..18068018243a0b 100644 --- a/src/tests/tracing/eventpipe/gcdump/gcdump.csproj +++ b/src/tests/tracing/eventpipe/gcdump/gcdump.csproj @@ -4,8 +4,9 @@ exe true true - + true + true diff --git a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.csproj b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.csproj index ed69ca0a75e6de..c20471b62209ef 100644 --- a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.csproj +++ b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.csproj @@ -4,9 +4,9 @@ exe true true - true - + true + true diff --git a/src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj b/src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj index 17320dc68377f7..4cf5a34c0c141c 100644 --- a/src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj +++ b/src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj @@ -4,10 +4,10 @@ exe true true + + true true true - - true diff --git a/src/tests/tracing/eventpipe/processinfo/processinfo.csproj b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj index 2760fd02c27238..d4947c794dcebe 100644 --- a/src/tests/tracing/eventpipe/processinfo/processinfo.csproj +++ b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj @@ -4,6 +4,8 @@ exe true true + + true true + true true true + true diff --git a/src/tests/tracing/eventpipe/reverse/reverse.csproj b/src/tests/tracing/eventpipe/reverse/reverse.csproj index ed69ca0a75e6de..a2fca0e2c1cca0 100644 --- a/src/tests/tracing/eventpipe/reverse/reverse.csproj +++ b/src/tests/tracing/eventpipe/reverse/reverse.csproj @@ -5,8 +5,9 @@ true true true - + true + true diff --git a/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj b/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj index 55e8a2a220c229..c20471b62209ef 100644 --- a/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj +++ b/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj @@ -4,9 +4,9 @@ exe true true - true - + true + true diff --git a/src/tests/tracing/eventpipe/rundownvalidation/rundownvalidation.csproj b/src/tests/tracing/eventpipe/rundownvalidation/rundownvalidation.csproj index 22dd698007ed9a..65cc47f3ac80ae 100644 --- a/src/tests/tracing/eventpipe/rundownvalidation/rundownvalidation.csproj +++ b/src/tests/tracing/eventpipe/rundownvalidation/rundownvalidation.csproj @@ -3,15 +3,14 @@ .NETCoreApp exe true + + true true true - - true - true diff --git a/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj b/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj index 34d588f3c2dd1b..b5ed1d9774bfe9 100644 --- a/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj +++ b/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj @@ -4,8 +4,9 @@ exe true true - true + true + true true true diff --git a/src/tests/tracing/runtimeeventsource/nativeruntimeeventsource.csproj b/src/tests/tracing/runtimeeventsource/nativeruntimeeventsource.csproj index 11c39d9a439b55..aafdc6ee3207ea 100644 --- a/src/tests/tracing/runtimeeventsource/nativeruntimeeventsource.csproj +++ b/src/tests/tracing/runtimeeventsource/nativeruntimeeventsource.csproj @@ -2,7 +2,9 @@ Exe true + true + true true diff --git a/src/tests/tracing/runtimeeventsource/runtimeeventsource.csproj b/src/tests/tracing/runtimeeventsource/runtimeeventsource.csproj index 3b0d2f0f0329f2..1a5278c477f034 100644 --- a/src/tests/tracing/runtimeeventsource/runtimeeventsource.csproj +++ b/src/tests/tracing/runtimeeventsource/runtimeeventsource.csproj @@ -2,6 +2,9 @@ Exe true + + true + true true true diff --git a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs index 5b946d199ce3cb..fe140b82d23d52 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs @@ -138,8 +138,8 @@ private static void NewKnownStack (Dictionary> knownStacks return; } - if (knownStacks.ContainsKey (newOffset)) { - knownStacks[newOffset] = MergeStack (knownStacks[newOffset], newStack); + if (knownStacks.TryGetValue (newOffset, out Stack? value)) { + knownStacks[newOffset] = MergeStack (value, newStack); } else { knownStacks.Add (newOffset, new Stack (newStack.Reverse ())); } @@ -292,12 +292,12 @@ protected virtual void Scan (MethodIL methodIL, ref InterproceduralState interpr foreach (Instruction operation in methodIL.Instructions) { int curBasicBlock = blockIterator.MoveNext (operation); - if (knownStacks.ContainsKey (operation.Offset)) { + if (knownStacks.TryGetValue (operation.Offset, out Stack? knownValue)) { if (currentStack == null) { // The stack copy constructor reverses the stack - currentStack = new Stack (knownStacks[operation.Offset].Reverse ()); + currentStack = new Stack (knownValue.Reverse ()); } else { - currentStack = MergeStack (currentStack, knownStacks[operation.Offset]); + currentStack = MergeStack (currentStack, knownValue); } } diff --git a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs index 0b357b56330f5c..28780d11239158 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs @@ -303,12 +303,14 @@ public static bool HandleCall ( if (staticType is null) { // We don't know anything about the type GetType was called on. Track this as a usual result of a method call without any annotations AddReturnValue (context.Annotations.FlowAnnotations.GetMethodReturnValue (calledMethodDefinition)); - } else if (staticType.IsSealed || staticType.IsTypeOf ("System", "Delegate")) { + } else if (staticType.IsSealed || staticType.IsTypeOf ("System", "Delegate") || staticType.IsTypeOf ("System", "Array")) { // We can treat this one the same as if it was a typeof() expression // We can allow Object.GetType to be modeled as System.Delegate because we keep all methods // on delegates anyway so reflection on something this approximation would miss is actually safe. + // We can also treat all arrays as "sealed" since it's not legal to derive from Array type (even though it is not sealed itself) + // We ignore the fact that the type can be annotated (see below for handling of annotated types) // This means the annotations (if any) won't be applied - instead we rely on the exact knowledge // of the type. So for example even if the type is annotated with PublicMethods diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs index deb54564a8d0a5..5a5fca7df33753 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs @@ -9,5 +9,7 @@ namespace Mono.Linker.Tests.Cases.Expectations.Assertions public class SkipKeptItemsValidationAttribute : BaseExpectedLinkedBehaviorAttribute { public SkipKeptItemsValidationAttribute () { } + + public Tool By { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs index 5029df77743ce7..baea4bfcbf43d9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs @@ -18,7 +18,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "These tests are not targeted at AOT scenarios")] @@ -58,8 +57,8 @@ static void ReflectionReadOnly () typeof (AnnotatedField).GetField ("_annotatedField").GetValue (null); } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (AnnotatedField))] static void DynamicDependency () { @@ -71,8 +70,8 @@ static void DynamicDependencySuppressedByRUC () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (nameof (_annotatedField), typeof (AnnotatedField))] static void DynamicDependencyByName () { @@ -133,7 +132,7 @@ static void PotentialWriteAccess (ref Type type) } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2110", nameof (AnnotatedField._annotatedField), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2110", nameof (AnnotatedField._annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdToken () { Expression a = () => PotentialWriteAccess (ref _annotatedField); @@ -189,8 +188,8 @@ static void AnnotatedAttributeConstructor () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodParameters))] static void DynamicDependency () { @@ -202,8 +201,8 @@ static void DynamicDependencySuppressedByRUC () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (nameof (MethodWithSingleAnnotatedParameter), typeof (AnnotatedMethodParameters))] static void DynamicDependencyByName () { @@ -221,8 +220,8 @@ static void DynamicallyAccessedMembersSuppressedByRUC () typeof (AnnotatedMethodParameters).RequiresPublicMethods (); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void Ldftn () { var _ = new Action (AnnotatedMethodParameters.MethodWithSingleAnnotatedParameter); @@ -233,8 +232,8 @@ interface IWithAnnotatedMethod public void AnnotatedMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void Ldvirtftn () { IWithAnnotatedMethod instance = null; @@ -264,7 +263,7 @@ static void DynamicallyAccessedMembersAll2 () } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2067", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Analyzer)] static void LdToken () { @@ -325,8 +324,8 @@ static void ReflectionOnVirtualSuppressedByRUC () typeof (AnnotatedMethodReturnValue).GetMethod (nameof (VirtualMethodWithAnnotatedReturnValue)).Invoke (null, null); } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodReturnValue))] static void DynamicDependency () { @@ -348,8 +347,8 @@ static void DynamicDependencyByNameOnInstance () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (nameof (VirtualMethodWithAnnotatedReturnValue), typeof (AnnotatedMethodReturnValue))] static void DynamicDependencyByNameOnVirtual () { @@ -377,8 +376,8 @@ static void LdftnOnInstance () var _ = new Func ((new AnnotatedMethodReturnValue ()).InstanceMethodWithAnnotatedReturnValue); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdftnOnVirtual () { var _ = new Func ((new AnnotatedMethodReturnValue ()).VirtualMethodWithAnnotatedReturnValue); @@ -390,7 +389,7 @@ static void LdTokenOnStatic () } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdTokenOnVirtual () { Expression> _ = (a) => a.VirtualMethodWithAnnotatedReturnValue (); @@ -433,7 +432,7 @@ class AnnotatedProperty public virtual Type VirtualProperty4WithAnnotation { get => null; set { value.ToString (); } } public static Type Property5WithAnnotationOnMembers { - [ExpectedWarning ("IL2078", nameof (Property5WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2078", nameof (Property5WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] get; [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] @@ -501,14 +500,14 @@ static void AnnotatedAttributeProperty () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (AnnotatedProperty))] static void DynamicDependency () { @@ -592,14 +591,14 @@ static void DynamicallyAccessedMembersAll2 () } // Analyzer doesn't produce this warning https://github.com/dotnet/linker/issues/2628 - [ExpectedWarning ("IL2110", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2110", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void DynamicallyAccessedFields () { typeof (AnnotatedProperty).RequiresNonPublicFields (); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdToken () { Expression> _ = () => Property1WithAnnotation; @@ -697,8 +696,8 @@ public static void GenericMethodWithAnnotation ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (GenericWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (GenericWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static void GenericTypeWithStaticMethodViaLdftn () { var _ = new Action (GenericWithAnnotatedMethod.AnnotatedMethod); @@ -716,8 +715,8 @@ public static void GenericMethodWithAnnotationDirectCall () GenericMethodWithAnnotation (typeof (TestType)); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static void GenericMethodWithAnnotationViaLdftn () { var _ = new Action (GenericMethodWithAnnotation); @@ -744,7 +743,7 @@ static void DynamicallyAccessedMembersAll2 () } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdToken () { // Note that this should warn even though the code looks "Correct" diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs index bd89abc447dce7..b7c71da382b731 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs @@ -179,7 +179,7 @@ static void TwoOutRefs ( } [Kept] - // https://github.com/dotnet/linker/issues/2874 + // https://github.com/dotnet/runtime/issues/85464 [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static void Test () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs index 722720553ad3e0..9e382e40a380c1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs @@ -10,8 +10,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] - // This test tries to hit a case where the entire assemly is preserved (via descriptor, NOT action) + // This test tries to hit a case where the entire assembly is preserved (via descriptor, NOT action) // meaning we will go and mark all types and members in it. // At the same time there's a compiler generated method (local function) which is called from // a branch which will be removed due to constant propagation. @@ -44,7 +43,9 @@ public static void WithLocalFunctionInner () } // Analyzer doesn't implement constant propagation and branch removal, so it reaches this code - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer)] + // NativeAOT behavioral difference: + // https://github.com/dotnet/runtime/issues/85161 + [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer | Tool.NativeAot)] void LocalWithWarning () { // No warning @@ -64,7 +65,9 @@ public static void WithLocalFunction () } // Analyzer doesn't implement constant propagation and branch removal, so it reaches this code - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer)] + // NativeAOT behavioral difference: + // https://github.com/dotnet/runtime/issues/85161 + [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer | Tool.NativeAot)] void LocalWithWarning () { Requires (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs index 594a1926eece37..343edfcc63c46f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs @@ -11,8 +11,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] - [KeptAttributeAttribute (typeof (IgnoreTestCaseAttribute), By = Tool.Trimmer)] + [ExpectedNoWarnings] + [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Applying DAM PublicMethods on an array will mark Array.CreateInstance which has RDC on it")] + [KeptAttributeAttribute(typeof(UnconditionalSuppressMessageAttribute))] public class ComplexTypeHandling { public static void Main () @@ -93,7 +94,7 @@ static void RequirePublicMethodsOnArrayOfGenericParameter () _ = new RequirePublicMethodsGeneric (); } - [Kept] + [Kept (By = Tool.Trimmer)] // NativeAOT doesn't preserve array element types just due to the usage of the array type sealed class ArrayGetTypeFromMethodParamElement { // This method should not be marked, instead Array.* should be marked @@ -112,7 +113,7 @@ static void TestArrayGetTypeFromMethodParam () TestArrayGetTypeFromMethodParamHelper (null); } - [Kept] + [Kept (By = Tool.Trimmer)] // NativeAOT doesn't preserve array element types just due to the usage of the array type sealed class ArrayGetTypeFromFieldElement { // This method should not be marked, instead Array.* should be marked @@ -141,11 +142,11 @@ static void TestArrayTypeGetType () RequirePublicMethods (Type.GetType ("Mono.Linker.Tests.Cases.DataFlow.ComplexTypeHandling+ArrayTypeGetTypeElement[]")); } - // Technically there's no reason to mark this type since it's only used as an array element type and CreateInstance - // doesn't work on arrays, but the currently implementation will preserve it anyway due to how it processes + // Trimmer: Technically there's no reason to mark this type since it's only used as an array element type and CreateInstance + // doesn't work on arrays, but the current implementation will preserve it anyway due to how it processes // string -> Type resolution. This will only impact code which would have failed at runtime, so very unlikely to // actually occur in real apps (and even if it does happen, it just increases size, doesn't break behavior). - [Kept] + [Kept (By = Tool.Trimmer)] // NativeAOT doesn't preserve array element types just due to the usage of the array type class ArrayCreateInstanceByNameElement { public ArrayCreateInstanceByNameElement () @@ -154,12 +155,13 @@ public ArrayCreateInstanceByNameElement () } [Kept] + [ExpectedWarning ("IL2032", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/82447 static void TestArrayCreateInstanceByName () { Activator.CreateInstance ("test", "Mono.Linker.Tests.Cases.DataFlow.ComplexTypeHandling+ArrayCreateInstanceByNameElement[]"); } - [Kept] + [Kept (By = Tool.Trimmer)] // NativeAOT doesn't preserve array element types just due to the usage of the array type class ArrayInAttributeParamElement { // This method should not be marked, instead Array.* should be marked @@ -169,10 +171,17 @@ public void PublicMethod () { } [Kept] [KeptAttributeAttribute (typeof (RequiresPublicMethodAttribute))] [RequiresPublicMethod (typeof (ArrayInAttributeParamElement[]))] - static void TestArrayInAttributeParameter () + static void TestArrayInAttributeParameterImpl () { } + [Kept] + static void TestArrayInAttributeParameter() + { + // Have to access the method through reflection, otherwise NativeAOT will remove all attributes on it + // since they're not accessible. + typeof (ComplexTypeHandling).GetMethod (nameof (TestArrayInAttributeParameterImpl), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).Invoke (null, new object[] { }); + } [Kept] private static void RequirePublicMethods ( diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs index 22584259fcdb7f..3bc10b9aa5f919 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs @@ -12,7 +12,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [ExpectedNoWarnings] [SkipKeptItemsValidation] class ConstructedTypesDataFlow diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs index b8ef7d98ea7e0e..579a775301f5bd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs @@ -7,7 +7,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "These tests are not targetted at AOT scenarios")] @@ -85,7 +84,7 @@ static void TestUnknownInput (Type inputType) } // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestWithUnknownTypeArray (Type[] types) { typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types); @@ -100,7 +99,7 @@ static void TestWithArrayUnknownIndexSet (int indexToSet) } // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestWithArrayUnknownLengthSet (int arrayLen) { Type[] types = new Type[arrayLen]; @@ -424,14 +423,14 @@ static void TestWithEmptyInputNoSuchMethod_GetRuntimeMethod (Type unknownType) } // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestUnknownMethod (MethodInfo mi) { mi.MakeGenericMethod (typeof (TestType)); } // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestUnknownMethodButNoTypeArguments (MethodInfo mi) { // Technically trimming could figure this out, but it's not worth the complexity - such call will always fail at runtime. @@ -542,7 +541,7 @@ static void TestNoValueTypeArgument () } // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestWithUnknownTypeArray (Type[] types) { typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static) @@ -559,7 +558,7 @@ static void TestWithArrayUnknownIndexSet (int indexToSet) } // https://github.com/dotnet/linker/issues/2158 - analyzer doesn't work the same as ILLink, it simply doesn't handle refs - [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestWithArrayUnknownIndexSetByRef (int indexToSet) { Type[] types = new Type[1]; @@ -571,7 +570,7 @@ static void TestWithArrayUnknownIndexSetByRef (int indexToSet) } // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestWithArrayUnknownLengthSet (int arrayLen) { Type[] types = new Type[arrayLen]; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs index 9d3bcbf5119953..7bcdeb59729c38 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs @@ -11,69 +11,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] - [KeptAttributeAttribute (typeof (IgnoreTestCaseAttribute), By = Tool.Trimmer)] [SetupCompileArgument ("/optimize+")] [ExpectedNoWarnings] public class MemberTypes { - // Some of the types below declare delegates and will mark all members on them, this includes the Delegate .ctor(object, string) which has RUC and other members - [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] - // Some of the types below declare delegates and will mark all members on them, this includes the Delegate .ctor(Type, string) which has DAM annotations and other members - [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] - [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = Tool.Trimmer)] + // This is an easy way to suppress all trim related warnings in the Main method + // This test is about marking, not diagnostics and this Main will produce several warnings due to it accssing + // some problematic APIs (Delegate.Create for example) via reflection. + [RequiresUnreferencedCode("test")] + [KeptAttributeAttribute(typeof(RequiresUnreferencedCodeAttribute))] public static void Main () { RequirePublicParameterlessConstructor (typeof (PublicParameterlessConstructorType)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs index 4ac5f0edfe274c..716662e19e88d1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs @@ -13,8 +13,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] - [KeptAttributeAttribute (typeof (IgnoreTestCaseAttribute), By = Tool.Trimmer)] [ExpectedNoWarnings] [SetupCompileBefore ("base.dll", new[] { "Dependencies/MemberTypesAllBaseTypeAssembly.cs" })] @@ -67,7 +65,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow [KeptTypeInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType/PrivateNestedType")] [KeptMemberInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType/PrivateNestedType", new string[] { "PrivateMethod()" })] - [KeptMember (".ctor()")] + // https://github.com/dotnet/runtime/issues/78752 + [KeptMember (".ctor()", By = Tool.Trimmer)] public class MemberTypesAllOnCopyAssembly { public static void Main () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs index 207152b82030d3..b4ca654728bff1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs @@ -11,7 +11,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] class MethodByRefParameterDataFlow @@ -202,11 +201,11 @@ static class LocalMethodsAndLambdas [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] static ref Type GetTypeRefWithMethodsAndFields () { throw null; } - [ExpectedWarning ("IL2067", "t", "InnerMethodWithDam")] - [ExpectedWarning ("IL2067", "tWithMethodsAndFields", "InnerMethodWithDam")] + [ExpectedWarning ("IL2067", "'t'", "InnerMethodWithDam")] + [ExpectedWarning ("IL2067", "'tWithMethodsAndFields'", "InnerMethodWithDam")] [ExpectedWarning ("IL2072", nameof (GetTypeRefWithoutAnnotations), "InnerMethodWithDam")] [ExpectedWarning ("IL2068", nameof (GetTypeRefWithMethodsAndFields), "InnerMethodWithDam")] - static void MethodWithLocaMethodWithDam (Type t, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type tWithMethods, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] Type tWithMethodsAndFields) + static void MethodWithLocalMethodWithDam (Type t, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type tWithMethods, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] Type tWithMethodsAndFields) { // 2067 InnerMethodWithDam (ref t); @@ -233,7 +232,7 @@ void InnerMethodWithDam ([DynamicallyAccessedMembers (DynamicallyAccessedMemberT public static void Test () { - MethodWithLocaMethodWithDam (null, null, null); + MethodWithLocalMethodWithDam (null, null, null); } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs index d81811826260dd..348df96e99b076 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs @@ -10,8 +10,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] - [KeptAttributeAttribute (typeof (IgnoreTestCaseAttribute), By = Tool.Trimmer)] [ExpectedNoWarnings] [KeptPrivateImplementationDetails ("ThrowSwitchExpressionException")] [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))] @@ -301,7 +299,7 @@ static void MakeGenericTypeWithUnknownValue (object[] maybetypes) [Kept] // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2075", "GetFields", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2075", "GetFields", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void MakeGenericTypeWithKnowAndUnknownArray (Type[] unknownTypes = null, int p = 0) { Type[] types = p switch { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs index 1d8509978f1b19..1c3713e274b62b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs @@ -9,7 +9,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] // Note: this test's goal is to validate that the product correctly reports unrecognized patterns // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] @@ -273,7 +272,7 @@ public void TestPropertyWithDifferentBackingFields () // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 [ExpectedWarning ("IL2042", "Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithDifferentBackingFields", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get", "Type", @@ -282,7 +281,7 @@ public void TestPropertyWithDifferentBackingFields () Type PropertyWithDifferentBackingFields { [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] get { return PropertyWithDifferentBackingFields_GetterField; } @@ -300,7 +299,7 @@ public void TestPropertyWithExistingAttributes () // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 [ExpectedWarning ("IL2056", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes_Field", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] [CompilerGenerated] Type PropertyWithExistingAttributes_Field; @@ -311,13 +310,13 @@ public void TestPropertyWithExistingAttributes () Type PropertyWithExistingAttributes { // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] get { return PropertyWithExistingAttributes_Field; } // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] set { PropertyWithExistingAttributes_Field = value; } } @@ -338,7 +337,7 @@ public void TestPropertyWithConflictingAttributes () // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 [ExpectedWarning ("IL2056", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes_Field", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] [CompilerGenerated] Type PropertyWithConflictingAttributes_Field; @@ -349,13 +348,13 @@ public void TestPropertyWithConflictingAttributes () Type PropertyWithConflictingAttributes { // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.get", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] get { return PropertyWithConflictingAttributes_Field; } // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.set", - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] set { PropertyWithConflictingAttributes_Field = value; } } @@ -399,7 +398,7 @@ public void TestPropertyWithIndexerWithMatchingAnnotations ([DynamicallyAccessed } // Trimmer and analyzer handle formatting of indexers differently. - [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".Item.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".this[Int32].set", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)")] [LogDoesNotContain ("'Value passed to parameter 'index' of method 'Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithIndexer.Item.set'")] @@ -418,7 +417,7 @@ public class PropertyWithIndexer [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] public Type this[int index] { // Trimmer and analyzer handle formatting of indexers differently. - [ExpectedWarning ("IL2063", nameof (PropertyWithIndexer) + ".Item.get", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2063", nameof (PropertyWithIndexer) + ".Item.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2063", nameof (PropertyWithIndexer) + ".this[Int32].get", ProducedBy = Tool.Analyzer)] get => Property_Field[index]; set => Property_Field[index] = value; @@ -483,7 +482,7 @@ class WriteToGetOnlyProperty // Analyzer doesn't warn about compiler-generated backing field of property: https://github.com/dotnet/linker/issues/2731 [ExpectedWarning ("IL2074", nameof (WriteToGetOnlyProperty), nameof (GetUnknownType), - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] public WriteToGetOnlyProperty () { GetOnlyProperty = GetUnknownType (); @@ -551,9 +550,9 @@ class WriteCapturedGetOnlyProperty // Analyzer doesn't warn about compiler-generated backing field of property: https://github.com/dotnet/linker/issues/2731 [ExpectedWarning ("IL2074", nameof (WriteCapturedGetOnlyProperty), nameof (GetUnknownType), - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2074", nameof (WriteCapturedGetOnlyProperty), nameof (GetTypeWithPublicConstructors), - ProducedBy = Tool.Trimmer)] + ProducedBy = Tool.Trimmer | Tool.NativeAot)] public WriteCapturedGetOnlyProperty () { GetOnlyProperty = GetUnknownType () ?? GetTypeWithPublicConstructors (); @@ -666,14 +665,14 @@ Type this[Index idx] { } [ExpectedWarning ("IL2072", "this[Index].get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestRead (ExplicitIndexerAccess instance = null) { instance[new Index (1)].RequiresAll (); } [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "this[Index].set", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestWrite (ExplicitIndexerAccess instance = null) { instance[^1] = GetTypeWithPublicConstructors (); @@ -697,21 +696,21 @@ Type this[int idx] { int Length => throw new NotImplementedException (); [ExpectedWarning ("IL2072", "this[Int32].get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestRead (ImplicitIndexerAccess instance = null) { instance[new Index (1)].RequiresAll (); } [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "this[Int32].set", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestWrite (ImplicitIndexerAccess instance = null) { instance[^1] = GetTypeWithPublicConstructors (); } [ExpectedWarning ("IL2072", nameof (GetUnknownType), "this[Int32].set", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetUnknownType), "Item.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), "Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TestNullCoalescingAssignment (ImplicitIndexerAccess instance = null) { instance[new Index (1)] ??= GetUnknownType (); @@ -736,7 +735,7 @@ int this[[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicField } [ExpectedWarning ("IL2067", "this[Type].get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2067", "Item.get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void ParamDoesNotMeetRequirements (Type t) { var x = new IndexWithTypeWithDam (); @@ -750,7 +749,7 @@ static void ParamDoesMeetRequirements ([DynamicallyAccessedMembers (DynamicallyA } [ExpectedWarning ("IL2087", "this[Type].get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2087", "Item.get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2087", "Item.get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TypeParamDoesNotMeetRequirements () { var x = new IndexWithTypeWithDam (); @@ -791,7 +790,7 @@ Type this[[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFiel static Type fieldWithMethods; [ExpectedWarning ("IL2067", "this[Type].get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2067", "Item.get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void ParamDoesNotMeetRequirements (Type t) { var x = new IndexWithTypeWithDam (); @@ -805,7 +804,7 @@ static void ParamDoesMeetRequirements ([DynamicallyAccessedMembers (DynamicallyA } [ExpectedWarning ("IL2087", "this[Type].get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2087", "Item.get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2087", "Item.get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void TypeParamDoesNotMeetRequirements () { var x = new IndexWithTypeWithDam (); @@ -828,7 +827,7 @@ static void KnownTypeDoesMeetRequirements () } [ExpectedWarning ("IL2067", "this[Type].set", nameof (t), "idx", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.set", nameof (t), "idx", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2067", "Item.set", nameof (t), "idx", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void ValueMeetsRequirementsIndexDoesNot (Type t) { var x = new IndexWithTypeWithDam (); @@ -836,7 +835,7 @@ static void ValueMeetsRequirementsIndexDoesNot (Type t) } [ExpectedWarning ("IL2067", "this[Type].set", nameof (tUnannotated), "value", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.set", nameof (tUnannotated), "value", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2067", "Item.set", nameof (tUnannotated), "value", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void ValueDoesNotMeetRequirementsIndexDoes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type t, Type tUnannotated) { var x = new IndexWithTypeWithDam (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs index 9db1b0e571b858..fdedee546badda 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs @@ -11,17 +11,16 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] class RefFieldDataFlow { [Kept] - // Bug for the IL2069's here: https://github.com/dotnet/linker/issues/2874 - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer)] + // Bug for the IL2069's here: https://github.com/dotnet/runtime/issues/85464 + [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static void Main () { RefFieldWithMethods withMethods = new (ref fieldWithMethods); @@ -100,11 +99,11 @@ static void AssignRefToLocals< tmf = typeof (TF); // This is a hole that doesn't warn but assigns a misannotated value to target.T } - [ExpectedWarning ("IL2089", "RefFieldWithMethods", "T", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2089", "RefFieldWithMethods", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void AssignRefLocals< T, [DAM (DAMT.PublicMethods)] TM, @@ -178,13 +177,13 @@ static void AssignParameters (scoped RefFieldWithMethods target, [ExpectedWarning ("IL2069", "RefFieldWithMethods.T", "paramWithFields")] [ExpectedWarning ("IL2077", "paramWithMethodsAndFields", "RefFieldWithMethods.T")] // ILLink doesn't recognize ldind.ref - // https://github.com/dotnet/linker/issues/2943 + // https://github.com/dotnet/runtime/issues/85465 // IL2064's are bugs - shouldn't be unknown values - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2069", "RefFieldWithMethods.T", "param", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2069", "RefFieldWithMethods.T", "paramWithFields", ProducedBy = Tool.Analyzer)] static void AssignRefParameters< @@ -240,12 +239,12 @@ static void AssignFields (RefFieldWithMethods target, UnannotatedField unannotat [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldUnannotated.T", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldWithFields.T", ProducedBy = Tool.Analyzer)] // IL2064's are bugs - shouldn't be unknown values - // https://github.com/dotnet/linker/issues/2943 - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = unannotated.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withMethods.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withFields.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withMethodsAndFields.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withMethodsAndFields.T; + // https://github.com/dotnet/runtime/issues/85465 + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = unannotated.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethods.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withFields.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethodsAndFields.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethodsAndFields.T; static void AssignRefFields ( RefFieldWithMethods target, RefFieldUnannotated unannotated, @@ -272,11 +271,11 @@ static void AssignRefFields ( [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefUnannotated", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefWithFields", ProducedBy = Tool.Analyzer)] // IL2064's are bugs - shouldn't be unknown values - // https://github.com/dotnet/linker/issues/2943 - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; + // https://github.com/dotnet/runtime/issues/85465 + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; static void AssignRefReturns< T, [DAM (DAMT.PublicMethods)] TM, @@ -362,16 +361,16 @@ static void AssignProperties (RefFieldWithMethods target, [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropWithFields.T")] // ref Type t = ref x.T; target.T = t; // IL2064's are bugs - shouldn't be unknown values - // https://github.com/dotnet/linker/issues/2943 - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = unannotated.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withMethods.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withFields.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withMethodsAndFieldswithMtho.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = withMethods.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer)] // target.T = t; + // https://github.com/dotnet/runtime/issues/85465 + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = unannotated.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethods.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withFields.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethodsAndFieldswithMtho.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethods.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; static void AssignRefProperties (RefFieldWithMethods target, RefPropUnannotated unannotated = null, RefPropWithMethods withMethods = null, diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs index 5aa1aece4f3133..2f922940a3d739 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs @@ -9,8 +9,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] - [KeptAttributeAttribute (typeof (IgnoreTestCaseAttribute), By = Tool.Trimmer)] + [ExpectedNoWarnings] public class StaticInterfaceMethodDataflow { [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs index 21a848df98b7c8..6213816a58a4d9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs @@ -12,7 +12,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] // Note: this test's goal is to validate that the product correctly reports unrecognized patterns // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs index 75db763733993e..da049f3ab4968d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs @@ -203,7 +203,7 @@ public static void Test () [KeptMember (".ctor()")] private abstract class AbstractMethods { - [Kept (By = Tool.Trimmer)] // NativeAOT test infra doesn't check reflection-only methods (without entry point) yet + [Kept] [DynamicDependency (nameof (TargetMethod))] public abstract void SourceAbstractViaReflection (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index c3116903d6167b..b793d36af76a0d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -12,6 +12,7 @@ namespace Mono.Linker.Tests.Cases.Reflection { [ExpectedNoWarnings] + [SkipKeptItemsValidation (By = Tool.NativeAot)] public class TypeHierarchyReflectionWarnings { public static void Main () @@ -236,10 +237,10 @@ class AnnotatedPublicEvents public delegate void MyEventHandler (object sender, int i); [Kept] - // We always keep event methods when an event is kept, so this generates warnings + // ILLink always keeps event methods when an event is kept, so this generates warnings // on the event itself (since an event access is considered to reference the annotated add method), // and on the add method (if it is accessed through reflection). - [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--")] + [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] public event MyEventHandler RUCEvent { @@ -273,6 +274,7 @@ class AnnotatedInterfaces : RequiredInterface [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] // This should produce a warning: https://github.com/dotnet/linker/issues/2161 + [ExpectedWarning("IL2112", "--RUC on AnnotatedInterfaces.UnusedMethod--", ProducedBy = Tool.NativeAot)] [RequiresUnreferencedCode ("--RUC on AnnotatedInterfaces.UnusedMethod--")] public void RUCMethod () { } } @@ -307,7 +309,7 @@ class DerivedFromAnnotatedPublicParameterlessConstructor : AnnotatedPublicParame [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--")] - [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [RequiresUnreferencedCode ("--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--")] public DerivedFromAnnotatedPublicParameterlessConstructor () { } @@ -618,13 +620,13 @@ public virtual void RUCVirtualMethod () { } [KeptBaseType (typeof (Base))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] [ExpectedWarning ("IL2113", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--")] - // https://github.com/dotnet/linker/issues/2815 - // [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Derived.RUCVirtualMethod--")] public class Derived : Base { [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--RUCOnVirtualMethodDerivedAnnotated.Derived.RUCVirtualMethod--")] + // https://github.com/dotnet/linker/issues/2815 + [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Derived.RUCVirtualMethod--", ProducedBy = Tool.NativeAot)] public virtual void RUCVirtualMethod () { } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs index 553ba49e6bb689..f58b051b4a3e96 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs @@ -10,7 +10,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] public class ReflectionAccessFromCompilerGeneratedCode @@ -25,8 +24,11 @@ public static void Main () class ReflectionAccessFromStateMachine { [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true)] @@ -37,6 +39,8 @@ static IEnumerable TestIterator () } [RequiresUnreferencedCode ("--TestIteratorWithRUC--")] + [RequiresAssemblyFiles ("--TestIteratorWithRUC--")] + [RequiresDynamicCode ("--TestIteratorWithRUC--")] static IEnumerable TestIteratorWithRUC () { typeof (TypeWithMethodWithRequires).RequiresAll (); @@ -44,8 +48,11 @@ static IEnumerable TestIteratorWithRUC () } [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true)] @@ -56,6 +63,8 @@ static async void TestAsync () } [RequiresUnreferencedCode ("--TestAsyncWithRUC--")] + [RequiresAssemblyFiles ("--TestAsyncWithRUC--")] + [RequiresDynamicCode ("--TestAsyncWithRUC--")] static async void TestAsyncWithRUC () { typeof (TypeWithMethodWithRequires).RequiresAll (); @@ -63,10 +72,14 @@ static async void TestAsyncWithRUC () } [ExpectedWarning ("IL2026", "--TestIteratorWithRUC--")] + [ExpectedWarning ("IL3002", "--TestIteratorWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestIteratorWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] [ExpectedWarning ("IL2026", "--TestAsyncWithRUC--")] + [ExpectedWarning ("IL3002", "--TestAsyncWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestAsyncWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void Test () { - TestIterator (); + TestIterator ().GetEnumerator ().MoveNext (); // Must actually une the enumerator, otherwise NativeAOT will trim the implementation TestIteratorWithRUC (); TestAsync (); TestAsyncWithRUC (); @@ -78,8 +91,11 @@ class ReflectionAccessFromLocalFunction static void TestLocalFunction () { [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations))] @@ -91,9 +107,13 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "--LocalFunction--")] + [ExpectedWarning ("IL3002", "--LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] static void TestLocalFunctionWithRUC () { [RequiresUnreferencedCode ("--LocalFunction--")] + [RequiresAssemblyFiles ("--LocalFunction--")] + [RequiresDynamicCode ("--LocalFunction--")] void LocalFunction () { typeof (TypeWithMethodWithRequires).RequiresAll (); @@ -102,6 +122,8 @@ void LocalFunction () } [RequiresUnreferencedCode ("--TestLocalFunctionInMethodWithRUC--")] + [RequiresAssemblyFiles ("--TestLocalFunctionInMethodWithRUC--")] + [RequiresDynamicCode ("--TestLocalFunctionInMethodWithRUC--")] static void TestLocalFunctionInMethodWithRUC () { void LocalFunction () @@ -112,6 +134,8 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRUC--")] + [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void Test () { TestLocalFunction (); @@ -126,8 +150,11 @@ static void TestLambda () { var lambda = [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations))] @@ -138,10 +165,14 @@ static void TestLambda () } [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] static void TestLambdaWithRUC () { var lambda = [RequiresUnreferencedCode ("--TestLambdaInMethodWithRUC--")] + [RequiresAssemblyFiles ("--TestLambdaInMethodWithRUC--")] + [RequiresDynamicCode ("--TestLambdaInMethodWithRUC--")] () => { typeof (TypeWithMethodWithRequires).RequiresAll (); }; @@ -149,6 +180,8 @@ static void TestLambdaWithRUC () } [RequiresUnreferencedCode ("--TestLambdaInMethodWithRUC--")] + [RequiresAssemblyFiles ("--TestLambdaInMethodWithRUC--")] + [RequiresDynamicCode ("--TestLambdaInMethodWithRUC--")] static void TestLambdaInMethodWithRUC () { var lambda = @@ -159,6 +192,8 @@ static void TestLambdaInMethodWithRUC () } [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void Test () { TestLambda (); @@ -184,9 +219,13 @@ public static void MethodWithRequires () public static void MethodWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) { } [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--")] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void MethodWithLocalFunctionWithRUC () { [RequiresUnreferencedCode ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] + [RequiresAssemblyFiles ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] + [RequiresDynamicCode ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] void LocalFunction () { } LocalFunction (); @@ -195,12 +234,16 @@ void LocalFunction () public static void MethodWithLocalFunctionCallsRUC () { [ExpectedWarning ("IL2026", "--MethodWithRUC--")] + [ExpectedWarning ("IL3002", "--MethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] void LocalFunction () => MethodWithRUC (); LocalFunction (); } } [RequiresUnreferencedCode ("--MethodWithRUC--")] + [RequiresAssemblyFiles ("--MethodWithRUC--")] + [RequiresDynamicCode ("--MethodWithRUC--")] static void MethodWithRUC () { } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs index 95672d4222c61f..e5b28b192b7639 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs @@ -42,20 +42,11 @@ class RequiresAttributeMismatch [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] @@ -65,9 +56,7 @@ class RequiresAttributeMismatch [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "IBaseWithRequires.PropertyAnnotationInAccesor.get")] [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs index 8cc523da281a4e..06179031c754bb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs @@ -196,8 +196,6 @@ static IEnumerable TestMethodParameterWithRequirements (Type unknownType = yield return 0; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -207,8 +205,6 @@ static IEnumerable TestGenericMethodParameterRequirement () yield return 0; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -375,8 +371,6 @@ static async void TestMethodParameterWithRequirements (Type unknownType = null) await MethodAsync (); } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -386,8 +380,6 @@ static async void TestGenericMethodParameterRequirement () await MethodAsync (); } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -568,8 +560,6 @@ static async IAsyncEnumerable TestMethodParameterWithRequirements (Type unk yield return 0; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -580,8 +570,6 @@ static async IAsyncEnumerable TestGenericMethodParameterRequirement unknownType.RequiresNonPublicMethods (); } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -1397,8 +1382,6 @@ static void TestGenericMethodParameterRequirement () }; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -1950,8 +1933,6 @@ static async void TestAsyncOnlyReferencedViaReflectionWhichShouldWarn () [ExpectedWarning ("IL3002", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] - // ILLink warns about reflection access to compiler-generated state machine members. - // https://github.com/dotnet/runtime/issues/68786 [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestAsyncOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestIteratorOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", @@ -2082,8 +2063,6 @@ void LocalFunction () [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - // ILLink warn about reflection access to compiler-generated code - // https://github.com/dotnet/runtime/issues/68786 [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection), ProducedBy = Tool.Trimmer)] static void TestAll () @@ -2117,8 +2096,6 @@ static void TestAll () [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - // ILLink warn about reflection access to compiler-generated code - // https://github.com/dotnet/runtime/issues/68786 [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), "<" + nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection) + ">", ProducedBy = Tool.Trimmer)] static void TestNonPublicMethods () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index 93445e8c63b59e..2ae2c7fb2002b4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -535,16 +535,16 @@ class ReflectionAccessOnMethod [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()")] [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] - // ILLink skips warnings for base method overrides, assuming it is covered by RUC on the base method. - [ExpectedWarning ("IL2026", "DerivedWithRequiresOnType.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + // https://github.com/dotnet/linker/issues/2533 + [ExpectedWarning ("IL2026", "DerivedWithRequiresOnType.Method()", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method(Int32)")] [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method(Int32)", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method()")] [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method()")] [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] - // ILLink skips warnings for interface overrides, assuming it is covered by RUC on the interface method. + // https://github.com/dotnet/linker/issues/2533 + // NativeAOT has a correct override resolution and in this case the method is not an override - so it should warn [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method(Int32)", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method(Int32)", ProducedBy = Tool.NativeAot)] // ILLink incorrectly skips warnings for derived method, under the assumption that @@ -552,8 +552,7 @@ class ReflectionAccessOnMethod // is unannotated (and the mismatch produces no warning because the derived // type has RUC). // https://github.com/dotnet/linker/issues/2533 - [ExpectedWarning ("IL2026", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", ProducedBy = Tool.Analyzer)] static void TestDAMAccess () { // Warns because BaseWithoutRequiresOnType.Method has Requires on the method @@ -784,13 +783,13 @@ class BaseForDAMAnnotatedClass [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] [RequiresUnreferencedCode ("This class is dangerous")] [RequiresDynamicCode ("This class is dangerous")] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseField", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] class DAMAnnotatedClass : BaseForDAMAnnotatedClass { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicField", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static int publicField; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privatefield", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privatefield", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static int privatefield; } @@ -802,7 +801,7 @@ static void TestDAMOnTypeAccess (DAMAnnotatedClass instance) [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] class DAMAnnotatedClassAccessedFromRUCScope { - [ExpectedWarning ("IL2112", "DAMAnnotatedClassAccessedFromRUCScope.RUCMethod", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClassAccessedFromRUCScope.RUCMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [RequiresUnreferencedCode ("--RUCMethod--")] public static void RUCMethod () { } } @@ -1014,21 +1013,21 @@ class BaseForDAMAnnotatedClass [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] [RequiresUnreferencedCode ("This class is dangerous")] [RequiresDynamicCode ("This class is dangerous")] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] class DAMAnnotatedClass : BaseForDAMAnnotatedClass { public static int publicProperty { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.get", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] get; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] set; } static int privateProperty { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.get", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] get; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] set; } } @@ -1055,7 +1054,7 @@ public class AttributeWithRequires : Attribute // `field` cannot be used as named attribute argument because is static, and if accessed via // a property the property will be the one generating the warning, but then the warning will - // be suppresed by the Requires on the declaring type + // be suppressed by the Requires on the declaring type public int PropertyOnAttribute { get { return field; } set { field = value; } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs index 06294b22d85c2f..79273bd74bb736 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs @@ -12,7 +12,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] class RequiresOnVirtualsAndInterfaces @@ -51,8 +50,8 @@ public override void VirtualMethodRequires () } [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestBaseTypeVirtualMethodRequires () { var tmp = new BaseType (); @@ -61,8 +60,8 @@ static void TestBaseTypeVirtualMethodRequires () [LogDoesNotContain ("TypeWhichOverridesMethod.VirtualMethodRequires")] [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestTypeWhichOverridesMethodVirtualMethodRequires () { var tmp = new TypeWhichOverridesMethod (); @@ -71,8 +70,8 @@ static void TestTypeWhichOverridesMethodVirtualMethodRequires () [LogDoesNotContain ("TypeWhichOverridesMethod.VirtualMethodRequires")] [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestTypeWhichOverridesMethodVirtualMethodRequiresOnBase () { BaseType tmp = new TypeWhichOverridesMethod (); @@ -101,8 +100,8 @@ public override int VirtualPropertyRequires { [LogDoesNotContain ("TypeWhichOverridesProperty.VirtualPropertyRequires")] [ExpectedWarning ("IL2026", "--PropertyBaseType.VirtualPropertyRequires--")] - [ExpectedWarning ("IL3002", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestTypeWhichOverridesVirtualPropertyRequires () { var tmp = new TypeWhichOverridesProperty (); @@ -111,8 +110,8 @@ static void TestTypeWhichOverridesVirtualPropertyRequires () [LogDoesNotContain ("ImplementationClass.MethodWithRequires")] [ExpectedWarning ("IL2026", "--IRequires.MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestInterfaceMethodWithRequires () { IRequires inst = new ImplementationClass (); @@ -161,8 +160,8 @@ public override DerivedReturnType GetRequires () [LogDoesNotContain ("--CovariantReturnBase.GetRequires--")] [ExpectedWarning ("IL2026", "--CovariantReturnDerived.GetRequires--")] - [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestCovariantReturnCallOnDerived () { var tmp = new CovariantReturnDerived (); @@ -190,10 +189,9 @@ public override DerivedReturnType GetRequires () } } - // https://github.com/dotnet/runtime/issues/73321 [ExpectedWarning ("IL2026", "--CovariantReturnViaLdftn.Derived.GetRequires--")] - [ExpectedWarning ("IL3002", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] public static void Test () { var tmp = new Derived (); @@ -221,13 +219,13 @@ public virtual void RUCMethod () { } [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Base.RUCMethod--")] // Reflection triggered warnings are not produced by analyzer for RDC/RAS - // [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] - // [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/linker/issues/2815 - [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] // Reflection triggered warnings are not produced by analyzer for RDC/RAS - // [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] - // [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.NativeAot)] public static void Test () { typeof (Derived).RequiresPublicMethods (); @@ -260,11 +258,11 @@ public static void AbstractMethod () { } } [ExpectedWarning ("IL2026", "--StaticInterfaces.IRequires.VirtualMethod--")] - [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [ExpectedWarning ("IL2026", "--StaticInterfaces.IRequires.AbstractMethod--")] - [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void UseRequiresMethods () where T : IRequires { T.AbstractMethod (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs index f4d768a692b35c..15dd829a93a198 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs @@ -17,9 +17,7 @@ class RequiresViaDataflow { // Base/Derived and Implementation/Interface differs between ILLink and analyzer https://github.com/dotnet/linker/issues/2533 [ExpectedWarning ("IL2026", "--DynamicallyAccessedTypeWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL2026", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--")] [ExpectedWarning ("IL3002", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsUsingTargetViaXmlNetCore.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsUsingTargetViaXmlNetCore.cs index bf6f717a0519f4..9b9e7130e41a29 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsUsingTargetViaXmlNetCore.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsUsingTargetViaXmlNetCore.cs @@ -7,6 +7,9 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { + // https://github.com/dotnet/runtime/issues/82447 + [IgnoreTestCase ("NativeAOT doesn't support suppressing warnings via XML", IgnoredBy = Tool.NativeAot)] + [KeptAttributeAttribute(typeof(IgnoreTestCaseAttribute))] [TestCaseRequirements (TestRunCharacteristics.TargetingNetCore, "This test is specific to .NET Core")] // For netcoreapp we don't have to specify the assembly for the attribute, since the attribute comes from corelib // and will be found always. diff --git a/src/workloads/workloads.csproj b/src/workloads/workloads.csproj index 0fc48f5ba30e8e..3e81fe9ebca0d2 100644 --- a/src/workloads/workloads.csproj +++ b/src/workloads/workloads.csproj @@ -148,7 +148,7 @@